Compare commits

...

431 Commits

Author SHA1 Message Date
gingerBill 9453b2387b Merge pull request #2669 from laytan/check-disabled-when-generating-parapoly
Fix #2666 by checking for disabled when generating parapoly procs
2023-08-01 14:45:36 +01:00
gingerBill a4de59c8ee Merge pull request #2686 from ryuukk/patch-8
Assign element to Slice not Array when alloc a Type_Slice
2023-08-01 14:45:19 +01:00
gingerBill fab40080e4 Merge pull request #2693 from hasanyasin/master
Add -show-system-calls flag info to cli usage help
2023-08-01 14:45:03 +01:00
Hasan Yasin Ozturk fb30bda7d7 Add -show-system-calls flag info to cli usage help 2023-08-01 15:51:22 +03:00
gingerBill 65206fe33e Go through loads of TODOs 2023-08-01 11:39:04 +01:00
gingerBill 2f094134a3 Remove -strict-style-init-only 2023-08-01 11:14:52 +01:00
gingerBill 69e1f42aed Replace a lot of warnings with errors; remove deprecated stuff 2023-08-01 11:11:15 +01:00
gingerBill c35c58b023 Add -vet-style and -vet-semicolon 2023-08-01 11:03:15 +01:00
gingerBill 4b57aec1c6 Fix typo 2023-07-31 17:30:03 +01:00
gingerBill 2038bd0c15 Merge branch 'master' of https://github.com/odin-lang/Odin 2023-07-31 17:27:39 +01:00
gingerBill 19b24fcce2 Add require_results for proc groups 2023-07-31 17:27:23 +01:00
Jeroen van Rijn ed3354b433 Merge pull request #2692 from hasanyasin/master
Fix dropped "dev-" prefix from version tag
2023-07-31 16:55:37 +02:00
Hasan Yasin Ozturk 963eeee361 Fix dropped "dev-" prefix from version tag
In commit c3a31666, "dev-" prefix was dropped unintentionally. This commit fixes
that.
2023-07-31 17:46:45 +03:00
Jeroen van Rijn c3a316664a Merge pull request #2691 from hasanyasin/master
Set version date to commit date instead of build date
2023-07-31 16:39:32 +02:00
Hasan Yasin Ozturk 3d16880d95 Set version date to commit date instead of build date
Fixes #2688

This commit updates `build_odin.sh` and `build.bat` so that date of the commit
is used for the version tag, instead of the build time.
2023-07-31 17:29:56 +03:00
gingerBill be6f355665 Keep -vet happy by removing using 2023-07-31 12:32:30 +01:00
gingerBill 5dba08fb3b Keep -vet happy 2023-07-31 12:19:25 +01:00
gingerBill f17077c05c Remove debug code 2023-07-31 12:11:31 +01:00
gingerBill 8aa36072fc Remove using where easily possible 2023-07-31 12:11:17 +01:00
gingerBill 44ea82f845 Clean up usage of using throughout core and vendor 2023-07-31 11:46:40 +01:00
gingerBill 0de7df9eab Improve //+vet; remove using in many places; add //+vet !using-stmt where necessary 2023-07-31 11:37:14 +01:00
gingerBill 60e509b1e0 Add separate -vet flags; -vet-using-* flags; //+vet file flags 2023-07-31 11:09:19 +01:00
Jeroen van Rijn 551c379f1b Merge pull request #2687 from Kelimion/xml-value-fix
Fix #2684
2023-07-28 16:01:01 +02:00
Jeroen van Rijn 683ee75703 Fix #2684 2023-07-28 15:53:39 +02:00
ryuukk a99da47b0d Assign element to Slice not Array when alloc a Type_Slice 2023-07-27 22:13:55 +02:00
Jeroen van Rijn 5ac7fe453f Merge pull request #2676 from jasonKercher/fix-2667
coalesce tombstones in map insert
2023-07-22 10:29:15 +02:00
jason f9c083073e coalesce tombstones in map insert 2023-07-21 15:44:39 -04:00
Laytan Laats 74338733ba Fix #2666 by checking for disabled when generating parapoly procs 2023-07-19 20:27:34 +02:00
gingerBill 1b3657122c Uncomment procedures in procedure group 2023-07-17 16:02:18 +01:00
gingerBill 0f28857c59 Improve type inference for procedure group stuff 2023-07-17 13:03:58 +01:00
gingerBill 88485d5467 Improve scoring for polymorphic procedures 2023-07-17 12:57:33 +01:00
gingerBill 921530dd01 Fix to allow procedure groups on objective-c types 2023-07-17 12:43:56 +01:00
gingerBill dcf3023d93 Fix bug caused by incorrect assert 2023-07-17 12:06:48 +01:00
Jeroen van Rijn b12c46b28a Merge pull request #2659 from Pingar5/master
Fixed typo in GGPO bindings
2023-07-17 01:11:32 +02:00
Brennen Shaughnessy 635d671ee7 Fixed typo in GGPO bindings 2023-07-15 15:59:58 -04:00
Jeroen van Rijn 204c0fa4d8 Merge pull request #2650 from hchac/remove-core-odin-from-gitignore
Don't gitignore folders named odin.
2023-07-11 22:58:56 +02:00
gingerBill 3a0b66d5df Merge pull request #2625 from laytan/exit-code-1-on-test-failure
exit with code 1 on `odin test` failure
2023-07-11 21:50:18 +01:00
gingerBill 07d3122c14 Merge pull request #2651 from erjohnson/arena-static-bootstrap-doc-fix
Fix small doc mistakes in arena.odin
2023-07-11 21:49:06 +01:00
Eric Johnson c6957e4e31 Fix small doc mistakes in arena.odin 2023-07-11 13:41:12 -07:00
hchac 8068a3899d Don't gitignore folders named odin. 2023-07-11 16:23:54 -04:00
Laytan Laats 3cce972125 fix indentation 2023-07-11 19:34:59 +02:00
Laytan Laats 52700d6a84 use lb_emit_select instead of lb_emit_if for exit check 2023-07-11 19:30:44 +02:00
Jeroen van Rijn 0c80a4b836 Merge pull request #2640 from z64/z64/mutex
Improve Mutex struct documentation
2023-07-11 14:01:02 +02:00
Zac Nowicki 46f408cc9f Fixup link format 2023-07-11 07:43:36 -04:00
Jeroen van Rijn 5c068a9062 Merge pull request #2647 from ryuukk/patch-6
core:sys/windows: Deprecate htons, htonl, ntohl, ntohs in favor of endian specific integers
2023-07-11 08:11:50 +02:00
ryuukk e1fae5b902 Fix attribute 2023-07-11 03:51:28 +02:00
ryuukk 20e5e95ff8 Deprecate htons, htonl, ntohl, ntohs 2023-07-11 03:45:08 +02:00
Jeroen van Rijn a238f78855 Merge pull request #2645 from Pix-xiP/fix-raylib-gesture
GetGestureDetected proc returns a Gesture not a Gestures bit_set
2023-07-10 17:25:02 +02:00
Jeroen van Rijn 5b96712ed0 Merge pull request #2642 from ryuukk/patch-4
core:sys/windows: Add definitions for network byte order conversion procs
2023-07-10 17:04:09 +02:00
Pix f141078073 GetGestureDetecetd should return a Gestures bit_set not a Gesture. 2023-07-10 22:24:16 +08:00
Jeroen van Rijn d47fed16a9 Merge pull request #2643 from ryuukk/patch-5
core:sys/windows: Add CopyFileW proc
2023-07-10 11:21:37 +02:00
ryuukk bc43a8d38d Add CopyFileW 2023-07-10 06:02:38 +02:00
ryuukk ccd5685cee Fix doc links 2023-07-10 05:57:12 +02:00
ryuukk f0f8177a19 Add definitions for network byte order conversion procs 2023-07-10 05:56:26 +02:00
Zac Nowicki 363b701925 Improve Mutex struct documentation 2023-07-09 08:30:16 -04:00
Jeroen van Rijn 0a897e2fae Merge pull request #2638 from ramn/handle_nils_in_expect_value
Fix #2637
2023-07-09 00:28:02 +02:00
ramn 5f53d815d1 fix: make -vet not complain 2023-07-09 00:15:01 +02:00
ramn 7b89f25818 Fix #2637
where testing.expect_value can't compare nils
2023-07-08 23:46:51 +02:00
gingerBill 3072479c3c Generalize name mangling rule to have a singular definition for a name separator 2023-07-07 23:52:56 +01:00
gingerBill 62031c24a2 Add extra mutex guards around module value access 2023-07-07 23:35:16 +01:00
gingerBill aa38889704 Fix issue with pointer casting internal llvm intrinsics 2023-07-07 23:23:47 +01:00
gingerBill 17562e476f Remove math usage of raw LLVM intrinsic prototypes 2023-07-07 23:13:37 +01:00
gingerBill 6495f2cf98 Fix #2593 2023-07-07 23:09:46 +01:00
gingerBill ea20b644cc Fix #2624 2023-07-07 23:07:41 +01:00
gingerBill bf848637aa Fix #2629 2023-07-07 23:06:15 +01:00
gingerBill 759f846b2b Fix [2]union{T} comparison against nil 2023-07-07 23:03:46 +01:00
gingerBill 3758be55f5 Fix #2630 2023-07-07 22:56:20 +01:00
gingerBill 8f4c59b080 Add core:math/cmpl to all_main.odin 2023-07-07 22:29:53 +01:00
gingerBill 1ff6212ffa Always call lb_run_remove_dead_instruction_pass to fix -debug issues 2023-07-07 22:28:31 +01:00
Jeroen van Rijn b60d29ae9a Merge pull request #2627 from laytan/add-address-family-type-definition
add `ADDRESS_FAMILY` to darwin (currently only available in linux)
2023-07-03 22:45:28 +02:00
Laytan Laats 38d71e668d add ADDRESS_FAMILY to darwin (currently only available in linux) 2023-07-03 19:56:56 +02:00
Laytan Laats 7cdf37eaf6 exit with code 1 on odin test failure 2023-07-03 01:22:36 +02:00
Jeroen van Rijn 8d9adfd548 Merge pull request #2623 from laytan/fix-2615-cant-iterate-untyped-string
Fix #2615: can't iterate untyped string
2023-07-02 23:06:35 +02:00
Laytan Laats a3e2d90f4c add test 2023-07-02 23:00:37 +02:00
Laytan Laats fc81008ab5 Fix #2615: can't iterate untyped string 2023-07-02 22:18:25 +02:00
Jeroen van Rijn a1eae6304f Merge pull request #2622 from laytan/detect-unix-colors-support
detect unix color support
2023-07-02 21:34:34 +02:00
Laytan Laats 49058620f0 fix spacing 2023-07-02 21:25:48 +02:00
Laytan Laats f68a3639b4 use more common detection method and add FORCE_COLOR and NO_COLOR support 2023-07-02 21:11:19 +02:00
Laytan Laats f4e87c9720 ignore stderr in tput call 2023-07-02 20:20:10 +02:00
Laytan Laats 23bf7973fa detect unix color support 2023-07-02 19:56:46 +02:00
Jeroen van Rijn 67e0751124 Merge pull request #2621 from DanielGavin/vulkan-flags2
Add support for vulkan FlagBits2
2023-07-02 19:34:20 +02:00
DanielGavin f76559daf6 Remove whitespaces 2023-07-02 18:28:37 +02:00
DanielGavin 5e99ff6769 Add support FlagBits2 2023-07-02 18:24:37 +02:00
gingerBill 1ecb4aa9aa Begin work on core:math/cmplx
`complex*` types only at the moment, `quaternion*` types coming later
2023-06-28 13:20:23 +01:00
gingerBill a2b3c72647 Improve accuracy of abs or complex* types 2023-06-28 13:18:36 +01:00
gingerBill 0180a4fcd4 Add math.sincos 2023-06-28 12:57:09 +01:00
gingerBill abca3ceac8 Keep -vet happy 2023-06-28 12:20:12 +01:00
gingerBill 866a9fdf19 Actually add math.hypot 2023-06-28 12:19:45 +01:00
gingerBill 20e954a864 Add math.hypot 2023-06-28 12:16:49 +01:00
gingerBill 03e40b333a Merge branch 'master' of https://github.com/odin-lang/Odin 2023-06-28 11:57:43 +01:00
gingerBill ebed66d4ce General code style clean up for vendor:nanovg 2023-06-28 11:57:37 +01:00
gingerBill 9e9f3c485b General code style clean up for vendor:fontstash 2023-06-28 11:36:27 +01:00
gingerBill d50a844720 Replace mem with runtime in core:slice 2023-06-28 11:04:51 +01:00
Jeroen van Rijn 89e559296e Merge pull request #2612 from laytan/master
only run nightly upload if workflow is ran on main repo
2023-06-28 07:53:40 +02:00
Laytan Laats d352e2fa31 only run nightly upload if workflow is ran on main repo 2023-06-27 23:33:18 +02:00
Jeroen van Rijn 71bc452764 Merge pull request #2611 from GoNZooo/gonz.add-unix-setenv
fix(os): use `setenv` instead of `putenv`
2023-06-27 20:54:49 +02:00
Rickard Andersson f048ad13b5 fix(set_env): use clone_to_cstring instead of unsafe_to_cstring 2023-06-27 21:48:53 +03:00
Rickard Andersson d03d5d8f03 style: use tabs
:[
2023-06-27 21:46:00 +03:00
Rickard Andersson 6ff0ce15e7 cleanup: remove leftover line 2023-06-27 21:42:20 +03:00
Rickard Andersson 330b393e16 fix(os): use setenv instead of putenv
`setenv` doesn't copy the value that is put, which means that the
previous code had a bug where we free'd the temporary memory and the
environment was accidentally cleared right after the function finished.
2023-06-27 21:37:10 +03:00
gingerBill a820246f64 Keep -vet happy 2023-06-26 23:00:39 +01:00
gingerBill 1bf4c8c9ba Merge pull request #2268 from Skytrias/skytrias-vendor-additions
fontstash / nanovg vendor additions
2023-06-26 22:59:11 +01:00
skytrias ca1d437435 add build flags restrictions 2023-06-26 21:28:54 +02:00
gingerBill 8b8310711e Fix #2594 zero sized union code generation 2023-06-26 17:36:27 +01:00
gingerBill cdcb64b0d0 Add missing -strict-style check 2023-06-26 17:06:42 +01:00
gingerBill 3c0f1caa41 Fix #2606 2023-06-26 17:03:40 +01:00
gingerBill 8182ba4ee0 Improve internal names for parapoly records 2023-06-26 16:48:43 +01:00
gingerBill 3d9328fd79 Default to panic allocator for wasm targets 2023-06-26 15:55:52 +01:00
gingerBill 6c6f9f7d25 Fix fmt implementation for js 2023-06-26 15:55:35 +01:00
gingerBill c8f475174e Fix tests for -strict-style 2023-06-26 15:51:08 +01:00
gingerBill 3dec55f009 Replace x in &y Use &v in y syntax through core & vendor for switch/for statements 2023-06-26 15:42:57 +01:00
gingerBill 00d60e28c2 Allow switch &v in ... work to be consistent with for &e in ... 2023-06-26 15:41:53 +01:00
gingerBill ea00619c3b for &e, i in array and for k, &v in map (alternative to passing the iterable by pointer) 2023-06-26 15:20:40 +01:00
skytrias bbe50bdaf1 -strict-style fix 2023-06-23 16:21:52 +02:00
skytrias 6b59aee336 cleanup with -vet and add to all_vendor 2023-06-23 16:18:40 +02:00
gingerBill 26a5614572 Merge branch 'master' into skytrias-vendor-additions 2023-06-23 14:33:01 +01:00
gingerBill 19ea090633 Merge pull request #2584 from odin-lang/new-io
New and Improved `io.Stream` interface
2023-06-23 12:12:17 +01:00
gingerBill 9841b11a54 Merge pull request #2597 from odin-lang/ordered-named-arguments
Allowing for Positional and Named Arguments in Procedure Calls
2023-06-23 12:11:46 +01:00
gingerBill 5a6d5374d7 Update WebGL procedures to contextless calling convention 2023-06-22 14:30:02 +01:00
gingerBill 9099bc0b6e Merge pull request #2599 from RehkitzDev/master
fixed dynlib wasm stub
2023-06-22 12:56:23 +01:00
Rehkitzdev e3b43b6e1c fixed dynlib wasm stub 2023-06-22 13:35:22 +02:00
gingerBill b0d801f629 Merge pull request #2582 from ftphikari/master
[core:thread] Added self_cleanup flag to properly auto-clean threads
2023-06-21 18:21:48 +01:00
gingerBill c48057081e Fix nullptr entity case 2023-06-21 14:39:23 +01:00
gingerBill ea76e09ea7 Fix empty varargs 2023-06-21 14:30:39 +01:00
gingerBill c9fb078c0f Handle #c_vararg 2023-06-21 14:07:14 +01:00
gingerBill 1800030356 Correct deferred procedures 2023-06-21 14:01:46 +01:00
gingerBill 43ba2c6226 Fix constant parameter passing 2023-06-21 12:10:07 +01:00
gingerBill 735181dc0e Remove unnecessary indent 2023-06-21 01:33:37 +01:00
gingerBill 8a890fd3d3 Remove new_and_improved in the name 2023-06-21 01:32:35 +01:00
gingerBill 15e31e47fa Remove in order requirement for named parameters 2023-06-21 01:24:57 +01:00
gingerBill 9b54b99bf6 Use positional and named arguments within the core library 2023-06-21 01:17:05 +01:00
gingerBill 67ca9166d3 Allow named arguments variadic expansion .. 2023-06-21 01:03:21 +01:00
gingerBill b2ced834ba Minor code reshuffle 2023-06-21 00:43:51 +01:00
gingerBill 18746c1444 Refactor call argument checking to a single procedure 2023-06-21 00:40:02 +01:00
gingerBill 09f366bec7 Correct purely named argument handling 2023-06-21 00:03:56 +01:00
gingerBill 3998d0c81e Make error checks diverging where possible 2023-06-20 22:55:47 +01:00
gingerBill 2a002c3882 Fix scoring for untyped ternary expressions 2023-06-20 22:55:33 +01:00
gingerBill fb756e3463 Correct procedure group handling 2023-06-20 21:02:57 +01:00
gingerBill 3c5661b51b Allow for positional and named arguments in procedure calls 2023-06-20 20:29:40 +01:00
gingerBill 26e06ba6a6 Correct check_call_arguments_new_and_improved logic 2023-06-20 16:08:26 +01:00
gingerBill 7c57dde255 Start work on parapoly args for new and improved 2023-06-20 13:47:10 +01:00
gingerBill 9ec927b9e9 Try to get make everything work with parapoly 2023-06-20 00:30:29 +01:00
gingerBill 15a0d9f900 Begin to handle split arguments correctly 2023-06-19 23:46:06 +01:00
gingerBill f26e3c6509 Improve proc group selection with named arguments 2023-06-19 22:26:43 +01:00
gingerBill 6568625dea Fix line error printing for error messages 2023-06-19 22:12:47 +01:00
gingerBill 427f212170 Begin work in procedure calls 2023-06-19 13:56:00 +01:00
Jeroen van Rijn c1fb8eaf1a Merge pull request #2591 from GoNZooo/g.add-poll-for-unix
feat(os_linux): add `poll` & `ppoll`
2023-06-17 08:27:42 +02:00
Rickard Andersson 37469dc9c2 fix(poll): make interface more odinary
We take `fds` as a normal slice and get the length from it instead of
bothering with a second parameter.
2023-06-15 16:10:00 +03:00
Rickard Andersson dce57627c9 fix: remove redefinition of timespec
They are in the same package, so it's accessible anyway.
2023-06-15 08:54:42 +03:00
gingerBill 2992ca5df1 Basic support for new procedure code (non-polymorphic, non-proc-group) 2023-06-15 01:37:55 +01:00
Rickard Andersson a5ed5883c7 cleanup: more tabs 2023-06-14 23:59:09 +03:00
Rickard Andersson 0036509f74 cleanup(os_linux/poll): use tabs everywhere
:(
2023-06-14 23:51:33 +03:00
Rickard Andersson 003c470a4d fix(os_linux): make when for arm64 check correct order
Also remove `sys_select` since we aren't using it anyway
2023-06-14 23:38:00 +03:00
Rickard Andersson d6540d9077 fix(os_linux): call ppoll instead on arm64 2023-06-14 23:26:43 +03:00
Rickard Andersson 091c515fea cleanup(os_linux): remove select 2023-06-14 22:34:57 +03:00
Rickard Andersson 4f2b9835f5 feat(unix): add poll 2023-06-14 22:13:36 +03:00
gingerBill 242d3b3c4d Begin work allowing mixture of named and unnamed 2023-06-14 15:40:52 +01:00
gingerBill c66ac9725e Separate out logic for checking mixture of named and unnamed parameters 2023-06-14 14:56:33 +01:00
gingerBill feacc5cd11 Basic enforcement of ordered named arguments/parameters for procedures 2023-06-14 14:03:08 +01:00
gingerBill 3a761395be Add basic optimization for comparisons against the empty string "" 2023-06-14 12:49:33 +01:00
gingerBill a78d6fe0b3 Use i64 instead of int for internal procedures 2023-06-14 12:31:57 +01:00
gingerBill 08e466938f Merge branch 'master' into new-io 2023-06-14 12:07:04 +01:00
gingerBill e036155bdb Merge pull request #2586 from thetarnav/patch-1
Replace `0` with `os.ERROR_NONE` in `demo.odin`
2023-06-14 12:05:52 +01:00
gingerBill 2149afabe1 Merge pull request #2590 from inbelic/inbelic/fix-no_nil-variants-err
[check-type] fix faulty #no_nil variants error
2023-06-14 12:05:34 +01:00
finn ec32967daa [check-type] fix faulty #no_nil variants error
- when checking the variants of a union type we will skip adding
  the variants if we have an unspecialized polymorphic, hence our
  union_type variants will be empty and have a count of 0

- so when checking if we violate the #no_nil error, if we are in the
  unspecialized polymorphic case and there exists at least one variant
  in the original variants then we should not raise this error

- test checks that we do not raise the error anymore, and that we still
  detect the #no_nil error in the described circumstances
2023-06-13 22:07:01 +02:00
gingerBill fc4a5e61c2 Add ODIN_IGNORE_MSVC_CHECK check to build.bat 2023-06-13 13:21:15 +01:00
gingerBill e9608c9d05 Merge branch 'master' of https://github.com/odin-lang/Odin 2023-06-13 13:15:05 +01:00
gingerBill 581eebb197 Fix a race condition when produced anonymous procedure literals with -use-separate-modules 2023-06-13 13:14:59 +01:00
Jeroen van Rijn 10fa67fdaa Merge pull request #2589 from jlreymendez/master
fix: read file from windows was not returning platform error correctly
2023-06-13 09:48:50 +02:00
José Rey Méndez 10f2136675 fix: read file from windows was not returning platform error correctly 2023-06-12 19:28:41 -03:00
Jeroen van Rijn d97dd99d91 Merge pull request #2588 from laytan/fix-darwin-fcntl
fix fcntl binding on darwin
2023-06-12 16:16:49 +02:00
gingerBill 296674e18b Rename ODIN_DISALLOW_RTTI to ODIN_NO_RTTI; Remove dead command line flags 2023-06-12 14:53:05 +01:00
gingerBill 52a926dd90 Deprecate -disallow-rtti in favour of -no-rtti 2023-06-12 14:49:00 +01:00
Laytan Laats d38ea63c78 fix fcntl binding on darwin 2023-06-12 15:37:39 +02:00
gingerBill 2022a7615a Make all id suffixes use atomics where possible 2023-06-12 14:10:18 +01:00
gingerBill dca0fae781 Improve lb_generate_anonymous_proc_lit (again) 2023-06-12 13:42:51 +01:00
gingerBill e16c6c1b6b Replace procedure strings.concatenate 2023-06-12 12:58:47 +01:00
gingerBill ede9881458 Keep compilers happy 2023-06-12 12:54:36 +01:00
gingerBill a7f8c78358 Change how "$anon" mangling works to use an atomic value instead 2023-06-12 12:52:17 +01:00
Jeroen van Rijn 3a90b40425 Merge pull request #2587 from GoNZooo/g.fix-early-exit-on-no-hosts
fix(dns): don't exit early on no hosts in hosts file
2023-06-12 12:51:37 +02:00
Rickard Andersson 454709559b fix(dns): don't exit early on no hosts in hosts file
If we don't have any hosts specified we'll still not generate any
overrides which is fine, but we'll continue onto actually trying to
resolve the hostname we came into the function for initially.
2023-06-12 13:38:12 +03:00
Damian Tarnawski c3933cead4 Replace 0 with os.ERROR_NONE in demo.odin 2023-06-11 23:41:26 +02:00
gingerBill 420f93ce78 Ignore BSD's for stream.odin 2023-06-08 22:38:15 +01:00
gingerBill 2a212a7556 Put stream into the impl 2023-06-08 17:00:38 +01:00
gingerBill 145a7a24e8 Use io.Stream as the internal interface for os2.File 2023-06-08 16:55:01 +01:00
gingerBill 6c040497ef Update os2 to new io.Stream 2023-06-08 16:45:13 +01:00
gingerBill 9ee4b76cd9 Just make the io.Reader etc aliases 2023-06-08 16:38:57 +01:00
gingerBill 3f6775e29b Update to new io interface 2023-06-08 16:35:24 +01:00
gingerBill 4c17e2e97e Merge pull request #2552 from jcmoyer/fix-2466
Use compound literal storage for ValueDecl lvals
2023-06-08 12:34:40 +01:00
Jeroen van Rijn eac53fed59 Merge pull request #2583 from JamesDSource/master
Correct Timeval struct to use microseconds on darwin and linux (Issue #2489)
2023-06-08 09:39:25 +02:00
James Duran fed0c2ea26 Fix Timeval for darwin and linux 2023-06-07 21:55:08 -07:00
gingerBill 21c1618d94 Add botan libraries to all/all_vendor.odin 2023-06-08 00:28:35 +01:00
gingerBill d37699f51a Add bsd to mem/virtual 2023-06-07 23:07:31 +01:00
gingerBill d82bfa98a7 Remove redundant comments 2023-06-07 23:01:08 +01:00
gingerBill 9b15bda055 Add missing packages to examples/all 2023-06-07 22:48:39 +01:00
gingerBill 635842b322 Add more text packages to examples/all 2023-06-07 22:40:46 +01:00
hikari 3b8515beb0 [core:thread] Seeing if this fixes network tests 2023-06-07 20:52:41 +03:00
hikari 7b62b81ebd [core:thread] Fix compilation 2023-06-07 20:03:19 +03:00
hikari dcf4e51787 [core:thread] Added self_cleanup flag to properly auto-clean threads 2023-06-07 19:11:16 +03:00
gingerBill 7dc09ed450 Add ODIN_COMPILE_TIMESTAMP (unix timestamp in nanoseconds) 2023-06-07 15:49:12 +01:00
gingerBill 349641e95f Fix #2572 2023-06-07 13:08:15 +01:00
gingerBill 9941ec85d8 Fix #2578 (check for fallthrough) 2023-06-07 12:18:21 +01:00
gingerBill ef944b903b "Fix" #2580 2023-06-07 12:13:20 +01:00
gingerBill 0c477f2c6b Merge pull request #2289 from Lperlind/staging/fix_os_args
Fix out of range error with _alloc_command_line_arguments in darwin
2023-06-07 12:06:43 +01:00
gingerBill 151396507e Merge pull request #1309 from Yawning/fix/freebsd-syscall
src: "Fix" the system call intrinsic for FreeBSD
2023-06-07 12:04:57 +01:00
gingerBill 8441c0c51e Merge pull request #2577 from Tetralux/refactor-init-context
[thread] Refactor handling of 'init_context' + add doc comments for it
2023-06-07 11:51:30 +01:00
gingerBill ae7bf468d1 Merge pull request #2573 from inbelic/inbelic/fmt-zero-padding
[fmt] fix zero-padding behaviour of numbers
2023-06-07 11:44:53 +01:00
gingerBill 907ef82d4b Merge pull request #2470 from odin-lang/separate-int-word-sizes
Separate int size from word/pointer size
2023-06-07 02:20:06 +01:00
gingerBill 7a1ab62987 Fix endianness for wasm64p32 2023-06-07 01:19:40 +01:00
gingerBill 295cfc905c Fix typo in wasm64p32 abi 2023-06-07 00:53:31 +01:00
gingerBill 204924927a Ignore non-variable parameters 2023-06-07 00:35:11 +01:00
gingerBill f622a8393c Change ABI for wasm64p32 on slices and structs 2023-06-07 00:30:14 +01:00
gingerBill d75df7fd8a Rename procs 2023-06-07 00:12:54 +01:00
gingerBill 2bc5e0ebd7 Fix non-constant compound literals of slices 2023-06-07 00:10:39 +01:00
gingerBill ca6cef9a7d Fix wasm intrinsics; fix len for strings and slices 2023-06-06 23:11:42 +01:00
gingerBill 1c2a30d7e9 Fix constant slice initialization for wasm64p32 2023-06-06 22:51:51 +01:00
gingerBill 4a75a1e839 Merge branch 'master' into separate-int-word-sizes 2023-06-06 22:42:04 +01:00
gingerBill 6a2ff3a371 Merge pull request #2571 from jakubtomsu/builtin-soa-procs-improvements
Update SOA dynamic array procs to match non-SOA
2023-06-06 22:40:27 +01:00
gingerBill 7ce1386d1a Merge pull request #2575 from RehkitzDev/master
added webgl bindFramebuffer
2023-06-06 22:39:17 +01:00
gingerBill d6f45e4d76 Fix fmt for js 2023-06-06 22:38:43 +01:00
gingerBill 356f66784f Fix @(default_calling_convention) check on wasm 2023-06-06 22:36:36 +01:00
Jeroen van Rijn 166ab7b600 Merge pull request #2579 from apahl/patch-1
Documentation: Tracking_Allocator example is leaking memory
2023-06-06 15:20:38 +02:00
Axel Pahl 1cdb0abf80 Update core/mem/doc.odin 2023-06-06 15:17:18 +02:00
gingerBill 0defd1d141 Correct printing in fmt for ODIN_ERROR_POS_STYLE 2023-06-06 11:17:34 +01:00
gingerBill 24ed07b6d5 Add error requiring an explicit calling convention for foreign procedures 2023-06-06 11:12:14 +01:00
gingerBill ecad730945 Fix map_get typo 2023-06-06 11:08:09 +01:00
gingerBill efb7fd919b Minor fix to internal using logic with LLVM causing a compiler bug 2023-06-06 10:58:36 +01:00
Tetralux 5d6b923244 [thread] Refactor handling of 'init_context' + add doc comments for it 2023-06-03 08:08:18 +00:00
Rehkitzdev d8752da7d5 added webgl bindFramebuffer 2023-06-02 22:19:32 +02:00
finn 6952124988 [fmt] fix zero-padding behaviour of numbers
- when formatting a negative number with left zero-padding we expect the
  padding to be placed between the minus (-) sign and the number
- currently the padding is placed before the sign
2023-06-01 16:04:07 +02:00
jakubtomsu a6c93e2c41 Update SOA dynamic array procs to match non-SOA 2023-06-01 13:42:26 +02:00
gingerBill 788f3c22bf Merge branch 'master' of https://github.com/odin-lang/Odin 2023-05-31 22:23:53 +01:00
gingerBill c194dfbdf7 Remove thread.init_context = context 2023-05-31 22:23:47 +01:00
gingerBill 5e996a1c02 Merge pull request #2568 from RehkitzDev/master
fixed webgl BindFramebuffer parameter
2023-05-31 20:48:00 +01:00
Rehkitzdev b52bf11ea5 fixed webgl BindFramebuffer parameter 2023-05-31 21:44:30 +02:00
gingerBill 7915dde43c Merge pull request #2504 from jon-lipstate/attr_error
helpful error on custom-attrs
2023-05-31 14:08:33 +01:00
gingerBill 7675b9c28f Merge pull request #2564 from Lperlind/rand-docs
Document core:math/rand and add 'possible output'
2023-05-31 14:08:21 +01:00
Lucas Perlind ebe5636307 Document core:math/rand and add 'possible output'
Possible output allows us to just type check a test
and have some sort of output field in the docs but
not actually verify it matches stdout
2023-05-31 09:49:12 +10:00
gingerBill 6fe2df1d7d Add more documentation to numerous @builtin procedures in package runtime 2023-05-30 23:42:21 +01:00
gingerBill 5376d32772 Parse leading comment above attribute for value declarations 2023-05-30 23:06:04 +01:00
gingerBill 2924e478ee Improve check_decl_attributes logic for is_runtime 2023-05-30 20:36:43 +01:00
gingerBill 297700ad11 Merge branch 'master' of https://github.com/odin-lang/Odin 2023-05-30 20:26:27 +01:00
gingerBill 9d29914304 Don't strip builtin attribute form AST 2023-05-30 20:26:22 +01:00
jon lipstate b223bc0302 Merge branch 'odin-lang:master' into attr_error 2023-05-30 08:23:28 -07:00
gingerBill 3562a38f8c Merge pull request #2558 from laytan/implement-set-blocking-darwin
implement non blocking sockets for darwin
2023-05-30 02:15:20 +01:00
gingerBill 201544ef8b Merge pull request #2559 from wiremoons/patch-1
Update build_odin.sh to better support optimisation on Arm CPUs
2023-05-30 02:13:46 +01:00
gingerBill 837ba6c33b Minor change to #reverse for logic; add comments explaining it 2023-05-30 00:21:40 +01:00
gingerBill 3ab01dbc00 Fix type switch debug information on -o:none 2023-05-30 00:05:52 +01:00
gingerBill c241edaa30 Add missing procedure for #reverse on strings 2023-05-30 00:05:24 +01:00
gingerBill e0530df98a Support #reverse for strings 2023-05-29 23:45:21 +01:00
gingerBill 6cbce9fdff Merge pull request #2563 from charles-l/master
WASM: Use BasicC ABI convention for arguments that have `proc "c"`
2023-05-29 23:33:58 +01:00
gingerBill c1eb536726 Change to "contextless" from "c"` 2023-05-29 23:30:48 +01:00
gingerBill b848ae7abb Improve error message for #reverse on an interval 2023-05-29 23:27:42 +01:00
gingerBill f07453d0ae Support #reverse on #soa arrays 2023-05-29 23:24:03 +01:00
charles 052051244f WASM: Use BasicC ABI convention for arguments that have a proc "c" annotation 2023-05-29 18:20:25 -04:00
gingerBill 97490c6445 Basic support for #reverse for in on normal arrays 2023-05-29 23:17:06 +01:00
gingerBill 1247d36a12 Fix #2562 caused by inlining of procedure call 2023-05-29 22:57:42 +01:00
gingerBill f3a463000d Fix #2561 - ARM64 ABI bug for homogenous structs with more than 4 elements 2023-05-29 22:50:28 +01:00
gingerBill c38842ecb2 Merge pull request #2535 from jasonKercher/fix2515
Fix #2515 - Implement backward shift on `map` on insert and reseed hashes on resize
2023-05-29 22:41:46 +01:00
gingerBill 8b825b23b1 Add missing comma 2023-05-29 15:18:38 +01:00
gingerBill d2f62730bc Fix #2560 2023-05-29 14:55:27 +01:00
Simon Rowe d167d18bb3 Update build_odin.sh to better support optimisation on Arm CPUs
The `build_odin` flags include the option `release-native`.

The current `EXTRAFLAGS` set however don't work for Arm CPUs as they dont support `-march=native`.

Added code to detect CPU and either set the preferred flag for Arm CPUs (ie `-mcpu=native`) or keep the current default.

Information on preferred Arm CPU optimisation flag taken from here: https://community.arm.com/arm-community-blogs/b/tools-software-ides-blog/posts/compiler-flags-across-architectures-march-mtune-and-mcpu

Changes tested on an Apple Silicon M1 CPU (arm64) using HomeBrew installed llvm as follows:

```
Homebrew clang version 14.0.6                                                                                                                    
Target: arm64-apple-darwin22.5.0                                                                                                                 
Thread model: posix                                                                                                                              
InstalledDir: /opt/homebrew/opt/llvm@14/bin
```
2023-05-28 15:08:14 +01:00
Jeroen van Rijn 508d7c3336 Merge pull request #2557 from laytan/fix-weird-errno-on-darwin
fix weird errno returned on darwin
2023-05-27 23:26:45 +02:00
Laytan Laats 2b31d85cd4 implement non blocking sockets for darwin 2023-05-27 22:40:05 +02:00
Laytan Laats e350c37e6f fix weird errno returned on darwin 2023-05-27 21:49:39 +02:00
gingerBill 319a465429 Correct queue usage of runtime.Allocator_Error 2023-05-27 15:26:27 +01:00
gingerBill 9371325246 Fix typo 2023-05-25 12:19:41 +01:00
gingerBill 2fda3cf988 Remove os dependency in primitives_openbsd.odin 2023-05-25 12:17:39 +01:00
gingerBill 03b7194c97 Remove os dependency for futex_openbsd.odin 2023-05-25 12:05:58 +01:00
gingerBill 39bff40a75 Make many core:unicode/utf8 procedures "contextless" 2023-05-25 11:58:42 +01:00
gingerBill 3dc6edfd2d Merge branch 'master' of https://github.com/odin-lang/Odin 2023-05-25 11:58:09 +01:00
gingerBill 762747273e Add mutex to mem.Tracking_Allocator 2023-05-25 11:58:02 +01:00
gingerBill 0f392a95ae Merge pull request #2549 from NoahR02/update-vulkan
Update Vulkan
2023-05-24 23:17:06 +01:00
gingerBill 29786b0024 Merge pull request #2555 from ryhor-spivak/fix_windowplacement
Remove rcDevice field from WINDOWPLACEMENT
2023-05-24 23:14:42 +01:00
gingerBill 32ca50a097 Fix special printing for certain named types with fmt.printf related procedures 2023-05-24 20:54:30 +01:00
Ryhor Spivak 8012e6fa43 Remove rcDevice field from WINDOWPLACEMENT. Add WaitMessage and SetWindowPlacement.
rcDevice is under #ifdef _MAC in WinUser.h and _MAC is defined only for PowerPC Mac builds.
2023-05-24 15:14:30 +03:00
gingerBill 54b7cefb09 Fix lua.MAXSTACK 2023-05-24 10:21:53 +01:00
gingerBill 3a61350f4b Add debug messages to docs_writer.cpp 2023-05-22 21:48:32 +01:00
gingerBill bdbbaf6c88 Disable stable_type_cache for the time being 2023-05-22 21:34:20 +01:00
gingerBill 24a1a8a626 Keep -vet happy 2023-05-22 20:48:49 +01:00
gingerBill 38b64dc5df Improve doc_writer.cpp performance 2023-05-22 20:48:13 +01:00
gingerBill e3360a0e5d Merge branch 'master' of https://github.com/odin-lang/Odin 2023-05-22 20:44:07 +01:00
gingerBill 4181444734 Add vendor:darwin/MetalKit to examples/all 2023-05-22 20:44:01 +01:00
gingerBill 7958708641 Add missing class method to NS.Number 2023-05-22 20:43:41 +01:00
gingerBill 40a8ed535a Add @(require_results) to core:math/ease 2023-05-22 20:43:19 +01:00
Jeroen van Rijn c7d571f0b5 Merge pull request #2553 from laytan/fix-2550-json-unicode-issue
fix #2550 json encoding should use surrogate pairs per RFC7159
2023-05-22 18:28:59 +02:00
Laytan Laats 5d54b710e7 fix #2550 json encoding should use surrogate pairs per RFC7159 2023-05-22 17:22:33 +02:00
gingerBill 248f14a1ef Correct entity flag generation 2023-05-22 15:29:01 +01:00
gingerBill b76fc58543 Inline are_types_identical_unique_tuples to improve odin_doc_type performance 2023-05-22 15:23:24 +01:00
gingerBill 9fc9981a9e Update calling convention to the most appropriate
- "odin" if the `context` is needed for `assert`
- "contextless" if multiple return values are needed (better for optimizations)
- "c" otherwise
2023-05-22 15:04:33 +01:00
gingerBill 8f563df7c5 Use proc "c" calling convention in NS Foundation package 2023-05-22 14:59:24 +01:00
gingerBill 730192adc4 Add procedure groups for Device_newBuffer and Texture_newTextureView 2023-05-22 14:51:46 +01:00
gingerBill 8bf32ac697 Minor change to handling of propagation of errors with --- as a value 2023-05-22 12:53:29 +01:00
gingerBill 540f724b1f Fix --- on variable declarations 2023-05-22 12:42:02 +01:00
gingerBill d5a8f2298e Restrict --- to variable declarations only 2023-05-22 12:37:26 +01:00
gingerBill 18c5a53685 Add @(require_results) and contextless to procedures in core:math/bits 2023-05-22 12:13:44 +01:00
gingerBill a1172d31f4 Add @(require_results) to core:math/fixed 2023-05-22 12:11:53 +01:00
gingerBill 396debb9cb Add @(require_results) to core:math/linalg's glsl and hlsl packages 2023-05-22 12:11:18 +01:00
gingerBill c4cb2f2378 Add "contextless" to core:math/linalg procedures 2023-05-22 12:07:37 +01:00
gingerBill 74ce99e0d7 Add @(require_results) core:math/linalg procedures 2023-05-22 12:05:56 +01:00
gingerBill 89a233ccd2 Add @(require_results) to core:math/noise 2023-05-22 12:00:17 +01:00
gingerBill 2df6cabee0 Add @(require_results) to core:math/rand 2023-05-22 11:59:44 +01:00
gingerBill 82023cd629 Add @(require_results) to core:math procedures 2023-05-22 11:58:01 +01:00
gingerBill 1e17f44991 Improve error handling for resize and reserve procedures 2023-05-22 11:47:36 +01:00
gingerBill 600c97cc0f Add missing Allocator_Error and @(require_results) to many procedures 2023-05-22 11:34:38 +01:00
gingerBill 7298054974 Add require_results to make builtin procedures 2023-05-22 11:19:13 +01:00
J.C. Moyer 4d5a442d1f Use compound literal storage for ValueDecl lvals
Prior to this commit, if a variable was initialized using a compound
literal, its associated storage would not be set. This commit makes the
variable always take on the storage of the compound literal.

Fixes #2466
2023-05-21 16:43:34 -04:00
J.C. Moyer 249f42f054 Add test for #2466 2023-05-21 16:42:48 -04:00
NoahR02 87788142bf Generate the new vulkan files 2023-05-20 19:15:32 -04:00
NoahR02 f0b08a6c67 Add required metal types 2023-05-20 19:14:19 -04:00
NoahR02 a144a49a9a Parse vulkan video constants in seperate section and
add MAX_SHADER_MODULE_IDENTIFIER_SIZE_EXT to the base constants
2023-05-20 19:07:34 -04:00
NoahR02 2167f1b567 Make sure the 's' is after Flags and not the ext name 2023-05-20 18:58:40 -04:00
NoahR02 c5c723b80c Parse C bit fields in parse_structs 2023-05-20 18:42:49 -04:00
NoahR02 66461c9dbc Parse Vulkan Video headers 2023-05-20 18:28:39 -04:00
NoahR02 d77103e53e Add MicromapUsageEXT** to convert_type
We should probably parse this in parse_structs.
2023-05-20 18:18:50 -04:00
Jeroen van Rijn 963908e508 Merge pull request #2548 from ntn9995/fix_stb_truetype
add missing fields to fontinfo
2023-05-20 15:33:11 +02:00
ikarus 9e5677ab02 add missing fields to fontinfo 2023-05-20 20:07:41 +07:00
gingerBill 46bb9bc5c7 Enforce an icmp when casting to i1 to correct behaviour for booleans which are not 0 or 1 2023-05-20 12:41:30 +01:00
Jeroen van Rijn 118ab60588 Merge pull request #2521 from elusivePorpoise/main
remove misleading defer if example
2023-05-19 22:01:13 +02:00
Elusive Porpoise 223ae61c89 added error printing 2023-05-19 11:36:53 -07:00
Jeroen van Rijn 1f4baba06e Merge pull request #2479 from Naught00/master
Change default executable extension for non-Windows platforms
2023-05-19 20:09:39 +02:00
Mark Naughton fa1ce7d5d1 Fix accidental check in 2023-05-19 18:56:35 +01:00
Mark Naughton 775a488a36 Fix windows write_directory() 2023-05-19 18:53:43 +01:00
Mark Naughton 018904f0ec Add write permissions check on output folder 2023-05-19 18:37:55 +01:00
Jeroen van Rijn b358641e7d Merge pull request #2547 from laytan/parse-address-can-return-nil
fix parse_address can return nil
2023-05-19 19:28:24 +02:00
Laytan Laats ff745e0ad8 fix parse_address can return nil 2023-05-19 19:14:25 +02:00
gingerBill 4201834b18 Make intrinsics.type_merge form a union of the types; ignoring duplicates 2023-05-19 12:11:18 +01:00
gingerBill 2631e07bea Add intrinsics.type_merge 2023-05-19 11:18:20 +01:00
Jeroen van Rijn 76a1851cb8 Merge pull request #2546 from kstreets/master
Fix #2545 - Typo in vec4 lerping procedures
2023-05-18 22:40:44 +02:00
KyleRhoads45 87a1792677 Fix #2545 - Typo in vec4 lerping procedures 2023-05-18 13:19:22 -07:00
Mark Naughton 413077a5d9 Fix single-file package case 2023-05-18 13:23:17 +01:00
gingerBill d56fdd2937 Add fmt:"s,0" tags to UTF-16 strings in dxgi.odin 2023-05-18 12:00:23 +01:00
gingerBill 6639b7d017 Merge pull request #2500 from Ahsan-Sarbaz/master
Fixed a bug in DXGI
2023-05-18 11:57:55 +01:00
gingerBill 7702a488e5 Merge pull request #2474 from cshenton/patch-1
Add Dynamic Resource Root Signature flags
2023-05-18 11:56:35 +01:00
gingerBill 3108752a0c Fix #2518 2023-05-18 11:55:37 +01:00
gingerBill 56c0d32ea0 Fix #2526 2023-05-18 11:52:16 +01:00
gingerBill c0e84b0592 Fix #2536 2023-05-18 11:39:18 +01:00
gingerBill f2e590be7a Fix #2544 2023-05-18 11:35:47 +01:00
gingerBill 60ec3594ab Remove unused variable 2023-05-18 11:29:27 +01:00
gingerBill 49d1f6aca0 Merge branch 'master' into separate-int-word-sizes 2023-05-18 11:26:57 +01:00
gingerBill 49cd9648b0 Merge pull request #2512 from jasonKercher/master
update os2 to match core changes
2023-05-18 11:26:16 +01:00
gingerBill 1692dcf8d5 Merge pull request #2514 from ryuukk/patch-2
Missing cast
2023-05-18 11:26:02 +01:00
gingerBill 5ec4719124 Merge pull request #2523 from jcmoyer/fix-2056
Zero non-diagonal elements when converting to matrix
2023-05-18 11:25:44 +01:00
gingerBill 911c98e235 Merge pull request #2525 from laytan/fix-buffer-init-cap-0-wrong-allocator
fix bytes.buffer_init_allocator not using given allocator if len/cap is 0
2023-05-18 11:24:27 +01:00
gingerBill 535c64c318 Merge pull request #2534 from Tetralux/fix-append-nothing-loc
[runtime] Pass along #caller_location in append_nothing()
2023-05-18 11:23:46 +01:00
gingerBill 171f38b9b5 Allow implicit conversion between boolean types within or_return
This is to improve the experience using third-party code, especially foreign C-like code which may use a distinct boolean or a different sized one
2023-05-18 11:06:02 +01:00
jason b2645b3201 add rehash to map_shrink_dynamic 2023-05-17 00:06:31 -04:00
jason a9936d1570 implement random map seed 2023-05-16 23:49:55 -04:00
jason 3032a4274d implement backward shift during map insertion 2023-05-16 16:56:32 -04:00
Jeroen van Rijn 31c21a054b Merge pull request #2543 from Yawning/fix/cpuid-test
core/sys/info: Fix the CPUID check
2023-05-16 17:04:42 +02:00
Yawning Angel def4fdc3f3 core/sys/info: Fix the CPUID check
This needs to test that the n-th bit is set.
2023-05-16 23:52:15 +09:00
Jeroen van Rijn 3fed1af7df Merge pull request #2542 from Yawning/bug/cpuid-osxsave
core/sys/info: Workaround extremely rare XGETBV issues
2023-05-16 16:07:43 +02:00
Yawning Angel adb4692ce8 core/sys/info: Workaround extremely rare XGETBV issues
Someone ran into this on Discord, so adopt the same workaround that
chrome did, by checking both OSXSAVE and XSAVE before calling XGETBV.

The old way of detecting AVX is correct per Intel, but such is life.
2023-05-16 22:56:16 +09:00
gingerBill bb4ff84a4a Add extra mutex for error block stuff 2023-05-16 11:52:02 +01:00
Jeroen van Rijn 5d2c1b175e Merge pull request #2541 from laytan/add-hex-and-expand-percent-decoding
fix hex.encode and add tests for the package
2023-05-15 22:32:27 +02:00
Laytan Laats 2ab6de8ee4 fix hex.encode and add tests for the package 2023-05-15 20:52:07 +02:00
Jeroen van Rijn 1896ae5d15 Merge pull request #2533 from laytan/add-hex-and-expand-percent-decoding
add encoding/hex and use it to expand the percent decoding chars
2023-05-15 19:25:31 +02:00
Laytan Laats 6e4fab19a2 fix indentation and simplify hex.decode_sequence 2023-05-15 18:40:36 +02:00
gingerBill 103dcfe897 Merge pull request #2539 from powerc9000/patch-6
lua MAXSTACK should be 1000000 on 32 bits OR greater
2023-05-14 22:05:28 +01:00
Clay Murray 8caadbacf7 lua MAXSTACK should be 1000000 on 32 bits OR greater
Code only checks if 4 bytes for `rawptr` size. However lua defines the macro (that I assume the odin code is based on) as:

```
/*
@@ LUAI_IS32INT is true iff 'int' has (at least) 32 bits.
*/
#define LUAI_IS32INT	((UINT_MAX >> 30) >= 3)
```

This error broke `upvalues` because it would be looking for the wrong index for lua to find them at.
2023-05-14 14:00:38 -06:00
Jeroen van Rijn 870d776875 Merge pull request #2537 from CORDEA/feature/join-url-queries
Join URL queries with &
2023-05-14 09:03:10 +02:00
Yoshihiro Tanaka 59e66ffe49 Add test for net.split_url 2023-05-14 12:15:20 +09:00
Yoshihiro Tanaka 418a0132d0 Join URL queries with & 2023-05-14 12:15:20 +09:00
Laytan Laats a381846034 add encoding/hex and use it to expand the percent decoding chars 2023-05-14 03:23:24 +02:00
Tetralux 1c5ce75d9f [runtime] Pass along #caller_location in append_nothing() 2023-05-12 23:05:28 +00:00
gingerBill 8693a045bb Revert "Change intrinsics.read_cycle_counter on ARM64"
This reverts commit b567679eb6.
2023-05-12 11:50:49 +01:00
gingerBill b567679eb6 Change intrinsics.read_cycle_counter on ARM64 2023-05-12 11:34:01 +01:00
Jeroen van Rijn e6c8d3d1db Merge pull request #2532 from j0-1/j0-1-patch-1
Fixed incorrect header and typo
2023-05-11 22:28:37 +02:00
j0-1 12c4afd824 Fixed incorrect header and typo 2023-05-11 11:26:16 -07:00
Jeroen van Rijn 968a07ed7a Merge pull request #2531 from jasonKercher/fix2530
add nil check to heap_alloc calls (issue 2530)
2023-05-11 20:20:03 +02:00
jason f9c600a760 add nil check to heap_alloc calls (issue 2530) 2023-05-11 14:04:09 -04:00
Jeroen van Rijn 82561cfbac Merge pull request #2528 from matias-eduardo/patch-1
Patch "no_copy" typo in parser.cpp
2023-05-10 09:11:46 +02:00
matias 277ae4e2b0 Patch "no_copy" typo in parser.cpp 2023-05-10 02:58:17 -04:00
Jeroen van Rijn 0f9e747583 Merge pull request #2520 from matias-eduardo/master
Allow for custom sleep duration in tsc frequency fallback
2023-05-09 23:03:47 +02:00
Matias Fernandez 4e146a75b6 Allow user to pass in scale directly in spall.context_create 2023-05-09 16:43:26 -04:00
Jeroen van Rijn 33d0e2037b Merge pull request #2524 from laytan/fix-url-parse-leak
fix leak in url_parse
2023-05-09 21:46:51 +02:00
Laytan Laats 7a04b7262e fix bytes.buffer_init_allocator not using given allocator if len/cap is 0 2023-05-09 21:25:15 +02:00
Laytan Laats f2d5e4b995 fix leak in url_parse 2023-05-09 21:05:16 +02:00
J.C. Moyer ada42aa184 Add test for issue #2056 2023-05-09 12:37:12 -04:00
J.C. Moyer ed580b3060 Zero non-diagonal elements when converting to matrix
Fixes #2056
2023-05-09 12:00:38 -04:00
Jeroen van Rijn 29e4762011 Merge pull request #2519 from colrdavidson/revert-2462-master
Revert "Fix: header directories in Unix build script"
2023-05-09 08:27:47 +02:00
Elusive Porpoise eff4833840 remove misleading example 2023-05-08 23:13:27 -07:00
Matias Fernandez 9867037aa2 Revert "Add the waits that support I/O completion routines in kernel32.odin"
This reverts commit 46da53ba15.
2023-05-09 00:16:17 -04:00
Matias Fernandez 57c14f6a9b Allow custom sleep on tsc fallback.
This gives the user more control over the spectrum of precision vs. load time on Windows. Spall's output with much lower sleep times is still useful in my experience.

NOTE: A better API might be to allow the user to pass the freq as a param to "create_context" in case they already paid for it beforehand, but this seems fine for now.
2023-05-09 00:03:58 -04:00
Matias Fernandez 1ed105205c Merge branch 'master' of https://github.com/matias-eduardo/Odin 2023-05-08 23:52:21 -04:00
Colin Davidson 8233f49beb Revert "Fix: header directories in Unix build script" 2023-05-08 20:13:33 -07:00
Jeroen van Rijn 2c01a4613c Merge pull request #2516 from colrdavidson/read_at_fix
Make read_at and write_at more consistent between platforms
2023-05-07 08:52:37 +02:00
Colin Davidson b0eda47b26 prevent infinite-loop on EOF 2023-05-06 17:52:08 -07:00
Colin Davidson 291111e626 oops. define e 2023-05-06 17:23:44 -07:00
Colin Davidson 47693da4aa Make read_at and write_at more consistent between platforms 2023-05-06 17:14:11 -07:00
Jeroen van Rijn 9f39209712 Merge pull request #2513 from laytan/add-time-weekday
add time.weekday proc
2023-05-06 20:20:13 +02:00
Laytan Laats c47dcbbe2f fix spacing 2023-05-06 19:39:39 +02:00
ryuukk f313538ea5 Missing cast 2023-05-06 18:00:33 +02:00
Laytan Laats 956ffdf654 add time.weekday proc 2023-05-05 20:55:59 +02:00
jason ef4a527c36 default to O_NOCTTY in open 2023-05-04 11:46:39 -04:00
jason 3fe0680ad5 update os2 for recent core changes 2023-05-04 10:00:06 -04:00
gingerBill 182b269e46 Merge pull request #2511 from zhibog/botan3
Add Botan3 libraries and use VS 2022 for Windows builds
2023-05-03 22:14:17 +01:00
zhibog 05856ac93e Change nightly to VS 2022 too 2023-05-03 21:51:40 +02:00
zhibog 60c29e195a Windows requires the botan-3 naming due to the new release 2023-05-03 21:35:06 +02:00
zhibog 6b23662ce6 Fix typo 2023-05-03 21:15:50 +02:00
zhibog 77d6364405 Try Windows 2022, since the windows tests failed. Likely because I compiled them on a newer version of VS. Also added another when statement to make sure Linux still uses botan-2, because they haven't updated 2023-05-03 21:12:27 +02:00
zhibog 077a611a5e Add Botan 3.0, comment some tests, due to removed algorithms 2023-05-03 20:55:11 +02:00
gingerBill e82146bf17 Merge branch 'master' into separate-int-word-sizes 2023-05-03 17:06:37 +01:00
Jon Lipstate f5dcbf517b helpful errors custom-attrs 2023-04-30 18:36:00 -07:00
Ahsan-Sarbaz 808e7ed4ae Fixed Bug in DXGI 2023-05-01 00:16:20 +05:00
Mark Naughton 4b4481ea27 Simplify extension addition logic 2023-04-26 16:39:47 +01:00
Mark Naughton e84802468b Use buildpath instead of init_filename 2023-04-26 15:48:59 +01:00
Mark Naughton 1a5ed4eb7f Fix .bin not being applied for relative directory 2023-04-26 14:10:22 +01:00
Mark Naughton 5151403aaa Fix Windows version of get_current_directory 2023-04-25 12:08:15 +01:00
Mark Naughton 67b6a8ee89 Add Windows equivalent of get_current_directory 2023-04-24 14:26:53 +01:00
Mark Naughton 780375d865 Add .bin extension in extra case 2023-04-24 12:57:59 +01:00
Mark Naughton cbcf94669e Add get_current_directory() 2023-04-24 12:57:34 +01:00
Matias Fernandez 46da53ba15 Add the waits that support I/O completion routines in kernel32.odin 2023-04-23 22:08:12 -04:00
Mark Naughton 06e8d03fba Use last element for directory collision check 2023-04-23 21:15:08 +01:00
Mark Naughton a6b9341593 Add .bin extension the case of a collision
The directory name is used to determine the executable name. In the case
that the directory and output executable are in conflict, a .bin
extension is added.
2023-04-23 18:53:00 +01:00
Mark Naughton 47610725ea Change default executable extension
Putting a program into your path on a UNIX system with a
file extension means that you have to type the extension out for every
invocation of the program. A better default is to have no extension at
all since most people will end up removing it anyway.

This change does not affect Windows since the .exe extension is set
after the default extension if compiling on Windows.
2023-04-23 17:02:56 +01:00
Charlie Shenton c7d4af5c79 Add Dynamic Resource Root Signature flags
Add flag values associated with dynamics resources (ResourceDescriptorHeap and SamplerDescriptorHeap) see https://microsoft.github.io/DirectX-Specs/d3d/HLSL_SM_6_6_DynamicResources.html for details
2023-04-22 16:39:01 +10:00
gingerBill 685f7d0fea Rename word_size to ptr_size internally to make it clearer 2023-04-20 12:18:13 +01:00
gingerBill f5d9ca64f9 Begin work on new pseudo-architecture: wasm64p32 2023-04-20 12:02:32 +01:00
gingerBill cde442fa2c Add internal padding to types where ptr size != int size 2023-04-20 11:55:18 +01:00
gingerBill 84f966cb8f Begin work on separating int and word sizes (i.e. size_of(int) might not equal size_of(uintptr)) 2023-04-20 11:46:41 +01:00
Skytrias f36e19e86f fix GL2 2022-12-24 11:47:57 +01:00
Skytrias 86fada718e optional constants, starting GL2 fixes 2022-12-24 11:30:15 +01:00
Skytrias 2a94b66f4d test 2022-12-24 11:19:12 +01:00
Michael Kutowski 4ee413aa32 Merge branch 'odin-lang:master' into skytrias-vendor-additions 2022-12-24 10:39:01 +01:00
Lucas Perlind 2d824e4809 Fix out or range error with _alloc_command_line_arguments in darwin 2022-12-23 09:37:30 +11:00
skytrias 9474c99795 add freeLoadedData flag in case you dont want to remove font memory (e.g. #load) 2022-12-21 01:36:00 +01:00
Michael Kutowski 84a7f222ff mention fontstash and nanovg in reamde 2022-12-20 12:27:23 +01:00
skytrias d29423c24e add fontstash and nanovg port from heimdall 2022-12-20 12:17:23 +01:00
gingerBill 02a8bba02e Merge branch 'master' into fix/freebsd-syscall 2022-07-24 22:27:45 +01:00
Yawning Angel 6ea68869c9 src: "Fix" the system call intrinsic for FreeBSD
FreeBSD's systemcall handler clears out R8, R9, and R10 prior to
`sysretq`, and additionally returns positive errno (with CF) set on
error.  This modifies the syscall intrinsic such that LLVM knows
about the additional clobbered registers.

Note that propagating CF back to the caller of the syscall intrinsic
is left for a future PR.  As far as I can tell, Darwin does not use
the syscall intrinsic at all, and FreeBSD only uses it for SYS_GETTID,
so this should be "ok" for now.

See: sys/amd64/amd64/exception.S in the FreeBSD src for more details.
2021-11-13 20:40:27 +00:00
333 changed files with 33583 additions and 16504 deletions
+19 -14
View File
@@ -56,9 +56,9 @@ jobs:
runs-on: macos-latest
steps:
- uses: actions/checkout@v1
- name: Download LLVM and setup PATH
- name: Download LLVM, botan and setup PATH
run: |
brew install llvm@11
brew install llvm@11 botan
echo "/usr/local/opt/llvm@11/bin" >> $GITHUB_PATH
TMP_PATH=$(xcrun --show-sdk-path)/user/include
echo "CPATH=$TMP_PATH" >> $GITHUB_ENV
@@ -87,6 +87,11 @@ jobs:
cd tests/core
make
timeout-minutes: 10
- name: Vendor library tests
run: |
cd tests/vendor
make
timeout-minutes: 10
- name: Odin internals tests
run: |
cd tests/internal
@@ -99,13 +104,13 @@ jobs:
run: ./odin check examples/all -vet -strict-style -target:linux_arm64
timeout-minutes: 10
build_windows:
runs-on: windows-2019
runs-on: windows-2022
steps:
- uses: actions/checkout@v1
- name: build Odin
shell: cmd
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
- name: Odin version
run: ./odin version
@@ -116,65 +121,65 @@ jobs:
- name: Odin check
shell: cmd
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
timeout-minutes: 10
- name: Odin run
shell: cmd
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
timeout-minutes: 10
- name: Odin run -debug
shell: cmd
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
timeout-minutes: 10
- name: Odin check examples/all
shell: cmd
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
timeout-minutes: 10
- name: Core library tests
shell: cmd
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
call build.bat
timeout-minutes: 10
- name: Vendor library tests
shell: cmd
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
call build.bat
timeout-minutes: 10
- name: Odin internals tests
shell: cmd
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
call build.bat
timeout-minutes: 10
- name: Odin documentation tests
shell: cmd
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
call build.bat
timeout-minutes: 10
- name: core:math/big tests
shell: cmd
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
call build.bat
timeout-minutes: 10
- name: Odin check examples/all for Windows 32bits
shell: cmd
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
timeout-minutes: 10
+6 -3
View File
@@ -7,18 +7,19 @@ on:
jobs:
build_windows:
runs-on: windows-2019
if: github.repository == 'odin-lang/Odin'
runs-on: windows-2022
steps:
- uses: actions/checkout@v1
- name: build Odin
shell: cmd
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
- name: Odin run
shell: cmd
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
- name: Copy artifacts
run: |
@@ -37,6 +38,7 @@ jobs:
name: windows_artifacts
path: dist
build_ubuntu:
if: github.repository == 'odin-lang/Odin'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
@@ -61,6 +63,7 @@ jobs:
name: ubuntu_artifacts
path: dist
build_macos:
if: github.repository == 'odin-lang/Odin'
runs-on: macOS-latest
steps:
- uses: actions/checkout@v1
+2 -1
View File
@@ -270,6 +270,7 @@ bin/
# - Linux/MacOS
odin
!odin/
odin.dSYM
*.bin
demo.bin
@@ -286,4 +287,4 @@ shared/
*.sublime-workspace
examples/bug/
build.sh
!core/debug/
!core/debug/
+15 -10
View File
@@ -3,18 +3,20 @@
setlocal EnableDelayedExpansion
where /Q cl.exe || (
set __VSCMD_ARG_NO_LOGO=1
for /f "tokens=*" %%i in ('"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe" -latest -requires Microsoft.VisualStudio.Workload.NativeDesktop -property installationPath') do set VS=%%i
if "!VS!" equ "" (
echo ERROR: Visual Studio installation not found
exit /b 1
)
call "!VS!\VC\Auxiliary\Build\vcvarsall.bat" amd64 || exit /b 1
set __VSCMD_ARG_NO_LOGO=1
for /f "tokens=*" %%i in ('"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe" -latest -requires Microsoft.VisualStudio.Workload.NativeDesktop -property installationPath') do set VS=%%i
if "!VS!" equ "" (
echo ERROR: Visual Studio installation not found
exit /b 1
)
call "!VS!\VC\Auxiliary\Build\vcvarsall.bat" amd64 || exit /b 1
)
if "%VSCMD_ARG_TGT_ARCH%" neq "x64" (
echo ERROR: please run this from MSVC x64 native tools command prompt, 32-bit target is not supported!
exit /b 1
if "%ODIN_IGNORE_MSVC_CHECK%" == "" (
echo ERROR: please run this from MSVC x64 native tools command prompt, 32-bit target is not supported!
exit /b 1
)
)
for /f "usebackq tokens=1,2 delims=,=- " %%i in (`wmic os get LocalDateTime /value`) do @if %%i==LocalDateTime (
@@ -49,7 +51,10 @@ set compiler_flags= -nologo -Oi -TP -fp:precise -Gm- -MP -FC -EHsc- -GR- -GF
set compiler_defines= -DODIN_VERSION_RAW=\"%odin_version_raw%\"
if not exist .git\ goto skip_git_hash
for /f %%i in ('git rev-parse --short HEAD') do set GIT_SHA=%%i
for /f "tokens=1,2" %%i IN ('git show "--pretty=%%cd %%h" "--date=format:%%Y-%%m" --no-patch --no-notes HEAD') do (
set odin_version_raw=dev-%%i
set GIT_SHA=%%j
)
if %ERRORLEVEL% equ 0 set compiler_defines=%compiler_defines% -DGIT_SHA=\"%GIT_SHA%\"
:skip_git_hash
+16 -8
View File
@@ -4,23 +4,24 @@ set -eu
: ${CXX=clang++}
: ${CPPFLAGS=}
: ${CXXFLAGS=}
: ${INCLUDE_DIRECTORIES=}
: ${LDFLAGS=}
: ${ODIN_VERSION=dev-$(date +"%Y-%m")}
: ${GIT_SHA=}
CPPFLAGS="$CPPFLAGS -DODIN_VERSION_RAW=\"$ODIN_VERSION\""
CXXFLAGS="$CXXFLAGS -std=c++14"
INCLUDE_DIRECTORIES="$INCLUDE_DIRECTORIES -Isrc/"
LDFLAGS="$LDFLAGS -pthread -lm -lstdc++"
if [ -d ".git" ]; then
GIT_SHA=$(git rev-parse --short HEAD || :)
if [ "$GIT_SHA" ]; then
if [ -d ".git" ] && [ $(which git) ]; then
versionTag=( $(git show --pretty='%cd %h' --date=format:%Y-%m --no-patch --no-notes HEAD) )
if [ $? -eq 0 ]; then
ODIN_VERSION="dev-${versionTag[0]}"
GIT_SHA="${versionTag[1]}"
CPPFLAGS="$CPPFLAGS -DGIT_SHA=\"$GIT_SHA\""
fi
fi
CPPFLAGS="$CPPFLAGS -DODIN_VERSION_RAW=\"$ODIN_VERSION\""
DISABLED_WARNINGS="-Wno-switch -Wno-macro-redefined -Wno-unused-value"
OS=$(uname)
@@ -137,7 +138,14 @@ build_odin() {
EXTRAFLAGS="-O3"
;;
release-native)
EXTRAFLAGS="-O3 -march=native"
local ARCH=$(uname -m)
if [ "${ARCH}" == "arm64" ]; then
# Use preferred flag for Arm (ie arm64 / aarch64 / etc)
EXTRAFLAGS="-O3 -mcpu=native"
else
# Use preferred flag for x86 / amd64
EXTRAFLAGS="-O3 -march=native"
fi
;;
nightly)
EXTRAFLAGS="-DNIGHTLY -O3"
@@ -148,7 +156,7 @@ build_odin() {
esac
set -x
$CXX src/main.cpp src/libtommath.cpp $DISABLED_WARNINGS $CPPFLAGS $CXXFLAGS $INCLUDE_DIRECTORIES $EXTRAFLAGS $LDFLAGS -o odin
$CXX src/main.cpp src/libtommath.cpp $DISABLED_WARNINGS $CPPFLAGS $CXXFLAGS $EXTRAFLAGS $LDFLAGS -o odin
set +x
}
+22 -44
View File
@@ -14,51 +14,29 @@ read_writer_init :: proc(rw: ^Read_Writer, r: ^Reader, w: ^Writer) {
}
read_writer_to_stream :: proc(rw: ^Read_Writer) -> (s: io.Stream) {
s.stream_data = rw
s.stream_vtable = &_read_writer_vtable
s.procedure = _read_writer_procedure
s.data = rw
return
}
@(private)
_read_writer_vtable := io.Stream_VTable{
impl_read = proc(s: io.Stream, p: []byte) -> (n: int, err: io.Error) {
b := (^Read_Writer)(s.stream_data).r
return reader_read(b, p)
},
impl_unread_byte = proc(s: io.Stream) -> io.Error {
b := (^Read_Writer)(s.stream_data).r
return reader_unread_byte(b)
},
impl_read_rune = proc(s: io.Stream) -> (r: rune, size: int, err: io.Error) {
b := (^Read_Writer)(s.stream_data).r
return reader_read_rune(b)
},
impl_unread_rune = proc(s: io.Stream) -> io.Error {
b := (^Read_Writer)(s.stream_data).r
return reader_unread_rune(b)
},
impl_write_to = proc(s: io.Stream, w: io.Writer) -> (n: i64, err: io.Error) {
b := (^Read_Writer)(s.stream_data).r
return reader_write_to(b, w)
},
impl_flush = proc(s: io.Stream) -> io.Error {
b := (^Read_Writer)(s.stream_data).w
return writer_flush(b)
},
impl_write = proc(s: io.Stream, p: []byte) -> (n: int, err: io.Error) {
b := (^Read_Writer)(s.stream_data).w
return writer_write(b, p)
},
impl_write_byte = proc(s: io.Stream, c: byte) -> io.Error {
b := (^Read_Writer)(s.stream_data).w
return writer_write_byte(b, c)
},
impl_write_rune = proc(s: io.Stream, r: rune) -> (int, io.Error) {
b := (^Read_Writer)(s.stream_data).w
return writer_write_rune(b, r)
},
impl_read_from = proc(s: io.Stream, r: io.Reader) -> (n: i64, err: io.Error) {
b := (^Read_Writer)(s.stream_data).w
return writer_read_from(b, r)
},
}
_read_writer_procedure := proc(stream_data: rawptr, mode: io.Stream_Mode, p: []byte, offset: i64, whence: io.Seek_From) -> (n: i64, err: io.Error) {
rw := (^Read_Writer)(stream_data)
n_int: int
#partial switch mode {
case .Flush:
err = writer_flush(rw.w)
return
case .Read:
n_int, err = reader_read(rw.r, p)
n = i64(n_int)
return
case .Write:
n_int, err = writer_write(rw.w, p)
n = i64(n_int)
return
case .Query:
return io.query_utility({.Flush, .Read, .Write, .Query})
}
return 0, .Empty
}
+13 -45
View File
@@ -311,18 +311,6 @@ reader_write_to :: proc(b: ^Reader, w: io.Writer) -> (n: i64, err: io.Error) {
}
m: i64
if nr, ok := io.to_writer_to(b.rd); ok {
m, err = io.write_to(nr, w)
n += m
return n, err
}
if nw, ok := io.to_reader_from(w); ok {
m, err = io.read_from(nw, b.rd)
n += m
return n, err
}
if b.w-b.r < len(b.buf) {
if err = _reader_read_new_chunk(b); err != nil {
return
@@ -352,48 +340,28 @@ reader_write_to :: proc(b: ^Reader, w: io.Writer) -> (n: i64, err: io.Error) {
// reader_to_stream converts a Reader into an io.Stream
reader_to_stream :: proc(b: ^Reader) -> (s: io.Stream) {
s.stream_data = b
s.stream_vtable = &_reader_vtable
s.data = b
s.procedure = _reader_proc
return
}
@(private)
_reader_vtable := io.Stream_VTable{
impl_destroy = proc(s: io.Stream) -> io.Error {
b := (^Reader)(s.stream_data)
_reader_proc :: proc(stream_data: rawptr, mode: io.Stream_Mode, p: []byte, offset: i64, whence: io.Seek_From) -> (n: i64, err: io.Error) {
b := (^Reader)(stream_data)
#partial switch mode {
case .Read:
return io._i64_err(reader_read(b, p))
case .Destroy:
reader_destroy(b)
return nil
},
impl_read = proc(s: io.Stream, p: []byte) -> (n: int, err: io.Error) {
b := (^Reader)(s.stream_data)
return reader_read(b, p)
},
impl_read_byte = proc(s: io.Stream) -> (c: byte, err: io.Error) {
b := (^Reader)(s.stream_data)
return reader_read_byte(b)
},
impl_unread_byte = proc(s: io.Stream) -> io.Error {
b := (^Reader)(s.stream_data)
return reader_unread_byte(b)
},
impl_read_rune = proc(s: io.Stream) -> (r: rune, size: int, err: io.Error) {
b := (^Reader)(s.stream_data)
return reader_read_rune(b)
},
impl_unread_rune = proc(s: io.Stream) -> io.Error {
b := (^Reader)(s.stream_data)
return reader_unread_rune(b)
},
impl_write_to = proc(s: io.Stream, w: io.Writer) -> (n: i64, err: io.Error) {
b := (^Reader)(s.stream_data)
return reader_write_to(b, w)
},
return
case .Query:
return io.query_utility({.Read, .Destroy, .Query})
}
return 0, .Empty
}
//
// Utility procedures
//
+20 -39
View File
@@ -173,14 +173,6 @@ writer_read_from :: proc(b: ^Writer, r: io.Reader) -> (n: i64, err: io.Error) {
if b.err != nil {
return 0, b.err
}
if writer_buffered(b) == 0 {
if w, ok := io.to_reader_from(b.wr); !ok {
n, err = io.read_from(w, r)
b.err = err
return
}
}
for {
if writer_available(b) == 0 {
writer_flush(b) or_return
@@ -222,46 +214,35 @@ writer_read_from :: proc(b: ^Writer, r: io.Reader) -> (n: i64, err: io.Error) {
// writer_to_stream converts a Writer into an io.Stream
writer_to_stream :: proc(b: ^Writer) -> (s: io.Stream) {
s.stream_data = b
s.stream_vtable = &_writer_vtable
s.data = b
s.procedure = _writer_proc
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
return writer_to_stream(b)
}
@(private)
_writer_vtable := io.Stream_VTable{
impl_destroy = proc(s: io.Stream) -> io.Error {
b := (^Writer)(s.stream_data)
_writer_proc :: proc(stream_data: rawptr, mode: io.Stream_Mode, p: []byte, offset: i64, whence: io.Seek_From) -> (n: i64, err: io.Error) {
b := (^Writer)(stream_data)
#partial switch mode {
case .Flush:
err = writer_flush(b)
return
case .Write:
n_int: int
n_int, err = writer_write(b, p)
n = i64(n_int)
return
case .Destroy:
writer_destroy(b)
return nil
},
impl_flush = proc(s: io.Stream) -> io.Error {
b := (^Writer)(s.stream_data)
return writer_flush(b)
},
impl_write = proc(s: io.Stream, p: []byte) -> (n: int, err: io.Error) {
b := (^Writer)(s.stream_data)
return writer_write(b, p)
},
impl_write_byte = proc(s: io.Stream, c: byte) -> io.Error {
b := (^Writer)(s.stream_data)
return writer_write_byte(b, c)
},
impl_write_rune = proc(s: io.Stream, r: rune) -> (int, io.Error) {
b := (^Writer)(s.stream_data)
return writer_write_rune(b, r)
},
impl_read_from = proc(s: io.Stream, r: io.Reader) -> (n: i64, err: io.Error) {
b := (^Writer)(s.stream_data)
return writer_read_from(b, r)
},
return
case .Query:
return io.query_utility({.Flush, .Write, .Destroy, .Query})
}
return 0, .Empty
}
+27 -60
View File
@@ -38,6 +38,11 @@ buffer_init_string :: proc(b: ^Buffer, s: string) {
}
buffer_init_allocator :: proc(b: ^Buffer, len, cap: int, allocator := context.allocator) {
if b.buf == nil {
b.buf = make([dynamic]byte, len, cap, allocator)
return
}
b.buf.allocator = allocator
reserve(&b.buf, cap)
resize(&b.buf, len)
@@ -370,69 +375,31 @@ buffer_read_from :: proc(b: ^Buffer, r: io.Reader) -> (n: i64, err: io.Error) #n
buffer_to_stream :: proc(b: ^Buffer) -> (s: io.Stream) {
s.stream_data = b
s.stream_vtable = &_buffer_vtable
s.data = b
s.procedure = _buffer_proc
return
}
@(private)
_buffer_vtable := io.Stream_VTable{
impl_size = proc(s: io.Stream) -> i64 {
b := (^Buffer)(s.stream_data)
return i64(buffer_capacity(b))
},
impl_read = proc(s: io.Stream, p: []byte) -> (n: int, err: io.Error) {
b := (^Buffer)(s.stream_data)
return buffer_read(b, p)
},
impl_read_at = proc(s: io.Stream, p: []byte, offset: i64) -> (n: int, err: io.Error) {
b := (^Buffer)(s.stream_data)
return buffer_read_at(b, p, int(offset))
},
impl_read_byte = proc(s: io.Stream) -> (byte, io.Error) {
b := (^Buffer)(s.stream_data)
return buffer_read_byte(b)
},
impl_read_rune = proc(s: io.Stream) -> (r: rune, size: int, err: io.Error) {
b := (^Buffer)(s.stream_data)
return buffer_read_rune(b)
},
impl_write = proc(s: io.Stream, p: []byte) -> (n: int, err: io.Error) {
b := (^Buffer)(s.stream_data)
return buffer_write(b, p)
},
impl_write_at = proc(s: io.Stream, p: []byte, offset: i64) -> (n: int, err: io.Error) {
b := (^Buffer)(s.stream_data)
return buffer_write_at(b, p, int(offset))
},
impl_write_byte = proc(s: io.Stream, c: byte) -> io.Error {
b := (^Buffer)(s.stream_data)
return buffer_write_byte(b, c)
},
impl_write_rune = proc(s: io.Stream, r: rune) -> (int, io.Error) {
b := (^Buffer)(s.stream_data)
return buffer_write_rune(b, r)
},
impl_unread_byte = proc(s: io.Stream) -> io.Error {
b := (^Buffer)(s.stream_data)
return buffer_unread_byte(b)
},
impl_unread_rune = proc(s: io.Stream) -> io.Error {
b := (^Buffer)(s.stream_data)
return buffer_unread_rune(b)
},
impl_destroy = proc(s: io.Stream) -> io.Error {
b := (^Buffer)(s.stream_data)
_buffer_proc :: proc(stream_data: rawptr, mode: io.Stream_Mode, p: []byte, offset: i64, whence: io.Seek_From) -> (n: i64, err: io.Error) {
b := (^Buffer)(stream_data)
#partial switch mode {
case .Read:
return io._i64_err(buffer_read(b, p))
case .Read_At:
return io._i64_err(buffer_read_at(b, p, int(offset)))
case .Write:
return io._i64_err(buffer_write(b, p))
case .Write_At:
return io._i64_err(buffer_write_at(b, p, int(offset)))
case .Size:
n = i64(buffer_capacity(b))
return
case .Destroy:
buffer_destroy(b)
return nil
},
impl_write_to = proc(s: io.Stream, w: io.Writer) -> (n: i64, err: io.Error) {
b := (^Buffer)(s.stream_data)
return buffer_write_to(b, w)
},
impl_read_from = proc(s: io.Stream, r: io.Reader) -> (n: i64, err: io.Error) {
b := (^Buffer)(s.stream_data)
return buffer_read_from(b, r)
},
return
case .Query:
return io.query_utility({.Read, .Read_At, .Write, .Write_At, .Size, .Destroy})
}
return 0, .Empty
}
+20 -39
View File
@@ -16,8 +16,8 @@ reader_init :: proc(r: ^Reader, s: []byte) {
}
reader_to_stream :: proc(r: ^Reader) -> (s: io.Stream) {
s.stream_data = r
s.stream_vtable = &_reader_vtable
s.data = r
s.procedure = _reader_proc
return
}
@@ -137,41 +137,22 @@ reader_write_to :: proc(r: ^Reader, w: io.Writer) -> (n: i64, err: io.Error) {
@(private)
_reader_vtable := io.Stream_VTable{
impl_size = proc(s: io.Stream) -> i64 {
r := (^Reader)(s.stream_data)
return reader_size(r)
},
impl_read = proc(s: io.Stream, p: []byte) -> (n: int, err: io.Error) {
r := (^Reader)(s.stream_data)
return reader_read(r, p)
},
impl_read_at = proc(s: io.Stream, p: []byte, off: i64) -> (n: int, err: io.Error) {
r := (^Reader)(s.stream_data)
return reader_read_at(r, p, off)
},
impl_read_byte = proc(s: io.Stream) -> (byte, io.Error) {
r := (^Reader)(s.stream_data)
return reader_read_byte(r)
},
impl_unread_byte = proc(s: io.Stream) -> io.Error {
r := (^Reader)(s.stream_data)
return reader_unread_byte(r)
},
impl_read_rune = proc(s: io.Stream) -> (ch: rune, size: int, err: io.Error) {
r := (^Reader)(s.stream_data)
return reader_read_rune(r)
},
impl_unread_rune = proc(s: io.Stream) -> io.Error {
r := (^Reader)(s.stream_data)
return reader_unread_rune(r)
},
impl_seek = proc(s: io.Stream, offset: i64, whence: io.Seek_From) -> (i64, io.Error) {
r := (^Reader)(s.stream_data)
return reader_seek(r, offset, whence)
},
impl_write_to = proc(s: io.Stream, w: io.Writer) -> (n: i64, err: io.Error) {
r := (^Reader)(s.stream_data)
return reader_write_to(r, w)
},
_reader_proc :: proc(stream_data: rawptr, mode: io.Stream_Mode, p: []byte, offset: i64, whence: io.Seek_From) -> (n: i64, err: io.Error) {
r := (^Reader)(stream_data)
#partial switch mode {
case .Read:
return io._i64_err(reader_read(r, p))
case .Read_At:
return io._i64_err(reader_read_at(r, p, offset))
case .Seek:
n, err = reader_seek(r, offset, whence)
return
case .Size:
n = reader_size(r)
return
case .Query:
return io.query_utility({.Read, .Read_At, .Seek, .Size, .Query})
}
return 0, .Empty
}
+2 -2
View File
@@ -1118,7 +1118,7 @@ expand_macro :: proc(cpp: ^Preprocessor, rest: ^^Token, tok: ^Token) -> bool {
search_include_next :: proc(cpp: ^Preprocessor, filename: string) -> (path: string, ok: bool) {
for ; cpp.include_next_index < len(cpp.include_paths); cpp.include_next_index += 1 {
tpath := filepath.join(elems={cpp.include_paths[cpp.include_next_index], filename}, allocator=context.temp_allocator)
tpath := filepath.join({cpp.include_paths[cpp.include_next_index], filename}, allocator=context.temp_allocator)
if os.exists(tpath) {
return strings.clone(tpath), true
}
@@ -1136,7 +1136,7 @@ search_include_paths :: proc(cpp: ^Preprocessor, filename: string) -> (path: str
}
for include_path in cpp.include_paths {
tpath := filepath.join(elems={include_path, filename}, allocator=context.temp_allocator)
tpath := filepath.join({include_path, filename}, allocator=context.temp_allocator)
if os.exists(tpath) {
path, ok = strings.clone(tpath), true
cpp.filepath_cache[filename] = path
+3 -2
View File
@@ -188,7 +188,8 @@ input_size_from_memory :: proc(z: ^Context_Memory_Input) -> (res: i64, err: Erro
}
input_size_from_stream :: proc(z: ^Context_Stream_Input) -> (res: i64, err: Error) {
return io.size(z.input), nil
res, _ = io.size(z.input)
return
}
input_size :: proc{input_size_from_memory, input_size_from_stream}
@@ -215,7 +216,7 @@ read_slice_from_stream :: #force_inline proc(z: ^Context_Stream_Input, size: int
// TODO: REMOVE ALL USE OF context.temp_allocator here
// the is literally no need for it
b := make([]u8, size, context.temp_allocator)
_, e := z.input->impl_read(b[:])
_, e := io.read(z.input, b[:])
if e == .None {
return b, .None
}
+1 -1
View File
@@ -335,7 +335,7 @@ load_from_context :: proc(z: ^$C, buf: ^bytes.Buffer, known_gzip_size := -1, exp
// fmt.printf("GZIP: Expected Payload Size: %v\n", expected_output_size);
zlib_error := zlib.inflate_raw(z=z, expected_output_size=expected_output_size)
zlib_error := zlib.inflate_raw(z, expected_output_size=expected_output_size)
if zlib_error != nil {
return zlib_error
}
+4 -8
View File
@@ -177,12 +177,10 @@ decompress_slice_to_string :: proc(input: []u8, model := DEFAULT_MODEL, allocato
max_output_size := decompress_bound(len(input), model)
buf: [dynamic]u8
if !resize(&buf, max_output_size) {
return "", .Out_Of_Memory
}
resize(&buf, max_output_size) or_return
length, result := decompress_slice_to_output_buffer(input, buf[:])
resize(&buf, length)
resize(&buf, length) or_return
return string(buf[:]), result
}
decompress :: proc{decompress_slice_to_output_buffer, decompress_slice_to_string}
@@ -307,12 +305,10 @@ compress_string :: proc(input: string, model := DEFAULT_MODEL, allocator := cont
max_output_size := compress_bound(len(input))
buf: [dynamic]u8
if !resize(&buf, max_output_size) {
return {}, .Out_Of_Memory
}
resize(&buf, max_output_size) or_return
length, result := compress_string_to_buffer(input, buf[:])
resize(&buf, length)
resize(&buf, length) or_return
return buf[:length], result
}
compress :: proc{compress_string_to_buffer, compress_string}
+4 -3
View File
@@ -1,3 +1,4 @@
//+vet !using-param
package zlib
/*
@@ -471,7 +472,7 @@ inflate_from_context :: proc(using ctx: ^compress.Context_Memory_Input, raw := f
}
// Parse ZLIB stream without header.
inflate_raw(z=ctx, expected_output_size=expected_output_size) or_return
inflate_raw(ctx, expected_output_size=expected_output_size) or_return
if !raw {
compress.discard_to_next_byte_lsb(ctx)
@@ -665,7 +666,7 @@ inflate_from_byte_array :: proc(input: []u8, buf: ^bytes.Buffer, raw := false, e
ctx.input_data = input
ctx.output = buf
return inflate_from_context(ctx=&ctx, raw=raw, expected_output_size=expected_output_size)
return inflate_from_context(&ctx, raw=raw, expected_output_size=expected_output_size)
}
inflate_from_byte_array_raw :: proc(input: []u8, buf: ^bytes.Buffer, raw := false, expected_output_size := -1) -> (err: Error) {
@@ -674,7 +675,7 @@ inflate_from_byte_array_raw :: proc(input: []u8, buf: ^bytes.Buffer, raw := fals
ctx.input_data = input
ctx.output = buf
return inflate_raw(z=&ctx, expected_output_size=expected_output_size)
return inflate_raw(&ctx, expected_output_size=expected_output_size)
}
inflate :: proc{inflate_from_context, inflate_from_byte_array}
+11 -11
View File
@@ -14,7 +14,7 @@ Queue :: struct($T: typeid) {
DEFAULT_CAPACITY :: 16
// Procedure to initialize a queue
init :: proc(q: ^$Q/Queue($T), capacity := DEFAULT_CAPACITY, allocator := context.allocator) -> bool {
init :: proc(q: ^$Q/Queue($T), capacity := DEFAULT_CAPACITY, allocator := context.allocator) -> runtime.Allocator_Error {
if q.data.allocator.procedure == nil {
q.data.allocator = allocator
}
@@ -55,11 +55,11 @@ space :: proc(q: $Q/Queue($T)) -> int {
}
// Reserve enough space for at least the specified capacity
reserve :: proc(q: ^$Q/Queue($T), capacity: int) -> bool {
reserve :: proc(q: ^$Q/Queue($T), capacity: int) -> runtime.Allocator_Error {
if uint(capacity) > q.len {
return _grow(q, uint(capacity))
}
return true
return nil
}
@@ -112,25 +112,25 @@ peek_back :: proc(q: ^$Q/Queue($T), loc := #caller_location) -> ^T {
}
// Push an element to the back of the queue
push_back :: proc(q: ^$Q/Queue($T), elem: T) -> bool {
push_back :: proc(q: ^$Q/Queue($T), elem: T) -> (ok: bool, err: runtime.Allocator_Error) {
if space(q^) == 0 {
_grow(q) or_return
}
idx := (q.offset+uint(q.len))%builtin.len(q.data)
q.data[idx] = elem
q.len += 1
return true
return true, nil
}
// Push an element to the front of the queue
push_front :: proc(q: ^$Q/Queue($T), elem: T) -> bool {
push_front :: proc(q: ^$Q/Queue($T), elem: T) -> (ok: bool, err: runtime.Allocator_Error) {
if space(q^) == 0 {
_grow(q) or_return
}
q.offset = uint(q.offset - 1 + builtin.len(q.data)) % builtin.len(q.data)
q.len += 1
q.data[q.offset] = elem
return true
return true, nil
}
@@ -173,7 +173,7 @@ pop_front_safe :: proc(q: ^$Q/Queue($T)) -> (elem: T, ok: bool) {
}
// Push multiple elements to the front of the queue
push_back_elems :: proc(q: ^$Q/Queue($T), elems: ..T) -> bool {
push_back_elems :: proc(q: ^$Q/Queue($T), elems: ..T) -> (ok: bool, err: runtime.Allocator_Error) {
n := uint(builtin.len(elems))
if space(q^) < int(n) {
_grow(q, q.len + n) or_return
@@ -188,7 +188,7 @@ push_back_elems :: proc(q: ^$Q/Queue($T), elems: ..T) -> bool {
copy(q.data[insert_from:], elems[:insert_to])
copy(q.data[:insert_from], elems[insert_to:])
q.len += n
return true
return true, nil
}
// Consume `n` elements from the front of the queue
@@ -225,7 +225,7 @@ clear :: proc(q: ^$Q/Queue($T)) {
// Internal growinh procedure
_grow :: proc(q: ^$Q/Queue($T), min_capacity: uint = 0) -> bool {
_grow :: proc(q: ^$Q/Queue($T), min_capacity: uint = 0) -> runtime.Allocator_Error {
new_capacity := max(min_capacity, uint(8), uint(builtin.len(q.data))*2)
n := uint(builtin.len(q.data))
builtin.resize(&q.data, int(new_capacity)) or_return
@@ -234,5 +234,5 @@ _grow :: proc(q: ^$Q/Queue($T), min_capacity: uint = 0) -> bool {
copy(q.data[new_capacity-diff:], q.data[q.offset:][:diff])
q.offset += new_capacity - n
}
return true
return nil
}
@@ -32,7 +32,7 @@ init :: proc(sorter: ^$S/Sorter($K)) {
}
destroy :: proc(sorter: ^$S/Sorter($K)) {
for _, v in &sorter.relations {
for _, v in sorter.relations {
delete(v.dependents)
}
delete(sorter.relations)
@@ -80,7 +80,7 @@ sort :: proc(sorter: ^$S/Sorter($K)) -> (sorted, cycled: [dynamic]K) {
}
}
for root in &sorted do for k, _ in relations[root].dependents {
for root in sorted do for k, _ in relations[root].dependents {
relation := &relations[k]
relation.dependencies -= 1
if relation.dependencies == 0 {
+4 -4
View File
@@ -70,7 +70,7 @@ hash_stream_224 :: proc(s: io.Stream) -> ([DIGEST_SIZE_224]byte, bool) {
defer delete(buf)
read := 1
for read > 0 {
read, _ = s->impl_read(buf)
read, _ = io.read(s, buf)
if read > 0 {
update(&ctx, buf[:read])
}
@@ -149,7 +149,7 @@ hash_stream_256 :: proc(s: io.Stream) -> ([DIGEST_SIZE_256]byte, bool) {
defer delete(buf)
read := 1
for read > 0 {
read, _ = s->impl_read(buf)
read, _ = io.read(s, buf)
if read > 0 {
update(&ctx, buf[:read])
}
@@ -228,7 +228,7 @@ hash_stream_384 :: proc(s: io.Stream) -> ([DIGEST_SIZE_384]byte, bool) {
defer delete(buf)
read := 1
for read > 0 {
read, _ = s->impl_read(buf)
read, _ = io.read(s, buf)
if read > 0 {
update(&ctx, buf[:read])
}
@@ -307,7 +307,7 @@ hash_stream_512 :: proc(s: io.Stream) -> ([DIGEST_SIZE_512]byte, bool) {
defer delete(buf)
read := 1
for read > 0 {
read, _ = s->impl_read(buf)
read, _ = io.read(s, buf)
if read > 0 {
update(&ctx, buf[:read])
}
+1 -1
View File
@@ -77,7 +77,7 @@ hash_stream :: proc(s: io.Stream) -> ([DIGEST_SIZE]byte, bool) {
defer delete(buf)
read := 1
for read > 0 {
read, _ = s->impl_read(buf)
read, _ = io.read(s, buf)
if read > 0 {
_blake2.update(&ctx, buf[:read])
}
+1 -1
View File
@@ -77,7 +77,7 @@ hash_stream :: proc(s: io.Stream) -> ([DIGEST_SIZE]byte, bool) {
defer delete(buf)
read := 1
for read > 0 {
read, _ = s->impl_read(buf)
read, _ = io.read(s, buf)
if read > 0 {
_blake2.update(&ctx, buf[:read])
}
+1 -1
View File
@@ -65,7 +65,7 @@ hash_stream :: proc(s: io.Stream) -> ([DIGEST_SIZE]byte, bool) {
defer delete(buf)
read := 1
for read > 0 {
read, _ = s->impl_read(buf)
read, _ = io.read(s, buf)
if read > 0 {
update(&ctx, buf[:read])
}
+4 -4
View File
@@ -70,7 +70,7 @@ hash_stream_224 :: proc(s: io.Stream) -> ([DIGEST_SIZE_224]byte, bool) {
defer delete(buf)
read := 1
for read > 0 {
read, _ = s->impl_read(buf)
read, _ = io.read(s, buf)
if read > 0 {
update(&ctx, buf[:read])
}
@@ -149,7 +149,7 @@ hash_stream_256 :: proc(s: io.Stream) -> ([DIGEST_SIZE_256]byte, bool) {
defer delete(buf)
read := 1
for read > 0 {
read, _ = s->impl_read(buf)
read, _ = io.read(s, buf)
if read > 0 {
update(&ctx, buf[:read])
}
@@ -228,7 +228,7 @@ hash_stream_384 :: proc(s: io.Stream) -> ([DIGEST_SIZE_384]byte, bool) {
defer delete(buf)
read := 1
for read > 0 {
read, _ = s->impl_read(buf)
read, _ = io.read(s, buf)
if read > 0 {
update(&ctx, buf[:read])
}
@@ -307,7 +307,7 @@ hash_stream_512 :: proc(s: io.Stream) -> ([DIGEST_SIZE_512]byte, bool) {
defer delete(buf)
read := 1
for read > 0 {
read, _ = s->impl_read(buf)
read, _ = io.read(s, buf)
if read > 0 {
update(&ctx, buf[:read])
}
+15 -15
View File
@@ -79,7 +79,7 @@ hash_stream_128_3 :: proc(s: io.Stream) -> ([DIGEST_SIZE_128]byte, bool) {
defer delete(buf)
read := 1
for read > 0 {
read, _ = s->impl_read(buf)
read, _ = io.read(s, buf)
ctx.str_len = u32(len(buf[:read]))
if read > 0 {
update(&ctx, buf[:read])
@@ -164,7 +164,7 @@ hash_stream_128_4 :: proc(s: io.Stream) -> ([DIGEST_SIZE_128]byte, bool) {
defer delete(buf)
read := 1
for read > 0 {
read, _ = s->impl_read(buf)
read, _ = io.read(s, buf)
ctx.str_len = u32(len(buf[:read]))
if read > 0 {
update(&ctx, buf[:read])
@@ -249,7 +249,7 @@ hash_stream_128_5 :: proc(s: io.Stream) -> ([DIGEST_SIZE_128]byte, bool) {
defer delete(buf)
read := 1
for read > 0 {
read, _ = s->impl_read(buf)
read, _ = io.read(s, buf)
ctx.str_len = u32(len(buf[:read]))
if read > 0 {
update(&ctx, buf[:read])
@@ -334,7 +334,7 @@ hash_stream_160_3 :: proc(s: io.Stream) -> ([DIGEST_SIZE_160]byte, bool) {
defer delete(buf)
read := 1
for read > 0 {
read, _ = s->impl_read(buf)
read, _ = io.read(s, buf)
ctx.str_len = u32(len(buf[:read]))
if read > 0 {
update(&ctx, buf[:read])
@@ -419,7 +419,7 @@ hash_stream_160_4 :: proc(s: io.Stream) -> ([DIGEST_SIZE_160]byte, bool) {
defer delete(buf)
read := 1
for read > 0 {
read, _ = s->impl_read(buf)
read, _ = io.read(s, buf)
ctx.str_len = u32(len(buf[:read]))
if read > 0 {
update(&ctx, buf[:read])
@@ -504,7 +504,7 @@ hash_stream_160_5 :: proc(s: io.Stream) -> ([DIGEST_SIZE_160]byte, bool) {
defer delete(buf)
read := 1
for read > 0 {
read, _ = s->impl_read(buf)
read, _ = io.read(s, buf)
ctx.str_len = u32(len(buf[:read]))
if read > 0 {
update(&ctx, buf[:read])
@@ -589,7 +589,7 @@ hash_stream_192_3 :: proc(s: io.Stream) -> ([DIGEST_SIZE_192]byte, bool) {
defer delete(buf)
read := 1
for read > 0 {
read, _ = s->impl_read(buf)
read, _ = io.read(s, buf)
ctx.str_len = u32(len(buf[:read]))
if read > 0 {
update(&ctx, buf[:read])
@@ -674,7 +674,7 @@ hash_stream_192_4 :: proc(s: io.Stream) -> ([DIGEST_SIZE_192]byte, bool) {
defer delete(buf)
read := 1
for read > 0 {
read, _ = s->impl_read(buf)
read, _ = io.read(s, buf)
ctx.str_len = u32(len(buf[:read]))
if read > 0 {
update(&ctx, buf[:read])
@@ -759,7 +759,7 @@ hash_stream_192_5 :: proc(s: io.Stream) -> ([DIGEST_SIZE_192]byte, bool) {
defer delete(buf)
read := 1
for read > 0 {
read, _ = s->impl_read(buf)
read, _ = io.read(s, buf)
ctx.str_len = u32(len(buf[:read]))
if read > 0 {
update(&ctx, buf[:read])
@@ -844,7 +844,7 @@ hash_stream_224_3 :: proc(s: io.Stream) -> ([DIGEST_SIZE_224]byte, bool) {
defer delete(buf)
read := 1
for read > 0 {
read, _ = s->impl_read(buf)
read, _ = io.read(s, buf)
ctx.str_len = u32(len(buf[:read]))
if read > 0 {
update(&ctx, buf[:read])
@@ -929,7 +929,7 @@ hash_stream_224_4 :: proc(s: io.Stream) -> ([DIGEST_SIZE_224]byte, bool) {
defer delete(buf)
read := 1
for read > 0 {
read, _ = s->impl_read(buf)
read, _ = io.read(s, buf)
ctx.str_len = u32(len(buf[:read]))
if read > 0 {
update(&ctx, buf[:read])
@@ -1014,7 +1014,7 @@ hash_stream_224_5 :: proc(s: io.Stream) -> ([DIGEST_SIZE_224]byte, bool) {
defer delete(buf)
read := 1
for read > 0 {
read, _ = s->impl_read(buf)
read, _ = io.read(s, buf)
ctx.str_len = u32(len(buf[:read]))
if read > 0 {
update(&ctx, buf[:read])
@@ -1099,7 +1099,7 @@ hash_stream_256_3 :: proc(s: io.Stream) -> ([DIGEST_SIZE_256]byte, bool) {
defer delete(buf)
read := 1
for read > 0 {
read, _ = s->impl_read(buf)
read, _ = io.read(s, buf)
ctx.str_len = u32(len(buf[:read]))
if read > 0 {
update(&ctx, buf[:read])
@@ -1184,7 +1184,7 @@ hash_stream_256_4 :: proc(s: io.Stream) -> ([DIGEST_SIZE_256]byte, bool) {
defer delete(buf)
read := 1
for read > 0 {
read, _ = s->impl_read(buf)
read, _ = io.read(s, buf)
ctx.str_len = u32(len(buf[:read]))
if read > 0 {
update(&ctx, buf[:read])
@@ -1270,7 +1270,7 @@ hash_stream_256_5 :: proc(s: io.Stream) -> ([DIGEST_SIZE_256]byte, bool) {
defer delete(buf)
read := 1
for read > 0 {
read, _ = s->impl_read(buf)
read, _ = io.read(s, buf)
ctx.str_len = u32(len(buf[:read]))
if read > 0 {
update(&ctx, buf[:read])
+4 -4
View File
@@ -70,7 +70,7 @@ hash_stream_224 :: proc(s: io.Stream) -> ([DIGEST_SIZE_224]byte, bool) {
defer delete(buf)
read := 1
for read > 0 {
read, _ = s->impl_read(buf)
read, _ = io.read(s, buf)
if read > 0 {
update(&ctx, buf[:read])
}
@@ -149,7 +149,7 @@ hash_stream_256 :: proc(s: io.Stream) -> ([DIGEST_SIZE_256]byte, bool) {
defer delete(buf)
read := 1
for read > 0 {
read, _ = s->impl_read(buf)
read, _ = io.read(s, buf)
if read > 0 {
update(&ctx, buf[:read])
}
@@ -228,7 +228,7 @@ hash_stream_384 :: proc(s: io.Stream) -> ([DIGEST_SIZE_384]byte, bool) {
defer delete(buf)
read := 1
for read > 0 {
read, _ = s->impl_read(buf)
read, _ = io.read(s, buf)
if read > 0 {
update(&ctx, buf[:read])
}
@@ -307,7 +307,7 @@ hash_stream_512 :: proc(s: io.Stream) -> ([DIGEST_SIZE_512]byte, bool) {
defer delete(buf)
read := 1
for read > 0 {
read, _ = s->impl_read(buf)
read, _ = io.read(s, buf)
if read > 0 {
update(&ctx, buf[:read])
}
+4 -4
View File
@@ -77,7 +77,7 @@ hash_stream_224 :: proc(s: io.Stream) -> ([DIGEST_SIZE_224]byte, bool) {
defer delete(buf)
read := 1
for read > 0 {
read, _ = s->impl_read(buf)
read, _ = io.read(s, buf)
if read > 0 {
_sha3.update(&ctx, buf[:read])
}
@@ -159,7 +159,7 @@ hash_stream_256 :: proc(s: io.Stream) -> ([DIGEST_SIZE_256]byte, bool) {
defer delete(buf)
read := 1
for read > 0 {
read, _ = s->impl_read(buf)
read, _ = io.read(s, buf)
if read > 0 {
_sha3.update(&ctx, buf[:read])
}
@@ -241,7 +241,7 @@ hash_stream_384 :: proc(s: io.Stream) -> ([DIGEST_SIZE_384]byte, bool) {
defer delete(buf)
read := 1
for read > 0 {
read, _ = s->impl_read(buf)
read, _ = io.read(s, buf)
if read > 0 {
_sha3.update(&ctx, buf[:read])
}
@@ -323,7 +323,7 @@ hash_stream_512 :: proc(s: io.Stream) -> ([DIGEST_SIZE_512]byte, bool) {
defer delete(buf)
read := 1
for read > 0 {
read, _ = s->impl_read(buf)
read, _ = io.read(s, buf)
if read > 0 {
_sha3.update(&ctx, buf[:read])
}
+1 -1
View File
@@ -64,7 +64,7 @@ hash_stream :: proc(s: io.Stream) -> ([DIGEST_SIZE]byte, bool) {
defer delete(buf)
read := 1
for read > 0 {
read, _ = s->impl_read(buf)
read, _ = io.read(s, buf)
if read > 0 {
update(&ctx, buf[:read])
}
+1 -1
View File
@@ -68,7 +68,7 @@ hash_stream :: proc(s: io.Stream) -> ([DIGEST_SIZE]byte, bool) {
defer delete(buf)
read := 1
for read > 0 {
read, _ = s->impl_read(buf)
read, _ = io.read(s, buf)
if read > 0 {
update(&ctx, buf[:read])
}
+1 -1
View File
@@ -67,7 +67,7 @@ hash_stream :: proc(s: io.Stream) -> ([DIGEST_SIZE]byte, bool) {
defer delete(buf)
read := 1
for read > 0 {
read, _ = s->impl_read(buf)
read, _ = io.read(s, buf)
if read > 0 {
update(&ctx, buf[:read])
}
+4 -4
View File
@@ -69,7 +69,7 @@ hash_stream_128 :: proc(s: io.Stream) -> ([DIGEST_SIZE_128]byte, bool) {
defer delete(buf)
read := 1
for read > 0 {
read, _ = s->impl_read(buf)
read, _ = io.read(s, buf)
if read > 0 {
update(&ctx, buf[:read])
}
@@ -145,7 +145,7 @@ hash_stream_160 :: proc(s: io.Stream) -> ([DIGEST_SIZE_160]byte, bool) {
defer delete(buf)
read := 1
for read > 0 {
read, _ = s->impl_read(buf)
read, _ = io.read(s, buf)
if read > 0 {
update(&ctx, buf[:read])
}
@@ -221,7 +221,7 @@ hash_stream_256 :: proc(s: io.Stream) -> ([DIGEST_SIZE_256]byte, bool) {
defer delete(buf)
read := 1
for read > 0 {
read, _ = s->impl_read(buf)
read, _ = io.read(s, buf)
if read > 0 {
update(&ctx, buf[:read])
}
@@ -297,7 +297,7 @@ hash_stream_320 :: proc(s: io.Stream) -> ([DIGEST_SIZE_320]byte, bool) {
defer delete(buf)
read := 1
for read > 0 {
read, _ = s->impl_read(buf)
read, _ = io.read(s, buf)
if read > 0 {
update(&ctx, buf[:read])
}
+1 -1
View File
@@ -67,7 +67,7 @@ hash_stream :: proc(s: io.Stream) -> ([DIGEST_SIZE]byte, bool) {
defer delete(buf)
read := 1
for read > 0 {
read, _ = s->impl_read(buf)
read, _ = io.read(s, buf)
if read > 0 {
update(&ctx, buf[:read])
}
+4 -4
View File
@@ -74,7 +74,7 @@ hash_stream_224 :: proc(s: io.Stream) -> ([DIGEST_SIZE_224]byte, bool) {
defer delete(buf)
read := 1
for read > 0 {
read, _ = s->impl_read(buf)
read, _ = io.read(s, buf)
if read > 0 {
update(&ctx, buf[:read])
}
@@ -153,7 +153,7 @@ hash_stream_256 :: proc(s: io.Stream) -> ([DIGEST_SIZE_256]byte, bool) {
defer delete(buf)
read := 1
for read > 0 {
read, _ = s->impl_read(buf)
read, _ = io.read(s, buf)
if read > 0 {
update(&ctx, buf[:read])
}
@@ -232,7 +232,7 @@ hash_stream_384 :: proc(s: io.Stream) -> ([DIGEST_SIZE_384]byte, bool) {
defer delete(buf)
read := 1
for read > 0 {
read, _ = s->impl_read(buf)
read, _ = io.read(s, buf)
if read > 0 {
update(&ctx, buf[:read])
}
@@ -311,7 +311,7 @@ hash_stream_512 :: proc(s: io.Stream) -> ([DIGEST_SIZE_512]byte, bool) {
defer delete(buf)
read := 1
for read > 0 {
read, _ = s->impl_read(buf)
read, _ = io.read(s, buf)
if read > 0 {
update(&ctx, buf[:read])
}
+4 -4
View File
@@ -73,7 +73,7 @@ hash_stream_224 :: proc(s: io.Stream) -> ([DIGEST_SIZE_224]byte, bool) {
defer delete(buf)
read := 1
for read > 0 {
read, _ = s->impl_read(buf)
read, _ = io.read(s, buf)
if read > 0 {
_sha3.update(&ctx, buf[:read])
}
@@ -152,7 +152,7 @@ hash_stream_256 :: proc(s: io.Stream) -> ([DIGEST_SIZE_256]byte, bool) {
defer delete(buf)
read := 1
for read > 0 {
read, _ = s->impl_read(buf)
read, _ = io.read(s, buf)
if read > 0 {
_sha3.update(&ctx, buf[:read])
}
@@ -231,7 +231,7 @@ hash_stream_384 :: proc(s: io.Stream) -> ([DIGEST_SIZE_384]byte, bool) {
defer delete(buf)
read := 1
for read > 0 {
read, _ = s->impl_read(buf)
read, _ = io.read(s, buf)
if read > 0 {
_sha3.update(&ctx, buf[:read])
}
@@ -310,7 +310,7 @@ hash_stream_512 :: proc(s: io.Stream) -> ([DIGEST_SIZE_512]byte, bool) {
defer delete(buf)
read := 1
for read > 0 {
read, _ = s->impl_read(buf)
read, _ = io.read(s, buf)
if read > 0 {
_sha3.update(&ctx, buf[:read])
}
+2 -2
View File
@@ -73,7 +73,7 @@ hash_stream_128 :: proc(s: io.Stream) -> ([DIGEST_SIZE_128]byte, bool) {
defer delete(buf)
read := 1
for read > 0 {
read, _ = s->impl_read(buf)
read, _ = io.read(s, buf)
if read > 0 {
_sha3.update(&ctx, buf[:read])
}
@@ -155,7 +155,7 @@ hash_stream_256 :: proc(s: io.Stream) -> ([DIGEST_SIZE_256]byte, bool) {
defer delete(buf)
read := 1
for read > 0 {
read, _ = s->impl_read(buf)
read, _ = io.read(s, buf)
if read > 0 {
_sha3.update(&ctx, buf[:read])
}
+1 -1
View File
@@ -66,7 +66,7 @@ hash_stream :: proc(s: io.Stream) -> ([DIGEST_SIZE]byte, bool) {
defer delete(buf)
read := 1
for read > 0 {
read, _ = s->impl_read(buf)
read, _ = io.read(s, buf)
if read > 0 {
update(&ctx, buf[:read])
}
+2 -2
View File
@@ -70,7 +70,7 @@ hash_stream_256 :: proc(s: io.Stream) -> ([DIGEST_SIZE_256]byte, bool) {
defer delete(buf)
read := 1
for read > 0 {
read, _ = s->impl_read(buf)
read, _ = io.read(s, buf)
if read > 0 {
update(&ctx, buf[:read])
}
@@ -146,7 +146,7 @@ hash_stream_512 :: proc(s: io.Stream) -> ([DIGEST_SIZE_512]byte, bool) {
defer delete(buf)
read := 1
for read > 0 {
read, _ = s->impl_read(buf)
read, _ = io.read(s, buf)
if read > 0 {
update(&ctx, buf[:read])
}
+3 -3
View File
@@ -71,7 +71,7 @@ hash_stream_128 :: proc(s: io.Stream) -> ([DIGEST_SIZE_128]byte, bool) {
defer delete(buf)
read := 1
for read > 0 {
read, _ = s->impl_read(buf)
read, _ = io.read(s, buf)
if read > 0 {
_tiger.update(&ctx, buf[:read])
}
@@ -150,7 +150,7 @@ hash_stream_160 :: proc(s: io.Stream) -> ([DIGEST_SIZE_160]byte, bool) {
defer delete(buf)
read := 1
for read > 0 {
read, _ = s->impl_read(buf)
read, _ = io.read(s, buf)
if read > 0 {
_tiger.update(&ctx, buf[:read])
}
@@ -229,7 +229,7 @@ hash_stream_192 :: proc(s: io.Stream) -> ([DIGEST_SIZE_192]byte, bool) {
defer delete(buf)
read := 1
for read > 0 {
read, _ = s->impl_read(buf)
read, _ = io.read(s, buf)
if read > 0 {
_tiger.update(&ctx, buf[:read])
}
+3 -3
View File
@@ -71,7 +71,7 @@ hash_stream_128 :: proc(s: io.Stream) -> ([DIGEST_SIZE_128]byte, bool) {
defer delete(buf)
read := 1
for read > 0 {
read, _ = s->impl_read(buf)
read, _ = io.read(s, buf)
if read > 0 {
_tiger.update(&ctx, buf[:read])
}
@@ -150,7 +150,7 @@ hash_stream_160 :: proc(s: io.Stream) -> ([DIGEST_SIZE_160]byte, bool) {
defer delete(buf)
read := 1
for read > 0 {
read, _ = s->impl_read(buf)
read, _ = io.read(s, buf)
if read > 0 {
_tiger.update(&ctx, buf[:read])
}
@@ -229,7 +229,7 @@ hash_stream_192 :: proc(s: io.Stream) -> ([DIGEST_SIZE_192]byte, bool) {
defer delete(buf)
read := 1
for read > 0 {
read, _ = s->impl_read(buf)
read, _ = io.read(s, buf)
if read > 0 {
_tiger.update(&ctx, buf[:read])
}
+1 -1
View File
@@ -66,7 +66,7 @@ hash_stream :: proc(s: io.Stream) -> ([DIGEST_SIZE]byte, bool) {
defer delete(buf)
read := 1
for read > 0 {
read, _ = s->impl_read(buf)
read, _ = io.read(s, buf)
if read > 0 {
update(&ctx, buf[:read])
}
-3
View File
@@ -1,8 +1,5 @@
package debug_pe
import "core:runtime"
import "core:io"
Section_Header32 :: struct {
name: [8]u8,
virtual_size: u32le,
+3 -3
View File
@@ -3,13 +3,13 @@
package dynlib
_load_library :: proc(path: string, global_symbols := false) -> (Library, bool) {
return
return nil, false
}
_unload_library :: proc(library: Library) -> bool {
return
return false
}
_symbol_address :: proc(library: Library, symbol: string) -> (ptr: rawptr, found: bool) {
return
return nil, false
}
+17 -20
View File
@@ -184,28 +184,26 @@ decode_xml :: proc(input: string, options := XML_Decode_Options{}, allocator :=
advance :: proc(t: ^Tokenizer) -> (err: Error) {
if t == nil { return .Tokenizer_Is_Nil }
using t
#no_bounds_check {
if read_offset < len(src) {
offset = read_offset
r, w = rune(src[read_offset]), 1
if t.read_offset < len(t.src) {
t.offset = t.read_offset
t.r, t.w = rune(t.src[t.read_offset]), 1
switch {
case r == 0:
case t.r == 0:
return .Illegal_NUL_Character
case r >= utf8.RUNE_SELF:
r, w = utf8.decode_rune_in_string(src[read_offset:])
if r == utf8.RUNE_ERROR && w == 1 {
case t.r >= utf8.RUNE_SELF:
t.r, t.w = utf8.decode_rune_in_string(t.src[t.read_offset:])
if t.r == utf8.RUNE_ERROR && t.w == 1 {
return .Illegal_UTF_Encoding
} else if r == utf8.RUNE_BOM && offset > 0 {
} else if t.r == utf8.RUNE_BOM && t.offset > 0 {
return .Illegal_BOM
}
}
read_offset += w
t.read_offset += t.w
return .None
} else {
offset = len(src)
r = -1
t.offset = len(t.src)
t.r = -1
return
}
}
@@ -273,26 +271,25 @@ _extract_xml_entity :: proc(t: ^Tokenizer) -> (entity: string, err: Error) {
All of these would be in the ASCII range.
Even if one is not, it doesn't matter. All characters we need to compare to extract are.
*/
using t
length := len(t.src)
found := false
#no_bounds_check {
for read_offset < length {
if src[read_offset] == ';' {
for t.read_offset < length {
if t.src[t.read_offset] == ';' {
t.read_offset += 1
found = true
read_offset += 1
break
}
read_offset += 1
t.read_offset += 1
}
}
if found {
return string(src[offset + 1 : read_offset - 1]), .None
return string(t.src[t.offset + 1 : t.read_offset - 1]), .None
}
return string(src[offset : read_offset]), .Invalid_Entity_Encoding
return string(t.src[t.offset : t.read_offset]), .Invalid_Entity_Encoding
}
/*
+73
View File
@@ -0,0 +1,73 @@
package hex
import "core:strings"
encode :: proc(src: []byte, allocator := context.allocator) -> []byte #no_bounds_check {
dst := make([]byte, len(src) * 2, allocator)
for i, j := 0, 0; i < len(src); i += 1 {
v := src[i]
dst[j] = HEXTABLE[v>>4]
dst[j+1] = HEXTABLE[v&0x0f]
j += 2
}
return dst
}
decode :: proc(src: []byte, allocator := context.allocator) -> (dst: []byte, ok: bool) #no_bounds_check {
if len(src) % 2 == 1 {
return
}
dst = make([]byte, len(src) / 2, allocator)
for i, j := 0, 1; j < len(src); j += 2 {
p := src[j-1]
q := src[j]
a := hex_digit(p) or_return
b := hex_digit(q) or_return
dst[i] = (a << 4) | b
i += 1
}
return dst, true
}
// Decodes the given sequence into one byte.
// Should be called with one byte worth of the source, eg: 0x23 -> '#'.
decode_sequence :: proc(str: string) -> (res: byte, ok: bool) {
str := str
if strings.has_prefix(str, "0x") || strings.has_prefix(str, "0X") {
str = str[2:]
}
if len(str) != 2 {
return 0, false
}
upper := hex_digit(str[0]) or_return
lower := hex_digit(str[1]) or_return
return upper << 4 | lower, true
}
@(private)
HEXTABLE := [16]byte {
'0', '1', '2', '3',
'4', '5', '6', '7',
'8', '9', 'a', 'b',
'c', 'd', 'e', 'f',
}
@(private)
hex_digit :: proc(char: byte) -> (u8, bool) {
switch char {
case '0' ..= '9': return char - '0', true
case 'a' ..= 'f': return char - 'a' + 10, true
case 'A' ..= 'F': return char - 'A' + 10, true
case: return 0, false
}
}
+2 -2
View File
@@ -83,7 +83,7 @@ read :: proc(data: []byte, filename := "<input>", print_error := false, allocato
meta_data = make([]Meta, int(capacity))
count := 0
defer meta_data = meta_data[:count]
for m in &meta_data {
for &m in meta_data {
m.name = read_name(r) or_return
type := read_value(r, Meta_Value_Type) or_return
@@ -116,7 +116,7 @@ read :: proc(data: []byte, filename := "<input>", print_error := false, allocato
layer_count := 0
layers = make(Layer_Stack, stack_count)
defer layers = layers[:layer_count]
for layer in &layers {
for &layer in layers {
layer.name = read_name(r) or_return
layer.components = read_value(r, u8) or_return
type := read_value(r, Layer_Data_Type) or_return
+3 -3
View File
@@ -153,7 +153,7 @@ marshal_to_writer :: proc(w: io.Writer, v: any, opt: ^Marshal_Options) -> (err:
case complex128: r, i = f64(real(z)), f64(imag(z))
case: return .Unsupported_Type
}
io.write_byte(w, '[') or_return
io.write_f64(w, r) or_return
io.write_string(w, ", ") or_return
@@ -165,8 +165,8 @@ marshal_to_writer :: proc(w: io.Writer, v: any, opt: ^Marshal_Options) -> (err:
case runtime.Type_Info_String:
switch s in a {
case string: io.write_quoted_string(w, s) or_return
case cstring: io.write_quoted_string(w, string(s)) or_return
case string: io.write_quoted_string(w, s, '"', nil, true) or_return
case cstring: io.write_quoted_string(w, string(s), '"', nil, true) or_return
}
case runtime.Type_Info_Boolean:
+10 -1
View File
@@ -2,6 +2,7 @@ package json
import "core:mem"
import "core:unicode/utf8"
import "core:unicode/utf16"
import "core:strconv"
Parser :: struct {
@@ -403,11 +404,19 @@ unquote_string :: proc(token: Token, spec: Specification, allocator := context.a
}
i += 6
// If this is a surrogate pair, decode as such by taking the next rune too.
if r >= utf8.SURROGATE_MIN && r <= utf8.SURROGATE_HIGH_MAX && len(s) > i + 2 && s[i:i+2] == "\\u" {
r2 := get_u4_rune(s[i:])
if r2 >= utf8.SURROGATE_LOW_MIN && r2 <= utf8.SURROGATE_MAX {
i += 6
r = utf16.decode_surrogate_pair(r, r2)
}
}
buf, buf_width := utf8.encode_rune(r)
copy(b[w:], buf[:buf_width])
w += buf_width
case '0':
if spec != .JSON {
b[w] = '\x00'
+5 -5
View File
@@ -72,7 +72,7 @@ unmarshal_string :: proc(data: string, ptr: ^$T, spec := DEFAULT_SPECIFICATION,
@(private)
assign_bool :: proc(val: any, b: bool) -> bool {
v := reflect.any_core(val)
switch dst in &v {
switch &dst in v {
case bool: dst = bool(b)
case b8: dst = b8 (b)
case b16: dst = b16 (b)
@@ -85,7 +85,7 @@ assign_bool :: proc(val: any, b: bool) -> bool {
@(private)
assign_int :: proc(val: any, i: $T) -> bool {
v := reflect.any_core(val)
switch dst in &v {
switch &dst in v {
case i8: dst = i8 (i)
case i16: dst = i16 (i)
case i16le: dst = i16le (i)
@@ -122,7 +122,7 @@ assign_int :: proc(val: any, i: $T) -> bool {
@(private)
assign_float :: proc(val: any, f: $T) -> bool {
v := reflect.any_core(val)
switch dst in &v {
switch &dst in v {
case f16: dst = f16 (f)
case f16le: dst = f16le(f)
case f16be: dst = f16be(f)
@@ -150,7 +150,7 @@ assign_float :: proc(val: any, f: $T) -> bool {
@(private)
unmarshal_string_token :: proc(p: ^Parser, val: any, str: string, ti: ^reflect.Type_Info) -> bool {
val := val
switch dst in &val {
switch &dst in val {
case string:
dst = str
return true
@@ -215,7 +215,7 @@ unmarshal_value :: proc(p: ^Parser, v: any) -> (err: Unmarshal_Error) {
}
}
switch dst in &v {
switch &dst in v {
// Handle json.Value as an unknown type
case Value:
dst = parse_value(p) or_return
+21 -23
View File
@@ -19,43 +19,39 @@ import "core:fmt"
*/
print :: proc(writer: io.Writer, doc: ^Document) -> (written: int, err: io.Error) {
if doc == nil { return }
using fmt
written += wprintf(writer, "[XML Prolog]\n")
written += fmt.wprintf(writer, "[XML Prolog]\n")
for attr in doc.prologue {
written += wprintf(writer, "\t%v: %v\n", attr.key, attr.val)
written += fmt.wprintf(writer, "\t%v: %v\n", attr.key, attr.val)
}
written += wprintf(writer, "[Encoding] %v\n", doc.encoding)
written += fmt.wprintf(writer, "[Encoding] %v\n", doc.encoding)
if len(doc.doctype.ident) > 0 {
written += wprintf(writer, "[DOCTYPE] %v\n", doc.doctype.ident)
written += fmt.wprintf(writer, "[DOCTYPE] %v\n", doc.doctype.ident)
if len(doc.doctype.rest) > 0 {
wprintf(writer, "\t%v\n", doc.doctype.rest)
fmt.wprintf(writer, "\t%v\n", doc.doctype.rest)
}
}
for comment in doc.comments {
written += wprintf(writer, "[Pre-root comment] %v\n", comment)
written += fmt.wprintf(writer, "[Pre-root comment] %v\n", comment)
}
if len(doc.elements) > 0 {
wprintln(writer, " --- ")
fmt.wprintln(writer, " --- ")
print_element(writer, doc, 0)
wprintln(writer, " --- ")
fmt.wprintln(writer, " --- ")
}
return written, .None
}
print_element :: proc(writer: io.Writer, doc: ^Document, element_id: Element_ID, indent := 0) -> (written: int, err: io.Error) {
using fmt
tab :: proc(writer: io.Writer, indent: int) {
for _ in 0..=indent {
wprintf(writer, "\t")
fmt.wprintf(writer, "\t")
}
}
@@ -64,22 +60,24 @@ print_element :: proc(writer: io.Writer, doc: ^Document, element_id: Element_ID,
element := doc.elements[element_id]
if element.kind == .Element {
wprintf(writer, "<%v>\n", element.ident)
if len(element.value) > 0 {
tab(writer, indent + 1)
wprintf(writer, "[Value] %v\n", element.value)
fmt.wprintf(writer, "<%v>\n", element.ident)
for value in element.value {
switch v in value {
case string:
tab(writer, indent + 1)
fmt.wprintf(writer, "[Value] %v\n", v)
case Element_ID:
print_element(writer, doc, v, indent + 1)
}
}
for attr in element.attribs {
tab(writer, indent + 1)
wprintf(writer, "[Attr] %v: %v\n", attr.key, attr.val)
}
for child in element.children {
print_element(writer, doc, child, indent + 1)
fmt.wprintf(writer, "[Attr] %v: %v\n", attr.key, attr.val)
}
} else if element.kind == .Comment {
wprintf(writer, "[COMMENT] %v\n", element.value)
fmt.wprintf(writer, "[COMMENT] %v\n", element.value)
}
return written, .None
+3 -3
View File
@@ -72,10 +72,10 @@ example :: proc() {
return
}
printf("Found `<charlist>` with %v children, %v elements total\n", len(docs[0].elements[charlist].children), docs[0].element_count)
printf("Found `<charlist>` with %v children, %v elements total\n", len(docs[0].elements[charlist].value), docs[0].element_count)
crc32 := doc_hash(docs[0])
printf("[%v] CRC32: 0x%08x\n", "🎉" if crc32 == 0xcaa042b9 else "🤬", crc32)
crc32 := doc_hash(docs[0], false)
printf("[%v] CRC32: 0x%08x\n", "🎉" if crc32 == 0x420dbac5 else "🤬", crc32)
for round in 0..<N {
defer xml.destroy(docs[round])
+17 -12
View File
@@ -13,20 +13,25 @@ find_child_by_ident :: proc(doc: ^Document, parent_id: Element_ID, ident: string
tag := doc.elements[parent_id]
count := 0
for child_id in tag.children {
child := doc.elements[child_id]
/*
Skip commments. They have no name.
*/
if child.kind != .Element { continue }
for v in tag.value {
switch child_id in v {
case string: continue
case Element_ID:
child := doc.elements[child_id]
/*
Skip commments. They have no name.
*/
if child.kind != .Element { continue }
/*
If the ident matches and it's the nth such child, return it.
*/
if child.ident == ident {
if count == nth { return child_id, true }
count += 1
/*
If the ident matches and it's the nth such child, return it.
*/
if child.ident == ident {
if count == nth { return child_id, true }
count += 1
}
}
}
return 0, false
}
+16 -16
View File
@@ -125,38 +125,38 @@ error :: proc(t: ^Tokenizer, offset: int, msg: string, args: ..any) {
}
@(optimization_mode="speed")
advance_rune :: proc(using t: ^Tokenizer) {
advance_rune :: proc(t: ^Tokenizer) {
#no_bounds_check {
/*
Already bounds-checked here.
*/
if read_offset < len(src) {
offset = read_offset
if ch == '\n' {
line_offset = offset
line_count += 1
if t.read_offset < len(t.src) {
t.offset = t.read_offset
if t.ch == '\n' {
t.line_offset = t.offset
t.line_count += 1
}
r, w := rune(src[read_offset]), 1
r, w := rune(t.src[t.read_offset]), 1
switch {
case r == 0:
error(t, t.offset, "illegal character NUL")
case r >= utf8.RUNE_SELF:
r, w = #force_inline utf8.decode_rune_in_string(src[read_offset:])
r, w = #force_inline utf8.decode_rune_in_string(t.src[t.read_offset:])
if r == utf8.RUNE_ERROR && w == 1 {
error(t, t.offset, "illegal UTF-8 encoding")
} else if r == utf8.RUNE_BOM && offset > 0 {
} else if r == utf8.RUNE_BOM && t.offset > 0 {
error(t, t.offset, "illegal byte order mark")
}
}
read_offset += w
ch = r
t.read_offset += w
t.ch = r
} else {
offset = len(src)
if ch == '\n' {
line_offset = offset
line_count += 1
t.offset = len(t.src)
if t.ch == '\n' {
t.line_offset = t.offset
t.line_count += 1
}
ch = -1
t.ch = -1
}
}
}
+15 -27
View File
@@ -125,16 +125,19 @@ Document :: struct {
Element :: struct {
ident: string,
value: string,
value: [dynamic]Value,
attribs: Attributes,
kind: enum {
Element = 0,
Comment,
},
parent: Element_ID,
children: [dynamic]Element_ID,
}
Value :: union {
string,
Element_ID,
}
Attribute :: struct {
@@ -247,9 +250,6 @@ parse_bytes :: proc(data: []u8, options := DEFAULT_OPTIONS, path := "", error_ha
err = .Unexpected_Token
element, parent: Element_ID
tag_is_open := false
first_element := true
open: Token
/*
@@ -275,16 +275,10 @@ parse_bytes :: proc(data: []u8, options := DEFAULT_OPTIONS, path := "", error_ha
e.g. <odin - Start of new element.
*/
element = new_element(doc)
tag_is_open = true
if first_element {
/*
First element.
*/
parent = element
first_element = false
if element == 0 { // First Element
parent = element
} else {
append(&doc.elements[parent].children, element)
append(&doc.elements[parent].value, element)
}
doc.elements[element].parent = parent
@@ -324,7 +318,6 @@ parse_bytes :: proc(data: []u8, options := DEFAULT_OPTIONS, path := "", error_ha
expect(t, .Gt) or_return
parent = doc.elements[element].parent
element = parent
tag_is_open = false
case:
error(t, t.offset, "Expected close tag, got: %#v\n", end_token)
@@ -344,7 +337,6 @@ parse_bytes :: proc(data: []u8, options := DEFAULT_OPTIONS, path := "", error_ha
}
parent = doc.elements[element].parent
element = parent
tag_is_open = false
} else if open.kind == .Exclaim {
/*
@@ -392,8 +384,8 @@ parse_bytes :: proc(data: []u8, options := DEFAULT_OPTIONS, path := "", error_ha
el := new_element(doc)
doc.elements[el].parent = element
doc.elements[el].kind = .Comment
doc.elements[el].value = comment
append(&doc.elements[element].children, el)
append(&doc.elements[el].value, comment)
append(&doc.elements[element].value, el)
}
}
@@ -436,9 +428,6 @@ parse_bytes :: proc(data: []u8, options := DEFAULT_OPTIONS, path := "", error_ha
/*
End of file.
*/
if tag_is_open {
return doc, .Premature_EOF
}
break loop
case:
@@ -450,7 +439,7 @@ parse_bytes :: proc(data: []u8, options := DEFAULT_OPTIONS, path := "", error_ha
needs_processing |= .Decode_SGML_Entities in opts.flags
if !needs_processing {
doc.elements[element].value = body_text
append(&doc.elements[element].value, body_text)
continue
}
@@ -472,10 +461,10 @@ parse_bytes :: proc(data: []u8, options := DEFAULT_OPTIONS, path := "", error_ha
decoded, decode_err := entity.decode_xml(body_text, decode_opts)
if decode_err == .None {
doc.elements[element].value = decoded
append(&doc.elements[element].value, decoded)
append(&doc.strings_to_free, decoded)
} else {
doc.elements[element].value = body_text
append(&doc.elements[element].value, body_text)
}
}
}
@@ -518,7 +507,7 @@ destroy :: proc(doc: ^Document) {
for el in doc.elements {
delete(el.attribs)
delete(el.children)
delete(el.value)
}
delete(doc.elements)
@@ -710,6 +699,5 @@ new_element :: proc(doc: ^Document) -> (id: Element_ID) {
cur := doc.element_count
doc.element_count += 1
return cur
}
+45 -37
View File
@@ -123,7 +123,7 @@ register_user_formatter :: proc(id: typeid, formatter: User_Formatter) -> Regist
aprint :: proc(args: ..any, sep := " ") -> string {
str: strings.Builder
strings.builder_init(&str)
sbprint(buf=&str, args=args, sep=sep)
sbprint(&str, ..args, sep=sep)
return strings.to_string(str)
}
// Creates a formatted string with a newline character at the end
@@ -139,7 +139,7 @@ aprint :: proc(args: ..any, sep := " ") -> string {
aprintln :: proc(args: ..any, sep := " ") -> string {
str: strings.Builder
strings.builder_init(&str)
sbprintln(buf=&str, args=args, sep=sep)
sbprintln(&str, ..args, sep=sep)
return strings.to_string(str)
}
// Creates a formatted string using a format string and arguments
@@ -171,7 +171,7 @@ aprintf :: proc(fmt: string, args: ..any) -> string {
tprint :: proc(args: ..any, sep := " ") -> string {
str: strings.Builder
strings.builder_init(&str, context.temp_allocator)
sbprint(buf=&str, args=args, sep=sep)
sbprint(&str, ..args, sep=sep)
return strings.to_string(str)
}
// Creates a formatted string with a newline character at the end
@@ -187,7 +187,7 @@ tprint :: proc(args: ..any, sep := " ") -> string {
tprintln :: proc(args: ..any, sep := " ") -> string {
str: strings.Builder
strings.builder_init(&str, context.temp_allocator)
sbprintln(buf=&str, args=args, sep=sep)
sbprintln(&str, ..args, sep=sep)
return strings.to_string(str)
}
// Creates a formatted string using a format string and arguments
@@ -217,7 +217,7 @@ tprintf :: proc(fmt: string, args: ..any) -> string {
//
bprint :: proc(buf: []byte, args: ..any, sep := " ") -> string {
sb := strings.builder_from_bytes(buf[0:len(buf)])
return sbprint(buf=&sb, args=args, sep=sep)
return sbprint(&sb, ..args, sep=sep)
}
// Creates a formatted string using a supplied buffer as the backing array, appends newline. Writes into the buffer.
//
@@ -230,7 +230,7 @@ bprint :: proc(buf: []byte, args: ..any, sep := " ") -> string {
//
bprintln :: proc(buf: []byte, args: ..any, sep := " ") -> string {
sb := strings.builder_from_bytes(buf[0:len(buf)])
return sbprintln(buf=&sb, args=args, sep=sep)
return sbprintln(&sb, ..args, sep=sep)
}
// Creates a formatted string using a supplied buffer as the backing array. Writes into the buffer.
//
@@ -327,7 +327,7 @@ ctprintf :: proc(format: string, args: ..any) -> cstring {
// Returns: A formatted string
//
sbprint :: proc(buf: ^strings.Builder, args: ..any, sep := " ") -> string {
wprint(w=strings.to_writer(buf), args=args, sep=sep)
wprint(strings.to_writer(buf), ..args, sep=sep)
return strings.to_string(buf^)
}
// Formats and writes to a strings.Builder buffer using the default print settings
@@ -340,7 +340,7 @@ sbprint :: proc(buf: ^strings.Builder, args: ..any, sep := " ") -> string {
// Returns: The resulting formatted string
//
sbprintln :: proc(buf: ^strings.Builder, args: ..any, sep := " ") -> string {
wprintln(w=strings.to_writer(buf), args=args, sep=sep)
wprintln(strings.to_writer(buf), ..args, sep=sep)
return strings.to_string(buf^)
}
// Formats and writes to a strings.Builder buffer according to the specified format string
@@ -353,7 +353,7 @@ sbprintln :: proc(buf: ^strings.Builder, args: ..any, sep := " ") -> string {
// Returns: The resulting formatted string
//
sbprintf :: proc(buf: ^strings.Builder, fmt: string, args: ..any) -> string {
wprintf(w=strings.to_writer(buf), fmt=fmt, args=args)
wprintf(strings.to_writer(buf), fmt, ..args)
return strings.to_string(buf^)
}
// Formats and writes to an io.Writer using the default print settings
@@ -835,22 +835,22 @@ int_from_arg :: proc(args: []any, arg_index: int) -> (int, int, bool) {
// - fi: A pointer to an Info structure
// - verb: The invalid format verb
//
fmt_bad_verb :: proc(using fi: ^Info, verb: rune) {
fmt_bad_verb :: proc(fi: ^Info, verb: rune) {
prev_in_bad := fi.in_bad
defer fi.in_bad = prev_in_bad
fi.in_bad = true
io.write_string(writer, "%!", &fi.n)
io.write_rune(writer, verb, &fi.n)
io.write_byte(writer, '(', &fi.n)
if arg.id != nil {
reflect.write_typeid(writer, arg.id, &fi.n)
io.write_byte(writer, '=', &fi.n)
fmt_value(fi, arg, 'v')
io.write_string(fi.writer, "%!", &fi.n)
io.write_rune(fi.writer, verb, &fi.n)
io.write_byte(fi.writer, '(', &fi.n)
if fi.arg.id != nil {
reflect.write_typeid(fi.writer, fi.arg.id, &fi.n)
io.write_byte(fi.writer, '=', &fi.n)
fmt_value(fi, fi.arg, 'v')
} else {
io.write_string(writer, "<nil>", &fi.n)
io.write_string(fi.writer, "<nil>", &fi.n)
}
io.write_byte(writer, ')', &fi.n)
io.write_byte(fi.writer, ')', &fi.n)
}
// Formats a boolean value according to the specified format verb
//
@@ -859,7 +859,7 @@ fmt_bad_verb :: proc(using fi: ^Info, verb: rune) {
// - b: The boolean value to format
// - verb: The format verb
//
fmt_bool :: proc(using fi: ^Info, b: bool, verb: rune) {
fmt_bool :: proc(fi: ^Info, b: bool, verb: rune) {
switch verb {
case 't', 'v':
fmt_string(fi, b ? "true" : "false", 's')
@@ -1142,6 +1142,11 @@ _pad :: proc(fi: ^Info, s: string) {
if fi.minus { // right pad
io.write_string(fi.writer, s, &fi.n)
fmt_write_padding(fi, width)
} else if !fi.space && s != "" && s[0] == '-' {
// left pad accounting for zero pad of negative number
io.write_byte(fi.writer, '-', &fi.n)
fmt_write_padding(fi, width)
io.write_string(fi.writer, s[1:], &fi.n)
} else { // left pad
fmt_write_padding(fi, width)
io.write_string(fi.writer, s, &fi.n)
@@ -1961,11 +1966,22 @@ fmt_named :: proc(fi: ^Info, v: any, verb: rune, info: runtime.Type_Info_Named)
switch a in v {
case runtime.Source_Code_Location:
io.write_string(fi.writer, a.file_path, &fi.n)
io.write_byte(fi.writer, '(', &fi.n)
io.write_int(fi.writer, int(a.line), 10, &fi.n)
io.write_byte(fi.writer, ':', &fi.n)
io.write_int(fi.writer, int(a.column), 10, &fi.n)
io.write_byte(fi.writer, ')', &fi.n)
when ODIN_ERROR_POS_STYLE == .Default {
io.write_byte(fi.writer, '(', &fi.n)
io.write_int(fi.writer, int(a.line), 10, &fi.n)
io.write_byte(fi.writer, ':', &fi.n)
io.write_int(fi.writer, int(a.column), 10, &fi.n)
io.write_byte(fi.writer, ')', &fi.n)
} else when ODIN_ERROR_POS_STYLE == .Unix {
io.write_byte(fi.writer, ':', &fi.n)
io.write_int(fi.writer, int(a.line), 10, &fi.n)
io.write_byte(fi.writer, ':', &fi.n)
io.write_int(fi.writer, int(a.column), 10, &fi.n)
io.write_byte(fi.writer, ':', &fi.n)
} else {
#panic("Unhandled ODIN_ERROR_POS_STYLE")
}
return
case time.Duration:
@@ -2647,18 +2663,10 @@ fmt_arg :: proc(fi: ^Info, arg: any, verb: rune) {
}
}
custom_types: switch a in arg {
case runtime.Source_Code_Location:
if fi.hash && verb == 'v' {
io.write_string(fi.writer, a.file_path, &fi.n)
io.write_byte(fi.writer, '(', &fi.n)
io.write_i64(fi.writer, i64(a.line), 10, &fi.n)
io.write_byte(fi.writer, ':', &fi.n)
io.write_i64(fi.writer, i64(a.column), 10, &fi.n)
io.write_byte(fi.writer, ')', &fi.n)
return
}
arg_info := type_info_of(arg.id)
if info, ok := arg_info.variant.(runtime.Type_Info_Named); ok {
fmt_named(fi, arg, verb, info)
return
}
base_arg := arg
+11 -14
View File
@@ -7,31 +7,28 @@ foreign import "odin_env"
@(private="file")
foreign odin_env {
write :: proc "c" (fd: u32, p: []byte) ---
write :: proc "contextless" (fd: u32, p: []byte) ---
}
@(private="file")
write_vtable := io.Stream_VTable{
impl_write = proc(s: io.Stream, p: []byte) -> (n: int, err: io.Error) {
fd := u32(uintptr(s.stream_data))
write_stream_proc :: proc(stream_data: rawptr, mode: io.Stream_Mode, p: []byte, offset: i64, whence: io.Seek_From) -> (n: i64, err: io.Error) {
if mode == .Write {
fd := u32(uintptr(stream_data))
write(fd, p)
return len(p), nil
},
return i64(len(p)), nil
}
return 0, .Empty
}
@(private="file")
stdout := io.Writer{
stream = {
stream_vtable = &write_vtable,
stream_data = rawptr(uintptr(1)),
},
procedure = write_stream_proc,
data = rawptr(uintptr(1)),
}
@(private="file")
stderr := io.Writer{
stream = {
stream_vtable = &write_vtable,
stream_data = rawptr(uintptr(2)),
},
procedure = write_stream_proc,
data = rawptr(uintptr(2)),
}
// print formats using the default print settings and writes to stdout
+11 -11
View File
@@ -12,9 +12,9 @@ fprint :: proc(fd: os.Handle, args: ..any, sep := " ") -> int {
b: bufio.Writer
defer bufio.writer_flush(&b)
bufio.writer_init_with_buf(&b, {os.stream_from_handle(fd)}, buf[:])
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, ..args, sep=sep)
}
// fprintln formats using the default print settings and writes to fd
@@ -23,10 +23,10 @@ fprintln :: proc(fd: os.Handle, args: ..any, sep := " ") -> int {
b: bufio.Writer
defer bufio.writer_flush(&b)
bufio.writer_init_with_buf(&b, {os.stream_from_handle(fd)}, buf[:])
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, ..args, sep=sep)
}
// fprintf formats according to the specified format string and writes to fd
fprintf :: proc(fd: os.Handle, fmt: string, args: ..any) -> int {
@@ -34,7 +34,7 @@ fprintf :: proc(fd: os.Handle, fmt: string, args: ..any) -> int {
b: bufio.Writer
defer bufio.writer_flush(&b)
bufio.writer_init_with_buf(&b, {os.stream_from_handle(fd)}, buf[:])
bufio.writer_init_with_buf(&b, os.stream_from_handle(fd), buf[:])
w := bufio.writer_to_writer(&b)
return wprintf(w, fmt, ..args)
@@ -44,7 +44,7 @@ fprint_type :: proc(fd: os.Handle, info: ^runtime.Type_Info) -> (n: int, err: io
b: bufio.Writer
defer bufio.writer_flush(&b)
bufio.writer_init_with_buf(&b, {os.stream_from_handle(fd)}, buf[:])
bufio.writer_init_with_buf(&b, os.stream_from_handle(fd), buf[:])
w := bufio.writer_to_writer(&b)
return wprint_type(w, info)
@@ -54,22 +54,22 @@ fprint_typeid :: proc(fd: os.Handle, id: typeid) -> (n: int, err: io.Error) {
b: bufio.Writer
defer bufio.writer_flush(&b)
bufio.writer_init_with_buf(&b, {os.stream_from_handle(fd)}, buf[:])
bufio.writer_init_with_buf(&b, os.stream_from_handle(fd), buf[:])
w := bufio.writer_to_writer(&b)
return wprint_typeid(w, id)
}
// print formats using the default print settings and writes to os.stdout
print :: proc(args: ..any, sep := " ") -> int { return fprint(fd=os.stdout, args=args, sep=sep) }
print :: proc(args: ..any, sep := " ") -> int { return fprint(os.stdout, ..args, sep=sep) }
// println formats using the default print settings and writes to os.stdout
println :: proc(args: ..any, sep := " ") -> int { return fprintln(fd=os.stdout, args=args, sep=sep) }
println :: proc(args: ..any, sep := " ") -> int { return fprintln(os.stdout, ..args, sep=sep) }
// printf formats according to the specified format string and writes to os.stdout
printf :: proc(fmt: string, args: ..any) -> int { return fprintf(os.stdout, fmt, ..args) }
// eprint formats using the default print settings and writes to os.stderr
eprint :: proc(args: ..any, sep := " ") -> int { return fprint(fd=os.stderr, args=args, sep=sep) }
eprint :: proc(args: ..any, sep := " ") -> int { return fprint(os.stderr, ..args, sep=sep) }
// eprintln formats using the default print settings and writes to os.stderr
eprintln :: proc(args: ..any, sep := " ") -> int { return fprintln(fd=os.stderr, args=args, sep=sep) }
eprintln :: proc(args: ..any, sep := " ") -> int { return fprintln(os.stderr, ..args, sep=sep) }
// eprintf formats according to the specified format string and writes to os.stderr
eprintf :: proc(fmt: string, args: ..any) -> int { return fprintf(os.stderr, fmt, ..args) }
+5 -5
View File
@@ -634,7 +634,7 @@ alpha_add_if_missing :: proc(img: ^Image, alpha_key := Alpha_Key{}, allocator :=
buf := bytes.Buffer{}
// Can we allocate the return buffer?
if !resize(&buf.buf, bytes_wanted) {
if resize(&buf.buf, bytes_wanted) != nil {
delete(buf.buf)
return false
}
@@ -826,7 +826,7 @@ alpha_drop_if_present :: proc(img: ^Image, options := Options{}, alpha_key := Al
buf := bytes.Buffer{}
// Can we allocate the return buffer?
if !resize(&buf.buf, bytes_wanted) {
if resize(&buf.buf, bytes_wanted) != nil {
delete(buf.buf)
return false
}
@@ -1075,7 +1075,7 @@ apply_palette_rgb :: proc(img: ^Image, palette: [256]RGB_Pixel, allocator := con
// Can we allocate the return buffer?
buf := bytes.Buffer{}
bytes_wanted := compute_buffer_size(img.width, img.height, 3, 8)
if !resize(&buf.buf, bytes_wanted) {
if resize(&buf.buf, bytes_wanted) != nil {
delete(buf.buf)
return false
}
@@ -1112,7 +1112,7 @@ apply_palette_rgba :: proc(img: ^Image, palette: [256]RGBA_Pixel, allocator := c
// Can we allocate the return buffer?
buf := bytes.Buffer{}
bytes_wanted := compute_buffer_size(img.width, img.height, 4, 8)
if !resize(&buf.buf, bytes_wanted) {
if resize(&buf.buf, bytes_wanted) != nil {
delete(buf.buf)
return false
}
@@ -1147,7 +1147,7 @@ expand_grayscale :: proc(img: ^Image, allocator := context.allocator) -> (ok: bo
// Can we allocate the return buffer?
buf := bytes.Buffer{}
bytes_wanted := compute_buffer_size(img.width, img.height, img.channels + 2, img.depth)
if !resize(&buf.buf, bytes_wanted) {
if resize(&buf.buf, bytes_wanted) != nil {
delete(buf.buf)
return false
}
+8 -7
View File
@@ -4,13 +4,14 @@ import "core:bytes"
import "core:image"
destroy :: proc(img: ^image.Image) -> bool {
if img == nil do return false
if img == nil {
return false
}
defer free(img)
bytes.buffer_destroy(&img.pixels)
info, ok := img.metadata.(^image.Netpbm_Info)
if !ok do return false
info := img.metadata.(^image.Netpbm_Info) or_return
header_destroy(&info.header)
free(info)
@@ -19,9 +20,9 @@ destroy :: proc(img: ^image.Image) -> bool {
return true
}
header_destroy :: proc(using header: ^Header) {
if format == .P7 && tupltype != "" {
delete(tupltype)
tupltype = ""
header_destroy :: proc(header: ^Header) {
if header.format == .P7 && header.tupltype != "" {
delete(header.tupltype)
header.tupltype = ""
}
}
+7 -6
View File
@@ -1,3 +1,4 @@
//+vet !using-stmt
package netpbm
import "core:bytes"
@@ -161,18 +162,18 @@ save_to_buffer :: proc(img: ^Image, custom_info: Info = {}, allocator := context
// convert from native endianness
if img.depth == 16 {
pixels := mem.slice_data_cast([]u16be, data.buf[len(header_buf):])
for p in &pixels {
for &p in pixels {
p = u16be(transmute(u16) p)
}
} else if header.format in PFM {
if header.little_endian {
pixels := mem.slice_data_cast([]f32le, data.buf[len(header_buf):])
for p in &pixels {
for &p in pixels {
p = f32le(transmute(f32) p)
}
} else {
pixels := mem.slice_data_cast([]f32be, data.buf[len(header_buf):])
for p in &pixels {
for &p in pixels {
p = f32be(transmute(f32) p)
}
}
@@ -578,18 +579,18 @@ decode_image :: proc(img: ^Image, header: Header, data: []byte, allocator := con
if header.format in PFM {
pixels := mem.slice_data_cast([]f32, img.pixels.buf[:])
if header.little_endian {
for p in &pixels {
for &p in pixels {
p = f32(transmute(f32le) p)
}
} else {
for p in &pixels {
for &p in pixels {
p = f32(transmute(f32be) p)
}
}
} else {
if img.depth == 16 {
pixels := mem.slice_data_cast([]u16, img.pixels.buf[:])
for p in &pixels {
for &p in pixels {
p = u16(transmute(u16be) p)
}
}
+8 -9
View File
@@ -36,7 +36,7 @@ destroy :: proc(img: ^Image) {
bytes.buffer_destroy(&img.pixels)
if v, ok := img.metadata.(^image.PNG_Info); ok {
for chunk in &v.chunks {
for chunk in v.chunks {
delete(chunk.data)
}
delete(v.chunks)
@@ -80,11 +80,10 @@ time :: proc(c: image.PNG_Chunk) -> (res: tIME, ok: bool) {
}
core_time :: proc(c: image.PNG_Chunk) -> (t: coretime.Time, ok: bool) {
if png_time, png_ok := time(c); png_ok {
using png_time
if t, png_ok := time(c); png_ok {
return coretime.datetime_to_time(
int(year), int(month), int(day),
int(hour), int(minute), int(second),
int(t.year), int(t.month), int(t.day),
int(t.hour), int(t.minute), int(t.second),
)
} else {
return {}, false
@@ -99,7 +98,7 @@ text :: proc(c: image.PNG_Chunk) -> (res: Text, ok: bool) {
case .tEXt:
ok = true
fields := bytes.split(s=c.data, sep=[]u8{0}, allocator=context.temp_allocator)
fields := bytes.split(c.data, sep=[]u8{0}, allocator=context.temp_allocator)
if len(fields) == 2 {
res.keyword = strings.clone(string(fields[0]))
res.text = strings.clone(string(fields[1]))
@@ -110,7 +109,7 @@ text :: proc(c: image.PNG_Chunk) -> (res: Text, ok: bool) {
case .zTXt:
ok = true
fields := bytes.split_n(s=c.data, sep=[]u8{0}, n=3, allocator=context.temp_allocator)
fields := bytes.split_n(c.data, sep=[]u8{0}, n=3, allocator=context.temp_allocator)
if len(fields) != 3 || len(fields[1]) != 0 {
// Compression method must be 0=Deflate, which thanks to the split above turns
// into an empty slice
@@ -199,7 +198,7 @@ text_destroy :: proc(text: Text) {
iccp :: proc(c: image.PNG_Chunk) -> (res: iCCP, ok: bool) {
runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD(ignore = context.temp_allocator == context.allocator)
fields := bytes.split_n(s=c.data, sep=[]u8{0}, n=3, allocator=context.temp_allocator)
fields := bytes.split_n(c.data, sep=[]u8{0}, n=3, allocator=context.temp_allocator)
if len(fields[0]) < 1 || len(fields[0]) > 79 {
// Invalid profile name
@@ -263,7 +262,7 @@ splt :: proc(c: image.PNG_Chunk) -> (res: sPLT, ok: bool) {
}
runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD(ignore = context.temp_allocator == context.allocator)
fields := bytes.split_n(s=c.data, sep=[]u8{0}, n=2, allocator=context.temp_allocator)
fields := bytes.split_n(c.data, sep=[]u8{0}, n=2, allocator=context.temp_allocator)
if len(fields) != 2 {
return
}
+13 -13
View File
@@ -11,6 +11,7 @@
// package png implements a PNG image reader
//
// The PNG specification is at https://www.w3.org/TR/PNG/.
//+vet !using-stmt
package png
import "core:compress"
@@ -444,15 +445,14 @@ load_from_context :: proc(ctx: ^$C, options := Options{}, allocator := context.a
img.width = int(header.width)
img.height = int(header.height)
using header
h := image.PNG_IHDR{
width = width,
height = height,
bit_depth = bit_depth,
color_type = color_type,
compression_method = compression_method,
filter_method = filter_method,
interlace_method = interlace_method,
width = header.width,
height = header.height,
bit_depth = header.bit_depth,
color_type = header.color_type,
compression_method = header.compression_method,
filter_method = header.filter_method,
interlace_method = header.interlace_method,
}
info.header = h
@@ -731,7 +731,7 @@ load_from_context :: proc(ctx: ^$C, options := Options{}, allocator := context.a
// We need to create a new image buffer
dest_raw_size := compute_buffer_size(int(header.width), int(header.height), out_image_channels, 8)
t := bytes.Buffer{}
if !resize(&t.buf, dest_raw_size) {
if resize(&t.buf, dest_raw_size) != nil {
return {}, .Unable_To_Allocate_Or_Resize
}
@@ -812,7 +812,7 @@ load_from_context :: proc(ctx: ^$C, options := Options{}, allocator := context.a
// We need to create a new image buffer
dest_raw_size := compute_buffer_size(int(header.width), int(header.height), out_image_channels, 16)
t := bytes.Buffer{}
if !resize(&t.buf, dest_raw_size) {
if resize(&t.buf, dest_raw_size) != nil {
return {}, .Unable_To_Allocate_Or_Resize
}
@@ -1011,7 +1011,7 @@ load_from_context :: proc(ctx: ^$C, options := Options{}, allocator := context.a
// We need to create a new image buffer
dest_raw_size := compute_buffer_size(int(header.width), int(header.height), out_image_channels, 8)
t := bytes.Buffer{}
if !resize(&t.buf, dest_raw_size) {
if resize(&t.buf, dest_raw_size) != nil {
return {}, .Unable_To_Allocate_Or_Resize
}
@@ -1522,7 +1522,7 @@ defilter :: proc(img: ^Image, filter_bytes: ^bytes.Buffer, header: ^image.PNG_IH
bytes_per_channel := depth == 16 ? 2 : 1
num_bytes := compute_buffer_size(width, height, channels, depth == 16 ? 16 : 8)
if !resize(&img.pixels.buf, num_bytes) {
if resize(&img.pixels.buf, num_bytes) != nil {
return .Unable_To_Allocate_Or_Resize
}
@@ -1564,7 +1564,7 @@ defilter :: proc(img: ^Image, filter_bytes: ^bytes.Buffer, header: ^image.PNG_IH
if x > 0 && y > 0 {
temp: bytes.Buffer
temp_len := compute_buffer_size(x, y, channels, depth == 16 ? 16 : 8)
if !resize(&temp.buf, temp_len) {
if resize(&temp.buf, temp_len) != nil {
return .Unable_To_Allocate_Or_Resize
}
+2 -2
View File
@@ -53,7 +53,7 @@ save_to_buffer :: proc(output: ^bytes.Buffer, img: ^Image, options := Options{}
// Calculate and allocate maximum size. We'll reclaim space to actually written output at the end.
max_size := pixels * (img.channels + 1) + size_of(image.QOI_Header) + size_of(u64be)
if !resize(&output.buf, max_size) {
if resize(&output.buf, max_size) != nil {
return .Unable_To_Allocate_Or_Resize
}
@@ -233,7 +233,7 @@ load_from_context :: proc(ctx: ^$C, options := Options{}, allocator := context.a
bytes_needed := image.compute_buffer_size(int(header.width), int(header.height), img.channels, 8)
if !resize(&img.pixels.buf, bytes_needed) {
if resize(&img.pixels.buf, bytes_needed) != nil {
return img, .Unable_To_Allocate_Or_Resize
}
+2 -2
View File
@@ -57,7 +57,7 @@ save_to_buffer :: proc(output: ^bytes.Buffer, img: ^Image, options := Options{}
// Calculate and allocate necessary space.
necessary := pixels * img.channels + size_of(image.TGA_Header)
if !resize(&output.buf, necessary) {
if resize(&output.buf, necessary) != nil {
return .Unable_To_Allocate_Or_Resize
}
@@ -292,7 +292,7 @@ load_from_context :: proc(ctx: ^$C, options := Options{}, allocator := context.a
return img, nil
}
if !resize(&img.pixels.buf, dest_channels * img.width * img.height) {
if resize(&img.pixels.buf, dest_channels * img.width * img.height) != nil {
return img, .Unable_To_Allocate_Or_Resize
}
+1
View File
@@ -192,6 +192,7 @@ type_map_info :: proc($T: typeid/map[$K]$V) -> ^runtime.Map_Info ---
type_map_cell_info :: proc($T: typeid) -> ^runtime.Map_Cell_Info ---
type_convert_variants_to_pointers :: proc($T: typeid) -> typeid where type_is_union(T) ---
type_merge :: proc($U, $V: typeid) -> typeid where type_is_union(U), type_is_union(V) ---
constant_utf16_cstring :: proc($literal: string) -> [^]u16 ---
+30 -74
View File
@@ -1,124 +1,80 @@
package io
to_reader :: proc(s: Stream) -> (r: Reader, ok: bool = true) #optional_ok {
r.stream = s
if s.stream_vtable == nil || s.impl_read == nil {
ok = false
}
r = s
ok = .Read in query(s)
return
}
to_writer :: proc(s: Stream) -> (w: Writer, ok: bool = true) #optional_ok {
w.stream = s
if s.stream_vtable == nil || s.impl_write == nil {
ok = false
}
w = s
ok = .Write in query(s)
return
}
to_closer :: proc(s: Stream) -> (c: Closer, ok: bool = true) #optional_ok {
c.stream = s
if s.stream_vtable == nil || s.impl_close == nil {
ok = false
}
c = s
ok = .Close in query(s)
return
}
to_flusher :: proc(s: Stream) -> (f: Flusher, ok: bool = true) #optional_ok {
f.stream = s
if s.stream_vtable == nil || s.impl_flush == nil {
ok = false
}
f = s
ok = .Flush in query(s)
return
}
to_seeker :: proc(s: Stream) -> (seeker: Seeker, ok: bool = true) #optional_ok {
seeker.stream = s
if s.stream_vtable == nil || s.impl_seek == nil {
ok = false
}
seeker = s
ok = .Seek in query(s)
return
}
to_read_writer :: proc(s: Stream) -> (r: Read_Writer, ok: bool = true) #optional_ok {
r.stream = s
if s.stream_vtable == nil || s.impl_read == nil || s.impl_write == nil {
ok = false
}
r = s
ok = query(s) >= {.Read, .Write}
return
}
to_read_closer :: proc(s: Stream) -> (r: Read_Closer, ok: bool = true) #optional_ok {
r.stream = s
if s.stream_vtable == nil || s.impl_read == nil || s.impl_close == nil {
ok = false
}
r = s
ok = query(s) >= {.Read, .Close}
return
}
to_read_write_closer :: proc(s: Stream) -> (r: Read_Write_Closer, ok: bool = true) #optional_ok {
r.stream = s
if s.stream_vtable == nil || s.impl_read == nil || s.impl_write == nil || s.impl_close == nil {
ok = false
}
r = s
ok = query(s) >= {.Read, .Write, .Close}
return
}
to_read_write_seeker :: proc(s: Stream) -> (r: Read_Write_Seeker, ok: bool = true) #optional_ok {
r.stream = s
if s.stream_vtable == nil || s.impl_read == nil || s.impl_write == nil || s.impl_seek == nil {
ok = false
}
r = s
ok = query(s) >= {.Read, .Write, .Seek}
return
}
to_write_flusher :: proc(s: Stream) -> (w: Write_Flusher, ok: bool = true) #optional_ok {
w.stream = s
if s.stream_vtable == nil || s.impl_write == nil || s.impl_flush == nil {
ok = false
}
w = s
ok = query(s) >= {.Write, .Flush}
return
}
to_write_flush_closer :: proc(s: Stream) -> (w: Write_Flush_Closer, ok: bool = true) #optional_ok {
w.stream = s
if s.stream_vtable == nil || s.impl_write == nil || s.impl_flush == nil || s.impl_close == nil {
ok = false
}
w = s
ok = query(s) >= {.Write, .Flush, .Close}
return
}
to_reader_at :: proc(s: Stream) -> (r: Reader_At, ok: bool = true) #optional_ok {
r.stream = s
if s.stream_vtable == nil || s.impl_read_at == nil {
ok = false
}
r = s
ok = query(s) >= {.Read_At}
return
}
to_writer_at :: proc(s: Stream) -> (w: Writer_At, ok: bool = true) #optional_ok {
w.stream = s
if s.stream_vtable == nil || s.impl_write_at == nil {
ok = false
}
return
}
to_reader_from :: proc(s: Stream) -> (r: Reader_From, ok: bool = true) #optional_ok {
r.stream = s
if s.stream_vtable == nil || s.impl_read_from == nil {
ok = false
}
return
}
to_writer_to :: proc(s: Stream) -> (w: Writer_To, ok: bool = true) #optional_ok {
w.stream = s
if s.stream_vtable == nil || s.impl_write_to == nil {
ok = false
}
w = s
ok = query(s) >= {.Write_At}
return
}
to_write_closer :: proc(s: Stream) -> (w: Write_Closer, ok: bool = true) #optional_ok {
w.stream = s
if s.stream_vtable == nil || s.impl_write == nil || s.impl_close == nil {
ok = false
}
w = s
ok = query(s) >= {.Write, .Close}
return
}
to_write_seeker :: proc(s: Stream) -> (w: Write_Seeker, ok: bool = true) #optional_ok {
w.stream = s
if s.stream_vtable == nil || s.impl_write == nil || s.impl_seek == nil {
ok = false
}
w = s
ok = query(s) >= {.Write, .Seek}
return
}
+146 -298
View File
@@ -53,137 +53,106 @@ Error :: enum i32 {
Empty = -1,
}
Close_Proc :: proc(using s: Stream) -> Error
Flush_Proc :: proc(using s: Stream) -> Error
Seek_Proc :: proc(using s: Stream, offset: i64, whence: Seek_From) -> (n: i64, err: Error)
Size_Proc :: proc(using s: Stream) -> i64
Read_Proc :: proc(using s: Stream, p: []byte) -> (n: int, err: Error)
Read_At_Proc :: proc(using s: Stream, p: []byte, off: i64) -> (n: int, err: Error)
Read_From_Proc :: proc(using s: Stream, r: Reader) -> (n: i64, err: Error)
Read_Byte_Proc :: proc(using s: Stream) -> (byte, Error)
Read_Rune_Proc :: proc(using s: Stream) -> (ch: rune, size: int, err: Error)
Unread_Byte_Proc :: proc(using s: Stream) -> Error
Unread_Rune_Proc :: proc(using s: Stream) -> Error
Write_Proc :: proc(using s: Stream, p: []byte) -> (n: int, err: Error)
Write_At_Proc :: proc(using s: Stream, p: []byte, off: i64) -> (n: int, err: Error)
Write_To_Proc :: proc(using s: Stream, w: Writer) -> (n: i64, err: Error)
Write_Byte_Proc :: proc(using s: Stream, c: byte) -> Error
Write_Rune_Proc :: proc(using s: Stream, r: rune) -> (size: int, err: Error)
Destroy_Proc :: proc(using s: Stream) -> Error
Stream_Mode :: enum {
Close,
Flush,
Read,
Read_At,
Write,
Write_At,
Seek,
Size,
Destroy,
Query, // query what modes are available
}
Stream_Mode_Set :: distinct bit_set[Stream_Mode; i64]
Stream_Proc :: #type proc(stream_data: rawptr, mode: Stream_Mode, p: []byte, offset: i64, whence: Seek_From) -> (n: i64, err: Error)
Stream :: struct {
using stream_vtable: ^Stream_VTable,
stream_data: rawptr,
}
Stream_VTable :: struct {
impl_close: Close_Proc,
impl_flush: Flush_Proc,
impl_seek: Seek_Proc,
impl_size: Size_Proc,
impl_read: Read_Proc,
impl_read_at: Read_At_Proc,
impl_read_byte: Read_Byte_Proc,
impl_read_rune: Read_Rune_Proc,
impl_write_to: Write_To_Proc,
impl_write: Write_Proc,
impl_write_at: Write_At_Proc,
impl_write_byte: Write_Byte_Proc,
impl_write_rune: Write_Rune_Proc,
impl_read_from: Read_From_Proc,
impl_unread_byte: Unread_Byte_Proc,
impl_unread_rune: Unread_Rune_Proc,
impl_destroy: Destroy_Proc,
procedure: Stream_Proc,
data: rawptr,
}
Reader :: Stream
Writer :: Stream
Closer :: Stream
Flusher :: Stream
Seeker :: Stream
Reader :: struct {using stream: Stream}
Writer :: struct {using stream: Stream}
Closer :: struct {using stream: Stream}
Flusher :: struct {using stream: Stream}
Seeker :: struct {using stream: Stream}
Read_Writer :: Stream
Read_Closer :: Stream
Read_Write_Closer :: Stream
Read_Write_Seeker :: Stream
Read_Writer :: struct {using stream: Stream}
Read_Closer :: struct {using stream: Stream}
Read_Write_Closer :: struct {using stream: Stream}
Read_Write_Seeker :: struct {using stream: Stream}
Write_Closer :: Stream
Write_Seeker :: Stream
Write_Flusher :: Stream
Write_Flush_Closer :: Stream
Write_Closer :: struct {using stream: Stream}
Write_Seeker :: struct {using stream: Stream}
Write_Flusher :: struct {using stream: Stream}
Write_Flush_Closer :: struct {using stream: Stream}
Reader_At :: struct {using stream: Stream}
Writer_At :: struct {using stream: Stream}
Reader_From :: struct {using stream: Stream}
Writer_To :: struct {using stream: Stream}
Reader_At :: Stream
Writer_At :: Stream
destroy :: proc(s: Stream) -> Error {
close_err := close({s})
if s.stream_vtable != nil && s.impl_destroy != nil {
return s->impl_destroy()
destroy :: proc(s: Stream) -> (err: Error) {
_ = flush(s)
_ = close(s)
if s.procedure != nil {
_, err = s.procedure(s.data, .Destroy, nil, 0, nil)
} else {
err = .Empty
}
if close_err != .None {
return close_err
}
return .Empty
return
}
query :: proc(s: Stream) -> (set: Stream_Mode_Set) {
if s.procedure != nil {
n, _ := s.procedure(s.data, .Query, nil, 0, nil)
set = transmute(Stream_Mode_Set)n
if set != nil {
set += {.Query}
}
}
return
}
query_utility :: #force_inline proc "contextless" (set: Stream_Mode_Set) -> (n: i64, err: Error) {
return transmute(i64)set, nil
}
_i64_err :: #force_inline proc "contextless" (n: int, err: Error) -> (i64, Error) {
return i64(n), err
}
// read reads up to len(p) bytes into s. It returns the number of bytes read and any error if occurred.
//
// When read encounters an .EOF or error after successfully reading n > 0 bytes, it returns the number of
// bytes read along with the error.
read :: proc(s: Reader, p: []byte, n_read: ^int = nil) -> (n: int, err: Error) {
if s.stream_vtable != nil {
if s.impl_read != nil {
n, err = s->impl_read(p)
if n_read != nil {
n_read^ += n
}
return
} else if s.impl_read_byte != nil {
bytes_read := 0
defer if n_read != nil {
n_read^ += bytes_read
}
for _, i in p {
p[i] = s->impl_read_byte() or_return
bytes_read += 1
}
return
}
if s.procedure != nil {
n64: i64
n64, err = s.procedure(s.data, .Read, p, 0, nil)
n = int(n64)
if n_read != nil { n_read^ += n }
} else {
err = .Empty
}
return 0, .Empty
return
}
// write writes up to len(p) bytes into s. It returns the number of bytes written and any error if occurred.
write :: proc(s: Writer, p: []byte, n_written: ^int = nil) -> (n: int, err: Error) {
if s.stream_vtable != nil {
if s.impl_write != nil {
n, err = s->impl_write(p)
if n_written != nil {
n_written^ += n
}
return
} else if s.impl_write_byte != nil {
bytes_written := 0
defer if n_written != nil {
n_written^ += bytes_written
}
for c in p {
s->impl_write_byte(c) or_return
bytes_written += 1
}
return
}
if s.procedure != nil {
n64: i64
n64, err = s.procedure(s.data, .Write, p, 0, nil)
n = int(n64)
if n_written != nil { n_written^ += n }
} else {
err = .Empty
}
return 0, .Empty
return
}
// seek sets the offset of the next read or write to offset.
@@ -194,57 +163,45 @@ write :: proc(s: Writer, p: []byte, n_written: ^int = nil) -> (n: int, err: Erro
//
// seek returns the new offset to the start of the file/stream, and any error if occurred.
seek :: proc(s: Seeker, offset: i64, whence: Seek_From) -> (n: i64, err: Error) {
if s.stream_vtable != nil && s.impl_seek != nil {
return s->impl_seek(offset, whence)
if s.procedure != nil {
n, err = s.procedure(s.data, .Seek, nil, offset, whence)
} else {
err = .Empty
}
return 0, .Empty
return
}
// The behaviour of close after the first call is stream implementation defined.
// Different streams may document their own behaviour.
close :: proc(s: Closer) -> Error {
if s.stream_vtable != nil && s.impl_close != nil {
return s->impl_close()
close :: proc(s: Closer) -> (err: Error) {
if s.procedure != nil {
_, err = s.procedure(s.data, .Close, nil, 0, nil)
}
// Instead of .Empty, .None is fine in this case
return .None
return
}
flush :: proc(s: Flusher) -> Error {
if s.stream_vtable != nil && s.impl_flush != nil {
return s->impl_flush()
flush :: proc(s: Flusher) -> (err: Error) {
if s.procedure != nil {
_, err = s.procedure(s.data, .Flush, nil, 0, nil)
}
// Instead of .Empty, .None is fine in this case
return .None
return
}
// size returns the size of the stream. If the stream does not support querying its size, 0 will be returned.
size :: proc(s: Stream) -> i64 {
if s.stream_vtable == nil {
return 0
size :: proc(s: Stream) -> (n: i64, err: Error) {
if s.procedure != nil {
n, err = s.procedure(s.data, .Size, nil, 0, nil)
if err == .Empty {
n = 0
curr := seek(s, 0, .Current) or_return
end := seek(s, 0, .End) or_return
seek(s, curr, .Start) or_return
n = end
}
} else {
err = .Empty
}
if s.impl_size != nil {
return s->impl_size()
}
if s.impl_seek == nil {
return 0
}
curr, end: i64
err: Error
if curr, err = s->impl_seek(0, .Current); err != nil {
return 0
}
if end, err = s->impl_seek(0, .End); err != nil {
return 0
}
if _, err = s->impl_seek(curr, .Start); err != nil {
return 0
}
return end
return
}
@@ -256,29 +213,24 @@ size :: proc(s: Stream) -> i64 {
//
// If n == len(p), err may be either nil or .EOF
read_at :: proc(r: Reader_At, p: []byte, offset: i64, n_read: ^int = nil) -> (n: int, err: Error) {
defer if n_read != nil {
n_read^ += n
}
if r.stream_vtable == nil {
return 0, .Empty
}
if r.impl_read_at != nil {
return r->impl_read_at(p, offset)
}
if r.impl_seek == nil || r.impl_read == nil {
return 0, .Empty
}
curr_offset := r->impl_seek(offset, .Current) or_return
n, err = r->impl_read(p)
_, err1 := r->impl_seek(curr_offset, .Start)
if err1 != nil && err == nil {
err = err1
if r.procedure != nil {
n64: i64
n64, err = r.procedure(r.data, .Read_At, p, offset, nil)
if err != .Empty {
n = int(n64)
} else {
curr := seek(r, offset, .Current) or_return
n, err = read(r, p)
_, err1 := seek(r, curr, .Start)
if err1 != nil && err == nil {
err = err1
}
}
if n_read != nil { n_read^ += n }
} else {
err = .Empty
}
return
}
// write_at writes len(p) bytes into p starting with the provided offset in the underlying Writer_At stream w.
@@ -287,97 +239,39 @@ read_at :: proc(r: Reader_At, p: []byte, offset: i64, n_read: ^int = nil) -> (n:
// If write_at is writing to a Writer_At which has a seek offset, then write_at should not affect the underlying
// seek offset.
write_at :: proc(w: Writer_At, p: []byte, offset: i64, n_written: ^int = nil) -> (n: int, err: Error) {
defer if n_written != nil {
n_written^ += n
}
if w.stream_vtable == nil {
return 0, .Empty
}
if w.impl_write_at != nil {
return w->impl_write_at(p, offset)
}
if w.impl_seek == nil || w.impl_write == nil {
return 0, .Empty
}
curr_offset: i64
curr_offset, err = w->impl_seek(offset, .Current)
if err != nil {
return 0, err
}
n, err = w->impl_write(p)
_, err1 := w->impl_seek(curr_offset, .Start)
if err1 != nil && err == nil {
err = err1
if w.procedure != nil {
n64: i64
n64, err = w.procedure(w.data, .Write_At, p, offset, nil)
if err != .Empty {
n = int(n64)
} else {
curr := seek(w, offset, .Current) or_return
n, err = write(w, p)
_, err1 := seek(w, curr, .Start)
if err1 != nil && err == nil {
err = err1
}
}
if n_written != nil { n_written^ += n }
} else {
err = .Empty
}
return
}
write_to :: proc(r: Writer_To, w: Writer) -> (n: i64, err: Error) {
if r.stream_vtable == nil || w.stream_vtable == nil {
return 0, .Empty
}
if r.impl_write_to != nil {
return r->impl_write_to(w)
}
return 0, .Empty
}
read_from :: proc(w: Reader_From, r: Reader) -> (n: i64, err: Error) {
if r.stream_vtable == nil || w.stream_vtable == nil {
return 0, .Empty
}
if r.impl_read_from != nil {
return w->impl_read_from(r)
}
return 0, .Empty
}
// read_byte reads and returns the next byte from r.
read_byte :: proc(r: Reader, n_read: ^int = nil) -> (b: byte, err: Error) {
defer if err == nil && n_read != nil {
n_read^ += 1
}
if r.stream_vtable == nil {
return 0, .Empty
}
if r.impl_read_byte != nil {
return r->impl_read_byte()
}
if r.impl_read == nil {
return 0, .Empty
}
buf: [1]byte
_, err = r->impl_read(buf[:])
return buf[0], err
_, err = read(r, buf[:], n_read)
b = buf[0]
return
}
write_byte :: proc(w: Writer, c: byte, n_written: ^int = nil) -> Error {
return _write_byte(auto_cast w, c, n_written)
}
@(private)
_write_byte :: proc(w: Writer, c: byte, n_written: ^int = nil) -> (err: Error) {
defer if err == nil && n_written != nil {
n_written^ += 1
}
if w.stream_vtable == nil {
return .Empty
}
if w.impl_write_byte != nil {
return w->impl_write_byte(c)
}
if w.impl_write == nil {
return .Empty
}
b := [1]byte{c}
_, err = w->impl_write(b[:])
return err
buf: [1]byte
buf[0] = c
write(w, buf[:], n_written) or_return
return nil
}
// read_rune reads a single UTF-8 encoded Unicode codepoint and returns the rune and its size in bytes.
@@ -385,19 +279,9 @@ read_rune :: proc(br: Reader, n_read: ^int = nil) -> (ch: rune, size: int, err:
defer if err == nil && n_read != nil {
n_read^ += size
}
if br.stream_vtable == nil {
return 0, 0, .Empty
}
if br.impl_read_rune != nil {
return br->impl_read_rune()
}
if br.impl_read == nil {
return 0, 0, .Empty
}
b: [utf8.UTF_MAX]byte
_, err = br->impl_read(b[:1])
_, err = read(br, b[:1])
s0 := b[0]
ch = rune(s0)
@@ -415,7 +299,7 @@ read_rune :: proc(br: Reader, n_read: ^int = nil) -> (ch: rune, size: int, err:
return
}
sz := int(x&7)
size, err = br->impl_read(b[1:sz])
size, err = read(br, b[1:sz])
if err != nil || size+1 < sz {
ch = utf8.RUNE_ERROR
return
@@ -425,28 +309,6 @@ read_rune :: proc(br: Reader, n_read: ^int = nil) -> (ch: rune, size: int, err:
return
}
unread_byte :: proc(s: Stream) -> Error {
if s.stream_vtable == nil {
return .Empty
}
if s.impl_unread_byte != nil {
return s->impl_unread_byte()
}
if s.impl_seek != nil {
_, err := s->impl_seek(-1, .Current)
return err
}
return .Empty
}
unread_rune :: proc(s: Writer) -> Error {
if s.stream_vtable != nil && s.impl_unread_rune != nil {
return s->impl_unread_rune()
}
return .Empty
}
// write_string writes the contents of the string s to w.
write_string :: proc(s: Writer, str: string, n_written: ^int = nil) -> (n: int, err: Error) {
return write(s, transmute([]byte)str, n_written)
@@ -457,14 +319,6 @@ write_rune :: proc(s: Writer, r: rune, n_written: ^int = nil) -> (size: int, err
defer if err == nil && n_written != nil {
n_written^ += size
}
if s.stream_vtable == nil {
return 0, .Empty
}
if s.impl_write_rune != nil {
return s->impl_write_rune(r)
}
if r < utf8.RUNE_SELF {
err = write_byte(s, byte(r))
if err == nil {
@@ -542,21 +396,15 @@ copy_n :: proc(dst: Writer, src: Reader, n: i64) -> (written: i64, err: Error) {
@(private)
_copy_buffer :: proc(dst: Writer, src: Reader, buf: []byte) -> (written: i64, err: Error) {
if dst.stream_vtable == nil || src.stream_vtable == nil {
if dst.procedure == nil || src.procedure == nil {
return 0, .Empty
}
if src.impl_write_to != nil {
return src->impl_write_to(dst)
}
if src.impl_read_from != nil {
return dst->impl_read_from(src)
}
buf := buf
if buf == nil {
DEFAULT_SIZE :: 4 * 1024
size := DEFAULT_SIZE
if src.stream_vtable == _limited_reader_vtable {
l := (^Limited_Reader)(src.stream_data)
if src.procedure == _limited_reader_proc {
l := (^Limited_Reader)(src.data)
if i64(size) > l.n {
if l.n < 1 {
size = 1
+48 -40
View File
@@ -5,33 +5,37 @@ Multi_Reader :: struct {
}
@(private)
_multi_reader_vtable := &Stream_VTable{
impl_read = proc(s: Stream, p: []byte) -> (n: int, err: Error) {
mr := (^Multi_Reader)(s.stream_data)
for len(mr.readers) > 0 {
r := mr.readers[0]
n, err = read(r, p)
if err == .EOF {
ordered_remove(&mr.readers, 0)
}
if n > 0 || err != .EOF {
if err == .EOF && len(mr.readers) > 0 {
// Don't return EOF yet, more readers remain
err = nil
}
return
}
_multi_reader_proc :: proc(stream_data: rawptr, mode: Stream_Mode, p: []byte, offset: i64, whence: Seek_From) -> (n: i64, err: Error) {
if mode == .Query {
return query_utility({.Read, .Query})
} else if mode != .Read {
return 0, .Empty
}
mr := (^Multi_Reader)(stream_data)
for len(mr.readers) > 0 {
r := mr.readers[0]
n, err = _i64_err(read(r, p))
if err == .EOF {
ordered_remove(&mr.readers, 0)
}
return 0, .EOF
},
if n > 0 || err != .EOF {
if err == .EOF && len(mr.readers) > 0 {
// Don't return EOF yet, more readers remain
err = nil
}
return
}
}
return 0, .EOF
}
multi_reader_init :: proc(mr: ^Multi_Reader, readers: ..Reader, allocator := context.allocator) -> (r: Reader) {
all_readers := make([dynamic]Reader, 0, len(readers), allocator)
for w in readers {
if w.stream_vtable == _multi_reader_vtable {
other := (^Multi_Reader)(w.stream_data)
if w.procedure == _multi_reader_proc {
other := (^Multi_Reader)(w.data)
append(&all_readers, ..other.readers[:])
} else {
append(&all_readers, w)
@@ -40,8 +44,8 @@ multi_reader_init :: proc(mr: ^Multi_Reader, readers: ..Reader, allocator := con
mr.readers = all_readers
r.stream_vtable = _multi_reader_vtable
r.stream_data = mr
r.procedure = _multi_reader_proc
r.data = mr
return
}
@@ -55,38 +59,42 @@ Multi_Writer :: struct {
}
@(private)
_multi_writer_vtable := &Stream_VTable{
impl_write = proc(s: Stream, p: []byte) -> (n: int, err: Error) {
mw := (^Multi_Writer)(s.stream_data)
for w in mw.writers {
n, err = write(w, p)
if err != nil {
return
}
if n != len(p) {
err = .Short_Write
return
}
_multi_writer_proc :: proc(stream_data: rawptr, mode: Stream_Mode, p: []byte, offset: i64, whence: Seek_From) -> (n: i64, err: Error) {
if mode == .Query {
return query_utility({.Write, .Query})
} else if mode != .Write {
return 0, .Empty
}
mw := (^Multi_Writer)(stream_data)
for w in mw.writers {
n, err = _i64_err(write(w, p))
if err != nil {
return
}
if n != i64(len(p)) {
err = .Short_Write
return
}
}
return len(p), nil
},
return i64(len(p)), nil
}
multi_writer_init :: proc(mw: ^Multi_Writer, writers: ..Writer, allocator := context.allocator) -> (out: Writer) {
mw.writers = make([dynamic]Writer, 0, len(writers), allocator)
for w in writers {
if w.stream_vtable == _multi_writer_vtable {
other := (^Multi_Writer)(w.stream_data)
if w.procedure == _multi_writer_proc {
other := (^Multi_Writer)(w.data)
append(&mw.writers, ..other.writers[:])
} else {
append(&mw.writers, w)
}
}
out.stream_vtable = _multi_writer_vtable
out.stream_data = mw
out.procedure = _multi_writer_proc
out.data = mw
return
}
+64 -44
View File
@@ -2,6 +2,7 @@ package io
import "core:strconv"
import "core:unicode/utf8"
import "core:unicode/utf16"
read_ptr :: proc(r: Reader, p: rawptr, byte_size: int, n_read: ^int = nil) -> (n: int, err: Error) {
return read(r, ([^]byte)(p)[:byte_size], n_read)
@@ -146,7 +147,7 @@ write_encoded_rune :: proc(w: Writer, r: rune, write_quote := true, n_written: ^
return
}
write_escaped_rune :: proc(w: Writer, r: rune, quote: byte, html_safe := false, n_written: ^int = nil) -> (n: int, err: Error) {
write_escaped_rune :: proc(w: Writer, r: rune, quote: byte, html_safe := false, n_written: ^int = nil, for_json := false) -> (n: int, err: Error) {
is_printable :: proc(r: rune) -> bool {
if r <= 0xff {
switch r {
@@ -163,7 +164,7 @@ write_escaped_rune :: proc(w: Writer, r: rune, quote: byte, html_safe := false,
defer if n_written != nil {
n_written^ += n
}
if html_safe {
switch r {
case '<', '>', '&':
@@ -211,17 +212,29 @@ write_escaped_rune :: proc(w: Writer, r: rune, quote: byte, html_safe := false,
write_byte(w, DIGITS_LOWER[c>>uint(s) & 0xf], &n) or_return
}
case:
write_byte(w, '\\', &n) or_return
write_byte(w, 'U', &n) or_return
for s := 28; s >= 0; s -= 4 {
write_byte(w, DIGITS_LOWER[c>>uint(s) & 0xf], &n) or_return
if for_json {
buf: [2]u16
utf16.encode(buf[:], []rune{c})
for bc in buf {
write_byte(w, '\\', &n) or_return
write_byte(w, 'u', &n) or_return
for s := 12; s >= 0; s -= 4 {
write_byte(w, DIGITS_LOWER[bc>>uint(s) & 0xf], &n) or_return
}
}
} else {
write_byte(w, '\\', &n) or_return
write_byte(w, 'U', &n) or_return
for s := 24; s >= 0; s -= 4 {
write_byte(w, DIGITS_LOWER[c>>uint(s) & 0xf], &n) or_return
}
}
}
}
return
}
write_quoted_string :: proc(w: Writer, str: string, quote: byte = '"', n_written: ^int = nil) -> (n: int, err: Error) {
write_quoted_string :: proc(w: Writer, str: string, quote: byte = '"', n_written: ^int = nil, for_json := false) -> (n: int, err: Error) {
defer if n_written != nil {
n_written^ += n
}
@@ -240,7 +253,7 @@ write_quoted_string :: proc(w: Writer, str: string, quote: byte = '"', n_written
continue
}
n_wrapper(write_escaped_rune(w, r, quote), &n) or_return
n_wrapper(write_escaped_rune(w, r, quote, false, nil, for_json), &n) or_return
}
write_byte(w, quote, &n) or_return
@@ -279,17 +292,21 @@ Tee_Reader :: struct {
}
@(private)
_tee_reader_vtable := &Stream_VTable{
impl_read = proc(s: Stream, p: []byte) -> (n: int, err: Error) {
t := (^Tee_Reader)(s.stream_data)
n, err = read(t.r, p)
_tee_reader_proc :: proc(stream_data: rawptr, mode: Stream_Mode, p: []byte, offset: i64, whence: Seek_From) -> (n: i64, err: Error) {
t := (^Tee_Reader)(stream_data)
#partial switch mode {
case .Read:
n, err = _i64_err(read(t.r, p))
if n > 0 {
if wn, werr := write(t.w, p[:n]); werr != nil {
return wn, werr
return i64(wn), werr
}
}
return
},
case .Query:
return query_utility({.Read, .Query})
}
return 0, .Empty
}
// tee_reader_init returns a Reader that writes to 'w' what it reads from 'r'
@@ -304,8 +321,8 @@ tee_reader_init :: proc(t: ^Tee_Reader, r: Reader, w: Writer, allocator := conte
}
tee_reader_to_reader :: proc(t: ^Tee_Reader) -> (r: Reader) {
r.stream_data = t
r.stream_vtable = _tee_reader_vtable
r.data = t
r.procedure = _tee_reader_proc
return
}
@@ -319,9 +336,10 @@ Limited_Reader :: struct {
}
@(private)
_limited_reader_vtable := &Stream_VTable{
impl_read = proc(s: Stream, p: []byte) -> (n: int, err: Error) {
l := (^Limited_Reader)(s.stream_data)
_limited_reader_proc :: proc(stream_data: rawptr, mode: Stream_Mode, p: []byte, offset: i64, whence: Seek_From) -> (n: i64, err: Error) {
l := (^Limited_Reader)(stream_data)
#partial switch mode {
case .Read:
if l.n <= 0 {
return 0, .EOF
}
@@ -329,10 +347,13 @@ _limited_reader_vtable := &Stream_VTable{
if i64(len(p)) > l.n {
p = p[0:l.n]
}
n, err = read(l.r, p)
n, err = _i64_err(read(l.r, p))
l.n -= i64(n)
return
},
case .Query:
return query_utility({.Read, .Query})
}
return 0, .Empty
}
limited_reader_init :: proc(l: ^Limited_Reader, r: Reader, n: i64) -> Reader {
@@ -342,8 +363,8 @@ limited_reader_init :: proc(l: ^Limited_Reader, r: Reader, n: i64) -> Reader {
}
limited_reader_to_reader :: proc(l: ^Limited_Reader) -> (r: Reader) {
r.stream_vtable = _limited_reader_vtable
r.stream_data = l
r.procedure = _limited_reader_proc
r.data = l
return
}
@@ -362,15 +383,16 @@ section_reader_init :: proc(s: ^Section_Reader, r: Reader_At, off: i64, n: i64)
return
}
section_reader_to_stream :: proc(s: ^Section_Reader) -> (out: Stream) {
out.stream_data = s
out.stream_vtable = _section_reader_vtable
out.data = s
out.procedure = _section_reader_proc
return
}
@(private)
_section_reader_vtable := &Stream_VTable{
impl_read = proc(stream: Stream, p: []byte) -> (n: int, err: Error) {
s := (^Section_Reader)(stream.stream_data)
_section_reader_proc :: proc(stream_data: rawptr, mode: Stream_Mode, p: []byte, offset: i64, whence: Seek_From) -> (n: i64, err: Error) {
s := (^Section_Reader)(stream_data)
#partial switch mode {
case .Read:
if s.off >= s.limit {
return 0, .EOF
}
@@ -378,13 +400,11 @@ _section_reader_vtable := &Stream_VTable{
if max := s.limit - s.off; i64(len(p)) > max {
p = p[0:max]
}
n, err = read_at(s.r, p, s.off)
n, err = _i64_err(read_at(s.r, p, s.off))
s.off += i64(n)
return
},
impl_read_at = proc(stream: Stream, p: []byte, off: i64) -> (n: int, err: Error) {
s := (^Section_Reader)(stream.stream_data)
p, off := p, off
case .Read_At:
p, off := p, offset
if off < 0 || off >= s.limit - s.base {
return 0, .EOF
@@ -392,17 +412,15 @@ _section_reader_vtable := &Stream_VTable{
off += s.base
if max := s.limit - off; i64(len(p)) > max {
p = p[0:max]
n, err = read_at(s.r, p, off)
n, err = _i64_err(read_at(s.r, p, off))
if err == nil {
err = .EOF
}
return
}
return read_at(s.r, p, off)
},
impl_seek = proc(stream: Stream, offset: i64, whence: Seek_From) -> (n: i64, err: Error) {
s := (^Section_Reader)(stream.stream_data)
return _i64_err(read_at(s.r, p, off))
case .Seek:
offset := offset
switch whence {
case:
@@ -420,10 +438,12 @@ _section_reader_vtable := &Stream_VTable{
s.off = offset
n = offset - s.base
return
},
impl_size = proc(stream: Stream) -> i64 {
s := (^Section_Reader)(stream.stream_data)
return s.limit - s.base
},
}
case .Size:
n = s.limit - s.base
return
case .Query:
return query_utility({.Read, .Read_At, .Seek, .Size, .Query})
}
return 0, nil
}
+13 -13
View File
@@ -76,43 +76,43 @@ nil_logger :: proc() -> Logger {
}
debugf :: proc(fmt_str: string, args: ..any, location := #caller_location) {
logf(level=.Debug, fmt_str=fmt_str, args=args, location=location)
logf(.Debug, fmt_str, ..args, location=location)
}
infof :: proc(fmt_str: string, args: ..any, location := #caller_location) {
logf(level=.Info, fmt_str=fmt_str, args=args, location=location)
logf(.Info, fmt_str, ..args, location=location)
}
warnf :: proc(fmt_str: string, args: ..any, location := #caller_location) {
logf(level=.Warning, fmt_str=fmt_str, args=args, location=location)
logf(.Warning, fmt_str, ..args, location=location)
}
errorf :: proc(fmt_str: string, args: ..any, location := #caller_location) {
logf(level=.Error, fmt_str=fmt_str, args=args, location=location)
logf(.Error, fmt_str, ..args, location=location)
}
fatalf :: proc(fmt_str: string, args: ..any, location := #caller_location) {
logf(level=.Fatal, fmt_str=fmt_str, args=args, location=location)
logf(.Fatal, fmt_str, ..args, location=location)
}
debug :: proc(args: ..any, sep := " ", location := #caller_location) {
log(level=.Debug, args=args, sep=sep, location=location)
log(.Debug, ..args, sep=sep, location=location)
}
info :: proc(args: ..any, sep := " ", location := #caller_location) {
log(level=.Info, args=args, sep=sep, location=location)
log(.Info, ..args, sep=sep, location=location)
}
warn :: proc(args: ..any, sep := " ", location := #caller_location) {
log(level=.Warning, args=args, sep=sep, location=location)
log(.Warning, ..args, sep=sep, location=location)
}
error :: proc(args: ..any, sep := " ", location := #caller_location) {
log(level=.Error, args=args, sep=sep, location=location)
log(.Error, ..args, sep=sep, location=location)
}
fatal :: proc(args: ..any, sep := " ", location := #caller_location) {
log(level=.Fatal, args=args, sep=sep, location=location)
log(.Fatal, ..args, sep=sep, location=location)
}
panic :: proc(args: ..any, location := #caller_location) -> ! {
log(level=.Fatal, args=args, location=location)
log(.Fatal, ..args, location=location)
runtime.panic("log.panic", location)
}
panicf :: proc(fmt_str: string, args: ..any, location := #caller_location) -> ! {
logf(level=.Fatal, fmt_str=fmt_str, args=args, location=location)
logf(.Fatal, fmt_str, ..args, location=location)
runtime.panic("log.panicf", location)
}
@@ -127,7 +127,7 @@ log :: proc(level: Level, args: ..any, sep := " ", location := #caller_location)
if level < logger.lowest_level {
return
}
str := fmt.tprint(args=args, sep=sep) //NOTE(Hoej): While tprint isn't thread-safe, no logging is.
str := fmt.tprint(..args, sep=sep) //NOTE(Hoej): While tprint isn't thread-safe, no logging is.
logger.procedure(logger.data, level, str, logger.options, location)
}
+27 -27
View File
@@ -38,60 +38,60 @@ log_allocator_proc :: proc(allocator_data: rawptr, mode: runtime.Allocator_Mode,
switch mode {
case .Alloc:
logf(
level=la.level,
fmt_str = "%s%s>>> ALLOCATOR(mode=.Alloc, size=%d, alignment=%d)",
args = {la.prefix, padding, size, alignment},
la.level,
"%s%s>>> ALLOCATOR(mode=.Alloc, size=%d, alignment=%d)",
la.prefix, padding, size, alignment,
location = location,
)
case .Alloc_Non_Zeroed:
logf(
level=la.level,
fmt_str = "%s%s>>> ALLOCATOR(mode=.Alloc_Non_Zeroed, size=%d, alignment=%d)",
args = {la.prefix, padding, size, alignment},
la.level,
"%s%s>>> ALLOCATOR(mode=.Alloc_Non_Zeroed, size=%d, alignment=%d)",
la.prefix, padding, size, alignment,
location = location,
)
case .Free:
if old_size != 0 {
logf(
level=la.level,
fmt_str = "%s%s<<< ALLOCATOR(mode=.Free, ptr=%p, size=%d)",
args = {la.prefix, padding, old_memory, old_size},
la.level,
"%s%s<<< ALLOCATOR(mode=.Free, ptr=%p, size=%d)",
la.prefix, padding, old_memory, old_size,
location = location,
)
} else {
logf(
level=la.level,
fmt_str = "%s%s<<< ALLOCATOR(mode=.Free, ptr=%p)",
args = {la.prefix, padding, old_memory},
la.level,
"%s%s<<< ALLOCATOR(mode=.Free, ptr=%p)",
la.prefix, padding, old_memory,
location = location,
)
}
case .Free_All:
logf(
level=la.level,
fmt_str = "%s%s<<< ALLOCATOR(mode=.Free_All)",
args = {la.prefix, padding},
la.level,
"%s%s<<< ALLOCATOR(mode=.Free_All)",
la.prefix, padding,
location = location,
)
case .Resize:
logf(
level=la.level,
fmt_str = "%s%s>>> ALLOCATOR(mode=.Resize, ptr=%p, old_size=%d, size=%d, alignment=%d)",
args = {la.prefix, padding, old_memory, old_size, size, alignment},
la.level,
"%s%s>>> ALLOCATOR(mode=.Resize, ptr=%p, old_size=%d, size=%d, alignment=%d)",
la.prefix, padding, old_memory, old_size, size, alignment,
location = location,
)
case .Query_Features:
logf(
level=la.level,
fmt_str = "%s%ALLOCATOR(mode=.Query_Features)",
args = {la.prefix, padding},
la.level,
"%s%ALLOCATOR(mode=.Query_Features)",
la.prefix, padding,
location = location,
)
case .Query_Info:
logf(
level=la.level,
fmt_str = "%s%ALLOCATOR(mode=.Query_Info)",
args = {la.prefix, padding},
la.level,
"%s%ALLOCATOR(mode=.Query_Info)",
la.prefix, padding,
location = location,
)
}
@@ -103,9 +103,9 @@ log_allocator_proc :: proc(allocator_data: rawptr, mode: runtime.Allocator_Mode,
defer la.locked = false
if err != nil {
logf(
level=la.level,
fmt_str = "%s%ALLOCATOR ERROR=%v",
args = {la.prefix, padding, error},
la.level,
"%s%ALLOCATOR ERROR=%v",
la.prefix, padding, error,
location = location,
)
}
+3 -3
View File
@@ -19,7 +19,7 @@ import rnd "core:math/rand"
int_destroy :: proc(integers: ..^Int) {
integers := integers
for a in &integers {
for a in integers {
assert_if_nil(a)
}
#force_inline internal_int_destroy(..integers)
@@ -408,7 +408,7 @@ clear_if_uninitialized_multi :: proc(args: ..^Int, allocator := context.allocato
args := args
assert_if_nil(..args)
for i in &args {
for i in args {
#force_inline internal_clear_if_uninitialized_single(i, allocator) or_return
}
return err
@@ -435,7 +435,7 @@ int_init_multi :: proc(integers: ..^Int, allocator := context.allocator) -> (err
assert_if_nil(..integers)
integers := integers
for a in &integers {
for a in integers {
#force_inline internal_clear(a, true, allocator) or_return
}
return nil
+2 -2
View File
@@ -1857,7 +1857,7 @@ internal_root_n :: proc { internal_int_root_n, }
internal_int_destroy :: proc(integers: ..^Int) {
integers := integers
for a in &integers {
for &a in integers {
if internal_int_allocated_cap(a) > 0 {
mem.zero_slice(a.digit[:])
free(&a.digit[0])
@@ -2909,7 +2909,7 @@ internal_int_init_multi :: proc(integers: ..^Int, allocator := context.allocator
context.allocator = allocator
integers := integers
for a in &integers {
for a in integers {
internal_clear(a) or_return
}
return nil
+1 -1
View File
@@ -429,7 +429,7 @@ internal_int_write_to_ascii_file :: proc(a: ^Int, filename: string, radix := i8(
len = l,
}
ok := os.write_entire_file(name=filename, data=data, truncate=true)
ok := os.write_entire_file(filename, data, truncate=true)
return nil if ok else .Cannot_Write_File
}
+1 -1
View File
@@ -137,7 +137,7 @@ rat_copy :: proc(dst, src: ^Rat, minimize := false, allocator := context.allocat
internal_rat_destroy :: proc(rationals: ..^Rat) {
rationals := rationals
for z in &rationals {
for &z in rationals {
internal_int_destroy(&z.a, &z.b)
}
}
+154 -77
View File
@@ -37,68 +37,96 @@ overflowing_sub :: intrinsics.overflow_sub
overflowing_mul :: intrinsics.overflow_mul
log2 :: proc(x: $T) -> T where intrinsics.type_is_integer(T), intrinsics.type_is_unsigned(T) {
@(require_results)
log2 :: proc "contextless" (x: $T) -> T where intrinsics.type_is_integer(T), intrinsics.type_is_unsigned(T) {
return (8*size_of(T)-1) - count_leading_zeros(x)
}
rotate_left8 :: proc(x: u8, k: int) -> u8 {
@(require_results)
rotate_left8 :: proc "contextless" (x: u8, k: int) -> u8 {
n :: 8
s := uint(k) & (n-1)
return x <<s | x>>(n-s)
}
rotate_left16 :: proc(x: u16, k: int) -> u16 {
@(require_results)
rotate_left16 :: proc "contextless" (x: u16, k: int) -> u16 {
n :: 16
s := uint(k) & (n-1)
return x <<s | x>>(n-s)
}
rotate_left32 :: proc(x: u32, k: int) -> u32 {
@(require_results)
rotate_left32 :: proc "contextless" (x: u32, k: int) -> u32 {
n :: 32
s := uint(k) & (n-1)
return x <<s | x>>(n-s)
}
rotate_left64 :: proc(x: u64, k: int) -> u64 {
@(require_results)
rotate_left64 :: proc "contextless" (x: u64, k: int) -> u64 {
n :: 64
s := uint(k) & (n-1)
return x <<s | x>>(n-s)
}
rotate_left :: proc(x: uint, k: int) -> uint {
@(require_results)
rotate_left :: proc "contextless" (x: uint, k: int) -> uint {
n :: 8*size_of(uint)
s := uint(k) & (n-1)
return x <<s | x>>(n-s)
}
from_be_u8 :: proc(i: u8) -> u8 { return i }
from_be_u16 :: proc(i: u16) -> u16 { when ODIN_ENDIAN == .Big { return i } else { return byte_swap(i) } }
from_be_u32 :: proc(i: u32) -> u32 { when ODIN_ENDIAN == .Big { return i } else { return byte_swap(i) } }
from_be_u64 :: proc(i: u64) -> u64 { when ODIN_ENDIAN == .Big { return i } else { return byte_swap(i) } }
from_be_uint :: proc(i: uint) -> uint { when ODIN_ENDIAN == .Big { return i } else { return byte_swap(i) } }
@(require_results)
from_be_u8 :: proc "contextless" (i: u8) -> u8 { return i }
@(require_results)
from_be_u16 :: proc "contextless" (i: u16) -> u16 { when ODIN_ENDIAN == .Big { return i } else { return byte_swap(i) } }
@(require_results)
from_be_u32 :: proc "contextless" (i: u32) -> u32 { when ODIN_ENDIAN == .Big { return i } else { return byte_swap(i) } }
@(require_results)
from_be_u64 :: proc "contextless" (i: u64) -> u64 { when ODIN_ENDIAN == .Big { return i } else { return byte_swap(i) } }
@(require_results)
from_be_uint :: proc "contextless" (i: uint) -> uint { when ODIN_ENDIAN == .Big { return i } else { return byte_swap(i) } }
from_le_u8 :: proc(i: u8) -> u8 { return i }
from_le_u16 :: proc(i: u16) -> u16 { when ODIN_ENDIAN == .Little { return i } else { return byte_swap(i) } }
from_le_u32 :: proc(i: u32) -> u32 { when ODIN_ENDIAN == .Little { return i } else { return byte_swap(i) } }
from_le_u64 :: proc(i: u64) -> u64 { when ODIN_ENDIAN == .Little { return i } else { return byte_swap(i) } }
from_le_uint :: proc(i: uint) -> uint { when ODIN_ENDIAN == .Little { return i } else { return byte_swap(i) } }
@(require_results)
from_le_u8 :: proc "contextless" (i: u8) -> u8 { return i }
@(require_results)
from_le_u16 :: proc "contextless" (i: u16) -> u16 { when ODIN_ENDIAN == .Little { return i } else { return byte_swap(i) } }
@(require_results)
from_le_u32 :: proc "contextless" (i: u32) -> u32 { when ODIN_ENDIAN == .Little { return i } else { return byte_swap(i) } }
@(require_results)
from_le_u64 :: proc "contextless" (i: u64) -> u64 { when ODIN_ENDIAN == .Little { return i } else { return byte_swap(i) } }
@(require_results)
from_le_uint :: proc "contextless" (i: uint) -> uint { when ODIN_ENDIAN == .Little { return i } else { return byte_swap(i) } }
to_be_u8 :: proc(i: u8) -> u8 { return i }
to_be_u16 :: proc(i: u16) -> u16 { when ODIN_ENDIAN == .Big { return i } else { return byte_swap(i) } }
to_be_u32 :: proc(i: u32) -> u32 { when ODIN_ENDIAN == .Big { return i } else { return byte_swap(i) } }
to_be_u64 :: proc(i: u64) -> u64 { when ODIN_ENDIAN == .Big { return i } else { return byte_swap(i) } }
to_be_uint :: proc(i: uint) -> uint { when ODIN_ENDIAN == .Big { return i } else { return byte_swap(i) } }
@(require_results)
to_be_u8 :: proc "contextless" (i: u8) -> u8 { return i }
@(require_results)
to_be_u16 :: proc "contextless" (i: u16) -> u16 { when ODIN_ENDIAN == .Big { return i } else { return byte_swap(i) } }
@(require_results)
to_be_u32 :: proc "contextless" (i: u32) -> u32 { when ODIN_ENDIAN == .Big { return i } else { return byte_swap(i) } }
@(require_results)
to_be_u64 :: proc "contextless" (i: u64) -> u64 { when ODIN_ENDIAN == .Big { return i } else { return byte_swap(i) } }
@(require_results)
to_be_uint :: proc "contextless" (i: uint) -> uint { when ODIN_ENDIAN == .Big { return i } else { return byte_swap(i) } }
to_le_u8 :: proc(i: u8) -> u8 { return i }
to_le_u16 :: proc(i: u16) -> u16 { when ODIN_ENDIAN == .Little { return i } else { return byte_swap(i) } }
to_le_u32 :: proc(i: u32) -> u32 { when ODIN_ENDIAN == .Little { return i } else { return byte_swap(i) } }
to_le_u64 :: proc(i: u64) -> u64 { when ODIN_ENDIAN == .Little { return i } else { return byte_swap(i) } }
to_le_uint :: proc(i: uint) -> uint { when ODIN_ENDIAN == .Little { return i } else { return byte_swap(i) } }
@(require_results)
to_le_u8 :: proc "contextless" (i: u8) -> u8 { return i }
@(require_results)
to_le_u16 :: proc "contextless" (i: u16) -> u16 { when ODIN_ENDIAN == .Little { return i } else { return byte_swap(i) } }
@(require_results)
to_le_u32 :: proc "contextless" (i: u32) -> u32 { when ODIN_ENDIAN == .Little { return i } else { return byte_swap(i) } }
@(require_results)
to_le_u64 :: proc "contextless" (i: u64) -> u64 { when ODIN_ENDIAN == .Little { return i } else { return byte_swap(i) } }
@(require_results)
to_le_uint :: proc "contextless" (i: uint) -> uint { when ODIN_ENDIAN == .Little { return i } else { return byte_swap(i) } }
len_u8 :: proc(x: u8) -> int {
@(require_results)
len_u8 :: proc "contextless" (x: u8) -> int {
return int(len_u8_table[x])
}
len_u16 :: proc(x: u16) -> (n: int) {
@(require_results)
len_u16 :: proc "contextless" (x: u16) -> (n: int) {
x := x
if x >= 1<<8 {
x >>= 8
@@ -106,7 +134,8 @@ len_u16 :: proc(x: u16) -> (n: int) {
}
return n + int(len_u8_table[x])
}
len_u32 :: proc(x: u32) -> (n: int) {
@(require_results)
len_u32 :: proc "contextless" (x: u32) -> (n: int) {
x := x
if x >= 1<<16 {
x >>= 16
@@ -118,7 +147,8 @@ len_u32 :: proc(x: u32) -> (n: int) {
}
return n + int(len_u8_table[x])
}
len_u64 :: proc(x: u64) -> (n: int) {
@(require_results)
len_u64 :: proc "contextless" (x: u64) -> (n: int) {
x := x
if x >= 1<<32 {
x >>= 32
@@ -134,7 +164,8 @@ len_u64 :: proc(x: u64) -> (n: int) {
}
return n + int(len_u8_table[x])
}
len_uint :: proc(x: uint) -> (n: int) {
@(require_results)
len_uint :: proc "contextless" (x: uint) -> (n: int) {
when size_of(uint) == size_of(u64) {
return len_u64(u64(x))
} else {
@@ -146,21 +177,24 @@ len_uint :: proc(x: uint) -> (n: int) {
len :: proc{len_u8, len_u16, len_u32, len_u64, len_uint}
add_u32 :: proc(x, y, carry: u32) -> (sum, carry_out: u32) {
@(require_results)
add_u32 :: proc "contextless" (x, y, carry: u32) -> (sum, carry_out: u32) {
tmp_carry, tmp_carry2: bool
sum, tmp_carry = intrinsics.overflow_add(x, y)
sum, tmp_carry2 = intrinsics.overflow_add(sum, carry)
carry_out = u32(tmp_carry | tmp_carry2)
return
}
add_u64 :: proc(x, y, carry: u64) -> (sum, carry_out: u64) {
@(require_results)
add_u64 :: proc "contextless" (x, y, carry: u64) -> (sum, carry_out: u64) {
tmp_carry, tmp_carry2: bool
sum, tmp_carry = intrinsics.overflow_add(x, y)
sum, tmp_carry2 = intrinsics.overflow_add(sum, carry)
carry_out = u64(tmp_carry | tmp_carry2)
return
}
add_uint :: proc(x, y, carry: uint) -> (sum, carry_out: uint) {
@(require_results)
add_uint :: proc "contextless" (x, y, carry: uint) -> (sum, carry_out: uint) {
when size_of(uint) == size_of(u64) {
a, b := add_u64(u64(x), u64(y), u64(carry))
} else {
@@ -172,21 +206,24 @@ add_uint :: proc(x, y, carry: uint) -> (sum, carry_out: uint) {
add :: proc{add_u32, add_u64, add_uint}
sub_u32 :: proc(x, y, borrow: u32) -> (diff, borrow_out: u32) {
@(require_results)
sub_u32 :: proc "contextless" (x, y, borrow: u32) -> (diff, borrow_out: u32) {
tmp_borrow, tmp_borrow2: bool
diff, tmp_borrow = intrinsics.overflow_sub(x, y)
diff, tmp_borrow2 = intrinsics.overflow_sub(diff, borrow)
borrow_out = u32(tmp_borrow | tmp_borrow2)
return
}
sub_u64 :: proc(x, y, borrow: u64) -> (diff, borrow_out: u64) {
@(require_results)
sub_u64 :: proc "contextless" (x, y, borrow: u64) -> (diff, borrow_out: u64) {
tmp_borrow, tmp_borrow2: bool
diff, tmp_borrow = intrinsics.overflow_sub(x, y)
diff, tmp_borrow2 = intrinsics.overflow_sub(diff, borrow)
borrow_out = u64(tmp_borrow | tmp_borrow2)
return
}
sub_uint :: proc(x, y, borrow: uint) -> (diff, borrow_out: uint) {
@(require_results)
sub_uint :: proc "contextless" (x, y, borrow: uint) -> (diff, borrow_out: uint) {
when size_of(uint) == size_of(u64) {
a, b := sub_u64(u64(x), u64(y), u64(borrow))
} else {
@@ -198,18 +235,21 @@ sub_uint :: proc(x, y, borrow: uint) -> (diff, borrow_out: uint) {
sub :: proc{sub_u32, sub_u64, sub_uint}
mul_u32 :: proc(x, y: u32) -> (hi, lo: u32) {
@(require_results)
mul_u32 :: proc "contextless" (x, y: u32) -> (hi, lo: u32) {
z := u64(x) * u64(y)
hi, lo = u32(z>>32), u32(z)
return
}
mul_u64 :: proc(x, y: u64) -> (hi, lo: u64) {
@(require_results)
mul_u64 :: proc "contextless" (x, y: u64) -> (hi, lo: u64) {
prod_wide := u128(x) * u128(y)
hi, lo = u64(prod_wide>>64), u64(prod_wide)
return
}
mul_uint :: proc(x, y: uint) -> (hi, lo: uint) {
@(require_results)
mul_uint :: proc "contextless" (x, y: uint) -> (hi, lo: uint) {
when size_of(uint) == size_of(u32) {
a, b := mul_u32(u32(x), u32(y))
} else {
@@ -222,13 +262,15 @@ mul_uint :: proc(x, y: uint) -> (hi, lo: uint) {
mul :: proc{mul_u32, mul_u64, mul_uint}
div_u32 :: proc(hi, lo, y: u32) -> (quo, rem: u32) {
@(require_results)
div_u32 :: proc "odin" (hi, lo, y: u32) -> (quo, rem: u32) {
assert(y != 0 && y <= hi)
z := u64(hi)<<32 | u64(lo)
quo, rem = u32(z/u64(y)), u32(z%u64(y))
return
}
div_u64 :: proc(hi, lo, y: u64) -> (quo, rem: u64) {
@(require_results)
div_u64 :: proc "odin" (hi, lo, y: u64) -> (quo, rem: u64) {
y := y
two32 :: 1 << 32
mask32 :: two32 - 1
@@ -273,7 +315,8 @@ div_u64 :: proc(hi, lo, y: u64) -> (quo, rem: u64) {
return q1*two32 + q0, (un21*two32 + un0 - q0*y) >> s
}
div_uint :: proc(hi, lo, y: uint) -> (quo, rem: uint) {
@(require_results)
div_uint :: proc "odin" (hi, lo, y: uint) -> (quo, rem: uint) {
when size_of(uint) == size_of(u32) {
a, b := div_u32(u32(hi), u32(lo), u32(y))
} else {
@@ -286,16 +329,26 @@ div :: proc{div_u32, div_u64, div_uint}
is_power_of_two_u8 :: proc(i: u8) -> bool { return i > 0 && (i & (i-1)) == 0 }
is_power_of_two_i8 :: proc(i: i8) -> bool { return i > 0 && (i & (i-1)) == 0 }
is_power_of_two_u16 :: proc(i: u16) -> bool { return i > 0 && (i & (i-1)) == 0 }
is_power_of_two_i16 :: proc(i: i16) -> bool { return i > 0 && (i & (i-1)) == 0 }
is_power_of_two_u32 :: proc(i: u32) -> bool { return i > 0 && (i & (i-1)) == 0 }
is_power_of_two_i32 :: proc(i: i32) -> bool { return i > 0 && (i & (i-1)) == 0 }
is_power_of_two_u64 :: proc(i: u64) -> bool { return i > 0 && (i & (i-1)) == 0 }
is_power_of_two_i64 :: proc(i: i64) -> bool { return i > 0 && (i & (i-1)) == 0 }
is_power_of_two_uint :: proc(i: uint) -> bool { return i > 0 && (i & (i-1)) == 0 }
is_power_of_two_int :: proc(i: int) -> bool { return i > 0 && (i & (i-1)) == 0 }
@(require_results)
is_power_of_two_u8 :: proc "contextless" (i: u8) -> bool { return i > 0 && (i & (i-1)) == 0 }
@(require_results)
is_power_of_two_i8 :: proc "contextless" (i: i8) -> bool { return i > 0 && (i & (i-1)) == 0 }
@(require_results)
is_power_of_two_u16 :: proc "contextless" (i: u16) -> bool { return i > 0 && (i & (i-1)) == 0 }
@(require_results)
is_power_of_two_i16 :: proc "contextless" (i: i16) -> bool { return i > 0 && (i & (i-1)) == 0 }
@(require_results)
is_power_of_two_u32 :: proc "contextless" (i: u32) -> bool { return i > 0 && (i & (i-1)) == 0 }
@(require_results)
is_power_of_two_i32 :: proc "contextless" (i: i32) -> bool { return i > 0 && (i & (i-1)) == 0 }
@(require_results)
is_power_of_two_u64 :: proc "contextless" (i: u64) -> bool { return i > 0 && (i & (i-1)) == 0 }
@(require_results)
is_power_of_two_i64 :: proc "contextless" (i: i64) -> bool { return i > 0 && (i & (i-1)) == 0 }
@(require_results)
is_power_of_two_uint :: proc "contextless" (i: uint) -> bool { return i > 0 && (i & (i-1)) == 0 }
@(require_results)
is_power_of_two_int :: proc "contextless" (i: int) -> bool { return i > 0 && (i & (i-1)) == 0 }
is_power_of_two :: proc{
is_power_of_two_u8, is_power_of_two_i8,
@@ -320,44 +373,56 @@ len_u8_table := [256]u8{
}
bitfield_extract_u8 :: proc(value: u8, offset, bits: uint) -> u8 { return (value >> offset) & u8(1<<bits - 1) }
bitfield_extract_u16 :: proc(value: u16, offset, bits: uint) -> u16 { return (value >> offset) & u16(1<<bits - 1) }
bitfield_extract_u32 :: proc(value: u32, offset, bits: uint) -> u32 { return (value >> offset) & u32(1<<bits - 1) }
bitfield_extract_u64 :: proc(value: u64, offset, bits: uint) -> u64 { return (value >> offset) & u64(1<<bits - 1) }
bitfield_extract_u128 :: proc(value: u128, offset, bits: uint) -> u128 { return (value >> offset) & u128(1<<bits - 1) }
bitfield_extract_uint :: proc(value: uint, offset, bits: uint) -> uint { return (value >> offset) & uint(1<<bits - 1) }
@(require_results)
bitfield_extract_u8 :: proc "contextless" (value: u8, offset, bits: uint) -> u8 { return (value >> offset) & u8(1<<bits - 1) }
@(require_results)
bitfield_extract_u16 :: proc "contextless" (value: u16, offset, bits: uint) -> u16 { return (value >> offset) & u16(1<<bits - 1) }
@(require_results)
bitfield_extract_u32 :: proc "contextless" (value: u32, offset, bits: uint) -> u32 { return (value >> offset) & u32(1<<bits - 1) }
@(require_results)
bitfield_extract_u64 :: proc "contextless" (value: u64, offset, bits: uint) -> u64 { return (value >> offset) & u64(1<<bits - 1) }
@(require_results)
bitfield_extract_u128 :: proc "contextless" (value: u128, offset, bits: uint) -> u128 { return (value >> offset) & u128(1<<bits - 1) }
@(require_results)
bitfield_extract_uint :: proc "contextless" (value: uint, offset, bits: uint) -> uint { return (value >> offset) & uint(1<<bits - 1) }
bitfield_extract_i8 :: proc(value: i8, offset, bits: uint) -> i8 {
@(require_results)
bitfield_extract_i8 :: proc "contextless" (value: i8, offset, bits: uint) -> i8 {
v := (u8(value) >> offset) & u8(1<<bits - 1)
m := u8(1<<(bits-1))
r := (v~m) - m
return i8(r)
}
bitfield_extract_i16 :: proc(value: i16, offset, bits: uint) -> i16 {
@(require_results)
bitfield_extract_i16 :: proc "contextless" (value: i16, offset, bits: uint) -> i16 {
v := (u16(value) >> offset) & u16(1<<bits - 1)
m := u16(1<<(bits-1))
r := (v~m) - m
return i16(r)
}
bitfield_extract_i32 :: proc(value: i32, offset, bits: uint) -> i32 {
@(require_results)
bitfield_extract_i32 :: proc "contextless" (value: i32, offset, bits: uint) -> i32 {
v := (u32(value) >> offset) & u32(1<<bits - 1)
m := u32(1<<(bits-1))
r := (v~m) - m
return i32(r)
}
bitfield_extract_i64 :: proc(value: i64, offset, bits: uint) -> i64 {
@(require_results)
bitfield_extract_i64 :: proc "contextless" (value: i64, offset, bits: uint) -> i64 {
v := (u64(value) >> offset) & u64(1<<bits - 1)
m := u64(1<<(bits-1))
r := (v~m) - m
return i64(r)
}
bitfield_extract_i128 :: proc(value: i128, offset, bits: uint) -> i128 {
@(require_results)
bitfield_extract_i128 :: proc "contextless" (value: i128, offset, bits: uint) -> i128 {
v := (u128(value) >> offset) & u128(1<<bits - 1)
m := u128(1<<(bits-1))
r := (v~m) - m
return i128(r)
}
bitfield_extract_int :: proc(value: int, offset, bits: uint) -> int {
@(require_results)
bitfield_extract_int :: proc "contextless" (value: int, offset, bits: uint) -> int {
v := (uint(value) >> offset) & uint(1<<bits - 1)
m := uint(1<<(bits-1))
r := (v~m) - m
@@ -381,52 +446,64 @@ bitfield_extract :: proc{
}
bitfield_insert_u8 :: proc(base, insert: u8, offset, bits: uint) -> u8 {
@(require_results)
bitfield_insert_u8 :: proc "contextless" (base, insert: u8, offset, bits: uint) -> u8 {
mask := u8(1<<bits - 1)
return (base &~ (mask<<offset)) | ((insert&mask) << offset)
}
bitfield_insert_u16 :: proc(base, insert: u16, offset, bits: uint) -> u16 {
@(require_results)
bitfield_insert_u16 :: proc "contextless" (base, insert: u16, offset, bits: uint) -> u16 {
mask := u16(1<<bits - 1)
return (base &~ (mask<<offset)) | ((insert&mask) << offset)
}
bitfield_insert_u32 :: proc(base, insert: u32, offset, bits: uint) -> u32 {
@(require_results)
bitfield_insert_u32 :: proc "contextless" (base, insert: u32, offset, bits: uint) -> u32 {
mask := u32(1<<bits - 1)
return (base &~ (mask<<offset)) | ((insert&mask) << offset)
}
bitfield_insert_u64 :: proc(base, insert: u64, offset, bits: uint) -> u64 {
@(require_results)
bitfield_insert_u64 :: proc "contextless" (base, insert: u64, offset, bits: uint) -> u64 {
mask := u64(1<<bits - 1)
return (base &~ (mask<<offset)) | ((insert&mask) << offset)
}
bitfield_insert_u128 :: proc(base, insert: u128, offset, bits: uint) -> u128 {
@(require_results)
bitfield_insert_u128 :: proc "contextless" (base, insert: u128, offset, bits: uint) -> u128 {
mask := u128(1<<bits - 1)
return (base &~ (mask<<offset)) | ((insert&mask) << offset)
}
bitfield_insert_uint :: proc(base, insert: uint, offset, bits: uint) -> uint {
@(require_results)
bitfield_insert_uint :: proc "contextless" (base, insert: uint, offset, bits: uint) -> uint {
mask := uint(1<<bits - 1)
return (base &~ (mask<<offset)) | ((insert&mask) << offset)
}
bitfield_insert_i8 :: proc(base, insert: i8, offset, bits: uint) -> i8 {
@(require_results)
bitfield_insert_i8 :: proc "contextless" (base, insert: i8, offset, bits: uint) -> i8 {
mask := i8(1<<bits - 1)
return (base &~ (mask<<offset)) | ((insert&mask) << offset)
}
bitfield_insert_i16 :: proc(base, insert: i16, offset, bits: uint) -> i16 {
@(require_results)
bitfield_insert_i16 :: proc "contextless" (base, insert: i16, offset, bits: uint) -> i16 {
mask := i16(1<<bits - 1)
return (base &~ (mask<<offset)) | ((insert&mask) << offset)
}
bitfield_insert_i32 :: proc(base, insert: i32, offset, bits: uint) -> i32 {
@(require_results)
bitfield_insert_i32 :: proc "contextless" (base, insert: i32, offset, bits: uint) -> i32 {
mask := i32(1<<bits - 1)
return (base &~ (mask<<offset)) | ((insert&mask) << offset)
}
bitfield_insert_i64 :: proc(base, insert: i64, offset, bits: uint) -> i64 {
@(require_results)
bitfield_insert_i64 :: proc "contextless" (base, insert: i64, offset, bits: uint) -> i64 {
mask := i64(1<<bits - 1)
return (base &~ (mask<<offset)) | ((insert&mask) << offset)
}
bitfield_insert_i128 :: proc(base, insert: i128, offset, bits: uint) -> i128 {
@(require_results)
bitfield_insert_i128 :: proc "contextless" (base, insert: i128, offset, bits: uint) -> i128 {
mask := i128(1<<bits - 1)
return (base &~ (mask<<offset)) | ((insert&mask) << offset)
}
bitfield_insert_int :: proc(base, insert: int, offset, bits: uint) -> int {
@(require_results)
bitfield_insert_int :: proc "contextless" (base, insert: int, offset, bits: uint) -> int {
mask := int(1<<bits - 1)
return (base &~ (mask<<offset)) | ((insert&mask) << offset)
}
+513
View File
@@ -0,0 +1,513 @@
package math_cmplx
import "core:builtin"
import "core:math"
// The original C code, the long comment, and the constants
// below are from http://netlib.sandia.gov/cephes/c9x-complex/clog.c.
// The go code is a simplified version of the original C.
//
// Cephes Math Library Release 2.8: June, 2000
// Copyright 1984, 1987, 1989, 1992, 2000 by Stephen L. Moshier
//
// The readme file at http://netlib.sandia.gov/cephes/ says:
// Some software in this archive may be from the book _Methods and
// Programs for Mathematical Functions_ (Prentice-Hall or Simon & Schuster
// International, 1989) or from the Cephes Mathematical Library, a
// commercial product. In either event, it is copyrighted by the author.
// What you see here may be used freely but it comes with no support or
// guarantee.
//
// The two known misprints in the book are repaired here in the
// source listings for the gamma function and the incomplete beta
// integral.
//
// Stephen L. Moshier
// moshier@na-net.ornl.gov
abs :: builtin.abs
conj :: builtin.conj
real :: builtin.real
imag :: builtin.imag
jmag :: builtin.jmag
kmag :: builtin.kmag
sin :: proc{
sin_complex128,
}
cos :: proc{
cos_complex128,
}
tan :: proc{
tan_complex128,
}
cot :: proc{
cot_complex128,
}
sinh :: proc{
sinh_complex128,
}
cosh :: proc{
cosh_complex128,
}
tanh :: proc{
tanh_complex128,
}
// sqrt returns the square root of x.
// The result r is chosen so that real(r) 0 and imag(r) has the same sign as imag(x).
sqrt :: proc{
sqrt_complex32,
sqrt_complex64,
sqrt_complex128,
}
ln :: proc{
ln_complex32,
ln_complex64,
ln_complex128,
}
log10 :: proc{
log10_complex32,
log10_complex64,
log10_complex128,
}
exp :: proc{
exp_complex32,
exp_complex64,
exp_complex128,
}
pow :: proc{
pow_complex32,
pow_complex64,
pow_complex128,
}
phase :: proc{
phase_complex32,
phase_complex64,
phase_complex128,
}
polar :: proc{
polar_complex32,
polar_complex64,
polar_complex128,
}
is_inf :: proc{
is_inf_complex32,
is_inf_complex64,
is_inf_complex128,
}
is_nan :: proc{
is_nan_complex32,
is_nan_complex64,
is_nan_complex128,
}
// sqrt_complex32 returns the square root of x.
// The result r is chosen so that real(r) 0 and imag(r) has the same sign as imag(x).
sqrt_complex32 :: proc "contextless" (x: complex32) -> complex32 {
return complex32(sqrt_complex128(complex128(x)))
}
// sqrt_complex64 returns the square root of x.
// The result r is chosen so that real(r) 0 and imag(r) has the same sign as imag(x).
sqrt_complex64 :: proc "contextless" (x: complex64) -> complex64 {
return complex64(sqrt_complex128(complex128(x)))
}
// sqrt_complex128 returns the square root of x.
// The result r is chosen so that real(r) 0 and imag(r) has the same sign as imag(x).
sqrt_complex128 :: proc "contextless" (x: complex128) -> complex128 {
// The original C code, the long comment, and the constants
// below are from http://netlib.sandia.gov/cephes/c9x-complex/clog.c.
// The go code is a simplified version of the original C.
//
// Cephes Math Library Release 2.8: June, 2000
// Copyright 1984, 1987, 1989, 1992, 2000 by Stephen L. Moshier
//
// The readme file at http://netlib.sandia.gov/cephes/ says:
// Some software in this archive may be from the book _Methods and
// Programs for Mathematical Functions_ (Prentice-Hall or Simon & Schuster
// International, 1989) or from the Cephes Mathematical Library, a
// commercial product. In either event, it is copyrighted by the author.
// What you see here may be used freely but it comes with no support or
// guarantee.
//
// The two known misprints in the book are repaired here in the
// source listings for the gamma function and the incomplete beta
// integral.
//
// Stephen L. Moshier
// moshier@na-net.ornl.gov
// Complex square root
//
// DESCRIPTION:
//
// If z = x + iy, r = |z|, then
//
// 1/2
// Re w = [ (r + x)/2 ] ,
//
// 1/2
// Im w = [ (r - x)/2 ] .
//
// Cancellation error in r-x or r+x is avoided by using the
// identity 2 Re w Im w = y.
//
// Note that -w is also a square root of z. The root chosen
// is always in the right half plane and Im w has the same sign as y.
//
// ACCURACY:
//
// Relative error:
// arithmetic domain # trials peak rms
// DEC -10,+10 25000 3.2e-17 9.6e-18
// IEEE -10,+10 1,000,000 2.9e-16 6.1e-17
if imag(x) == 0 {
// Ensure that imag(r) has the same sign as imag(x) for imag(x) == signed zero.
if real(x) == 0 {
return complex(0, imag(x))
}
if real(x) < 0 {
return complex(0, math.copy_sign(math.sqrt(-real(x)), imag(x)))
}
return complex(math.sqrt(real(x)), imag(x))
} else if math.is_inf(imag(x), 0) {
return complex(math.inf_f64(1.0), imag(x))
}
if real(x) == 0 {
if imag(x) < 0 {
r := math.sqrt(-0.5 * imag(x))
return complex(r, -r)
}
r := math.sqrt(0.5 * imag(x))
return complex(r, r)
}
a := real(x)
b := imag(x)
scale: f64
// Rescale to avoid internal overflow or underflow.
if abs(a) > 4 || abs(b) > 4 {
a *= 0.25
b *= 0.25
scale = 2
} else {
a *= 1.8014398509481984e16 // 2**54
b *= 1.8014398509481984e16
scale = 7.450580596923828125e-9 // 2**-27
}
r := math.hypot(a, b)
t: f64
if a > 0 {
t = math.sqrt(0.5*r + 0.5*a)
r = scale * abs((0.5*b)/t)
t *= scale
} else {
r = math.sqrt(0.5*r - 0.5*a)
t = scale * abs((0.5*b)/r)
r *= scale
}
if b < 0 {
return complex(t, -r)
}
return complex(t, r)
}
ln_complex32 :: proc "contextless" (x: complex32) -> complex32 {
return complex(math.ln(abs(x)), phase(x))
}
ln_complex64 :: proc "contextless" (x: complex64) -> complex64 {
return complex(math.ln(abs(x)), phase(x))
}
ln_complex128 :: proc "contextless" (x: complex128) -> complex128 {
return complex(math.ln(abs(x)), phase(x))
}
exp_complex32 :: proc "contextless" (x: complex32) -> complex32 {
switch re, im := real(x), imag(x); {
case math.is_inf(re, 0):
switch {
case re > 0 && im == 0:
return x
case math.is_inf(im, 0) || math.is_nan(im):
if re < 0 {
return complex(0, math.copy_sign(0, im))
} else {
return complex(math.inf_f64(1.0), math.nan_f64())
}
}
case math.is_nan(re):
if im == 0 {
return complex(math.nan_f16(), im)
}
}
r := math.exp(real(x))
s, c := math.sincos(imag(x))
return complex(r*c, r*s)
}
exp_complex64 :: proc "contextless" (x: complex64) -> complex64 {
switch re, im := real(x), imag(x); {
case math.is_inf(re, 0):
switch {
case re > 0 && im == 0:
return x
case math.is_inf(im, 0) || math.is_nan(im):
if re < 0 {
return complex(0, math.copy_sign(0, im))
} else {
return complex(math.inf_f64(1.0), math.nan_f64())
}
}
case math.is_nan(re):
if im == 0 {
return complex(math.nan_f32(), im)
}
}
r := math.exp(real(x))
s, c := math.sincos(imag(x))
return complex(r*c, r*s)
}
exp_complex128 :: proc "contextless" (x: complex128) -> complex128 {
switch re, im := real(x), imag(x); {
case math.is_inf(re, 0):
switch {
case re > 0 && im == 0:
return x
case math.is_inf(im, 0) || math.is_nan(im):
if re < 0 {
return complex(0, math.copy_sign(0, im))
} else {
return complex(math.inf_f64(1.0), math.nan_f64())
}
}
case math.is_nan(re):
if im == 0 {
return complex(math.nan_f64(), im)
}
}
r := math.exp(real(x))
s, c := math.sincos(imag(x))
return complex(r*c, r*s)
}
pow_complex32 :: proc "contextless" (x, y: complex32) -> complex32 {
if x == 0 { // Guaranteed also true for x == -0.
if is_nan(y) {
return nan_complex32()
}
r, i := real(y), imag(y)
switch {
case r == 0:
return 1
case r < 0:
if i == 0 {
return complex(math.inf_f16(1), 0)
}
return inf_complex32()
case r > 0:
return 0
}
unreachable()
}
modulus := abs(x)
if modulus == 0 {
return complex(0, 0)
}
r := math.pow(modulus, real(y))
arg := phase(x)
theta := real(y) * arg
if imag(y) != 0 {
r *= math.exp(-imag(y) * arg)
theta += imag(y) * math.ln(modulus)
}
s, c := math.sincos(theta)
return complex(r*c, r*s)
}
pow_complex64 :: proc "contextless" (x, y: complex64) -> complex64 {
if x == 0 { // Guaranteed also true for x == -0.
if is_nan(y) {
return nan_complex64()
}
r, i := real(y), imag(y)
switch {
case r == 0:
return 1
case r < 0:
if i == 0 {
return complex(math.inf_f32(1), 0)
}
return inf_complex64()
case r > 0:
return 0
}
unreachable()
}
modulus := abs(x)
if modulus == 0 {
return complex(0, 0)
}
r := math.pow(modulus, real(y))
arg := phase(x)
theta := real(y) * arg
if imag(y) != 0 {
r *= math.exp(-imag(y) * arg)
theta += imag(y) * math.ln(modulus)
}
s, c := math.sincos(theta)
return complex(r*c, r*s)
}
pow_complex128 :: proc "contextless" (x, y: complex128) -> complex128 {
if x == 0 { // Guaranteed also true for x == -0.
if is_nan(y) {
return nan_complex128()
}
r, i := real(y), imag(y)
switch {
case r == 0:
return 1
case r < 0:
if i == 0 {
return complex(math.inf_f64(1), 0)
}
return inf_complex128()
case r > 0:
return 0
}
unreachable()
}
modulus := abs(x)
if modulus == 0 {
return complex(0, 0)
}
r := math.pow(modulus, real(y))
arg := phase(x)
theta := real(y) * arg
if imag(y) != 0 {
r *= math.exp(-imag(y) * arg)
theta += imag(y) * math.ln(modulus)
}
s, c := math.sincos(theta)
return complex(r*c, r*s)
}
log10_complex32 :: proc "contextless" (x: complex32) -> complex32 {
return math.LN10*ln(x)
}
log10_complex64 :: proc "contextless" (x: complex64) -> complex64 {
return math.LN10*ln(x)
}
log10_complex128 :: proc "contextless" (x: complex128) -> complex128 {
return math.LN10*ln(x)
}
phase_complex32 :: proc "contextless" (x: complex32) -> f16 {
return math.atan2(imag(x), real(x))
}
phase_complex64 :: proc "contextless" (x: complex64) -> f32 {
return math.atan2(imag(x), real(x))
}
phase_complex128 :: proc "contextless" (x: complex128) -> f64 {
return math.atan2(imag(x), real(x))
}
rect_complex32 :: proc "contextless" (r, θ: f16) -> complex32 {
s, c := math.sincos(θ)
return complex(r*c, r*s)
}
rect_complex64 :: proc "contextless" (r, θ: f32) -> complex64 {
s, c := math.sincos(θ)
return complex(r*c, r*s)
}
rect_complex128 :: proc "contextless" (r, θ: f64) -> complex128 {
s, c := math.sincos(θ)
return complex(r*c, r*s)
}
polar_complex32 :: proc "contextless" (x: complex32) -> (r, θ: f16) {
return abs(x), phase(x)
}
polar_complex64 :: proc "contextless" (x: complex64) -> (r, θ: f32) {
return abs(x), phase(x)
}
polar_complex128 :: proc "contextless" (x: complex128) -> (r, θ: f64) {
return abs(x), phase(x)
}
nan_complex32 :: proc "contextless" () -> complex32 {
return complex(math.nan_f16(), math.nan_f16())
}
nan_complex64 :: proc "contextless" () -> complex64 {
return complex(math.nan_f32(), math.nan_f32())
}
nan_complex128 :: proc "contextless" () -> complex128 {
return complex(math.nan_f64(), math.nan_f64())
}
inf_complex32 :: proc "contextless" () -> complex32 {
inf := math.inf_f16(1)
return complex(inf, inf)
}
inf_complex64 :: proc "contextless" () -> complex64 {
inf := math.inf_f32(1)
return complex(inf, inf)
}
inf_complex128 :: proc "contextless" () -> complex128 {
inf := math.inf_f64(1)
return complex(inf, inf)
}
is_inf_complex32 :: proc "contextless" (x: complex32) -> bool {
return math.is_inf(real(x), 0) || math.is_inf(imag(x), 0)
}
is_inf_complex64 :: proc "contextless" (x: complex64) -> bool {
return math.is_inf(real(x), 0) || math.is_inf(imag(x), 0)
}
is_inf_complex128 :: proc "contextless" (x: complex128) -> bool {
return math.is_inf(real(x), 0) || math.is_inf(imag(x), 0)
}
is_nan_complex32 :: proc "contextless" (x: complex32) -> bool {
if math.is_inf(real(x), 0) || math.is_inf(imag(x), 0) {
return false
}
return math.is_nan(real(x)) || math.is_nan(imag(x))
}
is_nan_complex64 :: proc "contextless" (x: complex64) -> bool {
if math.is_inf(real(x), 0) || math.is_inf(imag(x), 0) {
return false
}
return math.is_nan(real(x)) || math.is_nan(imag(x))
}
is_nan_complex128 :: proc "contextless" (x: complex128) -> bool {
if math.is_inf(real(x), 0) || math.is_inf(imag(x), 0) {
return false
}
return math.is_nan(real(x)) || math.is_nan(imag(x))
}
+273
View File
@@ -0,0 +1,273 @@
package math_cmplx
import "core:builtin"
import "core:math"
// The original C code, the long comment, and the constants
// below are from http://netlib.sandia.gov/cephes/c9x-complex/clog.c.
// The go code is a simplified version of the original C.
//
// Cephes Math Library Release 2.8: June, 2000
// Copyright 1984, 1987, 1989, 1992, 2000 by Stephen L. Moshier
//
// The readme file at http://netlib.sandia.gov/cephes/ says:
// Some software in this archive may be from the book _Methods and
// Programs for Mathematical Functions_ (Prentice-Hall or Simon & Schuster
// International, 1989) or from the Cephes Mathematical Library, a
// commercial product. In either event, it is copyrighted by the author.
// What you see here may be used freely but it comes with no support or
// guarantee.
//
// The two known misprints in the book are repaired here in the
// source listings for the gamma function and the incomplete beta
// integral.
//
// Stephen L. Moshier
// moshier@na-net.ornl.gov
acos :: proc{
acos_complex32,
acos_complex64,
acos_complex128,
}
acosh :: proc{
acosh_complex32,
acosh_complex64,
acosh_complex128,
}
asin :: proc{
asin_complex32,
asin_complex64,
asin_complex128,
}
asinh :: proc{
asinh_complex32,
asinh_complex64,
asinh_complex128,
}
atan :: proc{
atan_complex32,
atan_complex64,
atan_complex128,
}
atanh :: proc{
atanh_complex32,
atanh_complex64,
atanh_complex128,
}
acos_complex32 :: proc "contextless" (x: complex32) -> complex32 {
w := asin(x)
return complex(math.PI/2 - real(w), -imag(w))
}
acos_complex64 :: proc "contextless" (x: complex64) -> complex64 {
w := asin(x)
return complex(math.PI/2 - real(w), -imag(w))
}
acos_complex128 :: proc "contextless" (x: complex128) -> complex128 {
w := asin(x)
return complex(math.PI/2 - real(w), -imag(w))
}
acosh_complex32 :: proc "contextless" (x: complex32) -> complex32 {
if x == 0 {
return complex(0, math.copy_sign(math.PI/2, imag(x)))
}
w := acos(x)
if imag(w) <= 0 {
return complex(-imag(w), real(w))
}
return complex(imag(w), -real(w))
}
acosh_complex64 :: proc "contextless" (x: complex64) -> complex64 {
if x == 0 {
return complex(0, math.copy_sign(math.PI/2, imag(x)))
}
w := acos(x)
if imag(w) <= 0 {
return complex(-imag(w), real(w))
}
return complex(imag(w), -real(w))
}
acosh_complex128 :: proc "contextless" (x: complex128) -> complex128 {
if x == 0 {
return complex(0, math.copy_sign(math.PI/2, imag(x)))
}
w := acos(x)
if imag(w) <= 0 {
return complex(-imag(w), real(w))
}
return complex(imag(w), -real(w))
}
asin_complex32 :: proc "contextless" (x: complex32) -> complex32 {
return complex32(asin_complex128(complex128(x)))
}
asin_complex64 :: proc "contextless" (x: complex64) -> complex64 {
return complex64(asin_complex128(complex128(x)))
}
asin_complex128 :: proc "contextless" (x: complex128) -> complex128 {
switch re, im := real(x), imag(x); {
case im == 0 && abs(re) <= 1:
return complex(math.asin(re), im)
case re == 0 && abs(im) <= 1:
return complex(re, math.asinh(im))
case math.is_nan(im):
switch {
case re == 0:
return complex(re, math.nan_f64())
case math.is_inf(re, 0):
return complex(math.nan_f64(), re)
case:
return nan_complex128()
}
case math.is_inf(im, 0):
switch {
case math.is_nan(re):
return x
case math.is_inf(re, 0):
return complex(math.copy_sign(math.PI/4, re), im)
case:
return complex(math.copy_sign(0, re), im)
}
case math.is_inf(re, 0):
return complex(math.copy_sign(math.PI/2, re), math.copy_sign(re, im))
}
ct := complex(-imag(x), real(x)) // i * x
xx := x * x
x1 := complex(1-real(xx), -imag(xx)) // 1 - x*x
x2 := sqrt(x1) // x2 = sqrt(1 - x*x)
w := ln(ct + x2)
return complex(imag(w), -real(w)) // -i * w
}
asinh_complex32 :: proc "contextless" (x: complex32) -> complex32 {
return complex32(asinh_complex128(complex128(x)))
}
asinh_complex64 :: proc "contextless" (x: complex64) -> complex64 {
return complex64(asinh_complex128(complex128(x)))
}
asinh_complex128 :: proc "contextless" (x: complex128) -> complex128 {
switch re, im := real(x), imag(x); {
case im == 0 && abs(re) <= 1:
return complex(math.asinh(re), im)
case re == 0 && abs(im) <= 1:
return complex(re, math.asin(im))
case math.is_inf(re, 0):
switch {
case math.is_inf(im, 0):
return complex(re, math.copy_sign(math.PI/4, im))
case math.is_nan(im):
return x
case:
return complex(re, math.copy_sign(0.0, im))
}
case math.is_nan(re):
switch {
case im == 0:
return x
case math.is_inf(im, 0):
return complex(im, re)
case:
return nan_complex128()
}
case math.is_inf(im, 0):
return complex(math.copy_sign(im, re), math.copy_sign(math.PI/2, im))
}
xx := x * x
x1 := complex(1+real(xx), imag(xx)) // 1 + x*x
return ln(x + sqrt(x1)) // log(x + sqrt(1 + x*x))
}
atan_complex32 :: proc "contextless" (x: complex32) -> complex32 {
return complex32(atan_complex128(complex128(x)))
}
atan_complex64 :: proc "contextless" (x: complex64) -> complex64 {
return complex64(atan_complex128(complex128(x)))
}
atan_complex128 :: proc "contextless" (x: complex128) -> complex128 {
// Complex circular arc tangent
//
// DESCRIPTION:
//
// If
// z = x + iy,
//
// then
// 1 ( 2x )
// Re w = - arctan(-----------) + k PI
// 2 ( 2 2)
// (1 - x - y )
//
// ( 2 2)
// 1 (x + (y+1) )
// Im w = - log(------------)
// 4 ( 2 2)
// (x + (y-1) )
//
// Where k is an arbitrary integer.
//
// catan(z) = -i catanh(iz).
//
// ACCURACY:
//
// Relative error:
// arithmetic domain # trials peak rms
// DEC -10,+10 5900 1.3e-16 7.8e-18
// IEEE -10,+10 30000 2.3e-15 8.5e-17
// The check catan( ctan(z) ) = z, with |x| and |y| < PI/2,
// had peak relative error 1.5e-16, rms relative error
// 2.9e-17. See also clog().
switch re, im := real(x), imag(x); {
case im == 0:
return complex(math.atan(re), im)
case re == 0 && abs(im) <= 1:
return complex(re, math.atanh(im))
case math.is_inf(im, 0) || math.is_inf(re, 0):
if math.is_nan(re) {
return complex(math.nan_f64(), math.copy_sign(0, im))
}
return complex(math.copy_sign(math.PI/2, re), math.copy_sign(0, im))
case math.is_nan(re) || math.is_nan(im):
return nan_complex128()
}
x2 := real(x) * real(x)
a := 1 - x2 - imag(x)*imag(x)
if a == 0 {
return nan_complex128()
}
t := 0.5 * math.atan2(2*real(x), a)
w := _reduce_pi_f64(t)
t = imag(x) - 1
b := x2 + t*t
if b == 0 {
return nan_complex128()
}
t = imag(x) + 1
c := (x2 + t*t) / b
return complex(w, 0.25*math.ln(c))
}
atanh_complex32 :: proc "contextless" (x: complex32) -> complex32 {
z := complex(-imag(x), real(x)) // z = i * x
z = atan(z)
return complex(imag(z), -real(z)) // z = -i * z
}
atanh_complex64 :: proc "contextless" (x: complex64) -> complex64 {
z := complex(-imag(x), real(x)) // z = i * x
z = atan(z)
return complex(imag(z), -real(z)) // z = -i * z
}
atanh_complex128 :: proc "contextless" (x: complex128) -> complex128 {
z := complex(-imag(x), real(x)) // z = i * x
z = atan(z)
return complex(imag(z), -real(z)) // z = -i * z
}
+409
View File
@@ -0,0 +1,409 @@
package math_cmplx
import "core:math"
import "core:math/bits"
// The original C code, the long comment, and the constants
// below are from http://netlib.sandia.gov/cephes/c9x-complex/clog.c.
// The go code is a simplified version of the original C.
//
// Cephes Math Library Release 2.8: June, 2000
// Copyright 1984, 1987, 1989, 1992, 2000 by Stephen L. Moshier
//
// The readme file at http://netlib.sandia.gov/cephes/ says:
// Some software in this archive may be from the book _Methods and
// Programs for Mathematical Functions_ (Prentice-Hall or Simon & Schuster
// International, 1989) or from the Cephes Mathematical Library, a
// commercial product. In either event, it is copyrighted by the author.
// What you see here may be used freely but it comes with no support or
// guarantee.
//
// The two known misprints in the book are repaired here in the
// source listings for the gamma function and the incomplete beta
// integral.
//
// Stephen L. Moshier
// moshier@na-net.ornl.gov
sin_complex128 :: proc "contextless" (x: complex128) -> complex128 {
// Complex circular sine
//
// DESCRIPTION:
//
// If
// z = x + iy,
//
// then
//
// w = sin x cosh y + i cos x sinh y.
//
// csin(z) = -i csinh(iz).
//
// ACCURACY:
//
// Relative error:
// arithmetic domain # trials peak rms
// DEC -10,+10 8400 5.3e-17 1.3e-17
// IEEE -10,+10 30000 3.8e-16 1.0e-16
// Also tested by csin(casin(z)) = z.
switch re, im := real(x), imag(x); {
case im == 0 && (math.is_inf(re, 0) || math.is_nan(re)):
return complex(math.nan_f64(), im)
case math.is_inf(im, 0):
switch {
case re == 0:
return x
case math.is_inf(re, 0) || math.is_nan(re):
return complex(math.nan_f64(), im)
}
case re == 0 && math.is_nan(im):
return x
}
s, c := math.sincos(real(x))
sh, ch := _sinhcosh_f64(imag(x))
return complex(s*ch, c*sh)
}
cos_complex128 :: proc "contextless" (x: complex128) -> complex128 {
// Complex circular cosine
//
// DESCRIPTION:
//
// If
// z = x + iy,
//
// then
//
// w = cos x cosh y - i sin x sinh y.
//
// ACCURACY:
//
// Relative error:
// arithmetic domain # trials peak rms
// DEC -10,+10 8400 4.5e-17 1.3e-17
// IEEE -10,+10 30000 3.8e-16 1.0e-16
switch re, im := real(x), imag(x); {
case im == 0 && (math.is_inf(re, 0) || math.is_nan(re)):
return complex(math.nan_f64(), -im*math.copy_sign(0, re))
case math.is_inf(im, 0):
switch {
case re == 0:
return complex(math.inf_f64(1), -re*math.copy_sign(0, im))
case math.is_inf(re, 0) || math.is_nan(re):
return complex(math.inf_f64(1), math.nan_f64())
}
case re == 0 && math.is_nan(im):
return complex(math.nan_f64(), 0)
}
s, c := math.sincos(real(x))
sh, ch := _sinhcosh_f64(imag(x))
return complex(c*ch, -s*sh)
}
sinh_complex128 :: proc "contextless" (x: complex128) -> complex128 {
// Complex hyperbolic sine
//
// DESCRIPTION:
//
// csinh z = (cexp(z) - cexp(-z))/2
// = sinh x * cos y + i cosh x * sin y .
//
// ACCURACY:
//
// Relative error:
// arithmetic domain # trials peak rms
// IEEE -10,+10 30000 3.1e-16 8.2e-17
switch re, im := real(x), imag(x); {
case re == 0 && (math.is_inf(im, 0) || math.is_nan(im)):
return complex(re, math.nan_f64())
case math.is_inf(re, 0):
switch {
case im == 0:
return complex(re, im)
case math.is_inf(im, 0) || math.is_nan(im):
return complex(re, math.nan_f64())
}
case im == 0 && math.is_nan(re):
return complex(math.nan_f64(), im)
}
s, c := math.sincos(imag(x))
sh, ch := _sinhcosh_f64(real(x))
return complex(c*sh, s*ch)
}
cosh_complex128 :: proc "contextless" (x: complex128) -> complex128 {
// Complex hyperbolic cosine
//
// DESCRIPTION:
//
// ccosh(z) = cosh x cos y + i sinh x sin y .
//
// ACCURACY:
//
// Relative error:
// arithmetic domain # trials peak rms
// IEEE -10,+10 30000 2.9e-16 8.1e-17
switch re, im := real(x), imag(x); {
case re == 0 && (math.is_inf(im, 0) || math.is_nan(im)):
return complex(math.nan_f64(), re*math.copy_sign(0, im))
case math.is_inf(re, 0):
switch {
case im == 0:
return complex(math.inf_f64(1), im*math.copy_sign(0, re))
case math.is_inf(im, 0) || math.is_nan(im):
return complex(math.inf_f64(1), math.nan_f64())
}
case im == 0 && math.is_nan(re):
return complex(math.nan_f64(), im)
}
s, c := math.sincos(imag(x))
sh, ch := _sinhcosh_f64(real(x))
return complex(c*ch, s*sh)
}
tan_complex128 :: proc "contextless" (x: complex128) -> complex128 {
// Complex circular tangent
//
// DESCRIPTION:
//
// If
// z = x + iy,
//
// then
//
// sin 2x + i sinh 2y
// w = --------------------.
// cos 2x + cosh 2y
//
// On the real axis the denominator is zero at odd multiples
// of PI/2. The denominator is evaluated by its Taylor
// series near these points.
//
// ctan(z) = -i ctanh(iz).
//
// ACCURACY:
//
// Relative error:
// arithmetic domain # trials peak rms
// DEC -10,+10 5200 7.1e-17 1.6e-17
// IEEE -10,+10 30000 7.2e-16 1.2e-16
// Also tested by ctan * ccot = 1 and catan(ctan(z)) = z.
switch re, im := real(x), imag(x); {
case math.is_inf(im, 0):
switch {
case math.is_inf(re, 0) || math.is_nan(re):
return complex(math.copy_sign(0, re), math.copy_sign(1, im))
}
return complex(math.copy_sign(0, math.sin(2*re)), math.copy_sign(1, im))
case re == 0 && math.is_nan(im):
return x
}
d := math.cos(2*real(x)) + math.cosh(2*imag(x))
if abs(d) < 0.25 {
d = _tan_series_f64(x)
}
if d == 0 {
return inf_complex128()
}
return complex(math.sin(2*real(x))/d, math.sinh(2*imag(x))/d)
}
tanh_complex128 :: proc "contextless" (x: complex128) -> complex128 {
switch re, im := real(x), imag(x); {
case math.is_inf(re, 0):
switch {
case math.is_inf(im, 0) || math.is_nan(im):
return complex(math.copy_sign(1, re), math.copy_sign(0, im))
}
return complex(math.copy_sign(1, re), math.copy_sign(0, math.sin(2*im)))
case im == 0 && math.is_nan(re):
return x
}
d := math.cosh(2*real(x)) + math.cos(2*imag(x))
if d == 0 {
return inf_complex128()
}
return complex(math.sinh(2*real(x))/d, math.sin(2*imag(x))/d)
}
cot_complex128 :: proc "contextless" (x: complex128) -> complex128 {
d := math.cosh(2*imag(x)) - math.cos(2*real(x))
if abs(d) < 0.25 {
d = _tan_series_f64(x)
}
if d == 0 {
return inf_complex128()
}
return complex(math.sin(2*real(x))/d, -math.sinh(2*imag(x))/d)
}
@(private="file")
_sinhcosh_f64 :: proc "contextless" (x: f64) -> (sh, ch: f64) {
if abs(x) <= 0.5 {
return math.sinh(x), math.cosh(x)
}
e := math.exp(x)
ei := 0.5 / e
e *= 0.5
return e - ei, e + ei
}
// taylor series of cosh(2y) - cos(2x)
@(private)
_tan_series_f64 :: proc "contextless" (z: complex128) -> f64 {
MACH_EPSILON :: 1.0 / (1 << 53)
x := abs(2 * real(z))
y := abs(2 * imag(z))
x = _reduce_pi_f64(x)
x, y = x * x, y * y
x2, y2 := 1.0, 1.0
f, rn, d := 1.0, 0.0, 0.0
for {
rn += 1
f *= rn
rn += 1
f *= rn
x2 *= x
y2 *= y
t := y2 + x2
t /= f
d += t
rn += 1
f *= rn
rn += 1
f *= rn
x2 *= x
y2 *= y
t = y2 - x2
t /= f
d += t
if !(abs(t/d) > MACH_EPSILON) { // don't use <=, because of floating point nonsense and NaN
break
}
}
return d
}
// _reduce_pi_f64 reduces the input argument x to the range (-PI/2, PI/2].
// x must be greater than or equal to 0. For small arguments it
// uses Cody-Waite reduction in 3 f64 parts based on:
// "Elementary Function Evaluation: Algorithms and Implementation"
// Jean-Michel Muller, 1997.
// For very large arguments it uses Payne-Hanek range reduction based on:
// "ARGUMENT REDUCTION FOR HUGE ARGUMENTS: Good to the Last Bit"
@(private)
_reduce_pi_f64 :: proc "contextless" (x: f64) -> f64 #no_bounds_check {
x := x
// REDUCE_THRESHOLD is the maximum value of x where the reduction using
// Cody-Waite reduction still gives accurate results. This threshold
// is set by t*PIn being representable as a f64 without error
// where t is given by t = floor(x * (1 / PI)) and PIn are the leading partial
// terms of PI. Since the leading terms, PI1 and PI2 below, have 30 and 32
// trailing zero bits respectively, t should have less than 30 significant bits.
// t < 1<<30 -> floor(x*(1/PI)+0.5) < 1<<30 -> x < (1<<30-1) * PI - 0.5
// So, conservatively we can take x < 1<<30.
REDUCE_THRESHOLD :: f64(1 << 30)
if abs(x) < REDUCE_THRESHOLD {
// Use Cody-Waite reduction in three parts.
// PI1, PI2 and PI3 comprise an extended precision value of PI
// such that PI ~= PI1 + PI2 + PI3. The parts are chosen so
// that PI1 and PI2 have an approximately equal number of trailing
// zero bits. This ensures that t*PI1 and t*PI2 are exact for
// large integer values of t. The full precision PI3 ensures the
// approximation of PI is accurate to 102 bits to handle cancellation
// during subtraction.
PI1 :: 0h400921fb40000000 // 3.141592502593994
PI2 :: 0h3e84442d00000000 // 1.5099578831723193e-07
PI3 :: 0h3d08469898cc5170 // 1.0780605716316238e-14
t := x / math.PI
t += 0.5
t = f64(i64(t)) // i64(t) = the multiple
return ((x - t*PI1) - t*PI2) - t*PI3
}
// Must apply Payne-Hanek range reduction
MASK :: 0x7FF
SHIFT :: 64 - 11 - 1
BIAS :: 1023
FRAC_MASK :: 1<<SHIFT - 1
// Extract out the integer and exponent such that,
// x = ix * 2 ** exp.
ix := transmute(u64)(x)
exp := int(ix>>SHIFT&MASK) - BIAS - SHIFT
ix &= FRAC_MASK
ix |= 1 << SHIFT
// bdpi is the binary digits of 1/PI as a u64 array,
// that is, 1/PI = SUM bdpi[i]*2^(-64*i).
// 19 64-bit digits give 1216 bits of precision
// to handle the largest possible f64 exponent.
@static bdpi := [?]u64{
0x0000000000000000,
0x517cc1b727220a94,
0xfe13abe8fa9a6ee0,
0x6db14acc9e21c820,
0xff28b1d5ef5de2b0,
0xdb92371d2126e970,
0x0324977504e8c90e,
0x7f0ef58e5894d39f,
0x74411afa975da242,
0x74ce38135a2fbf20,
0x9cc8eb1cc1a99cfa,
0x4e422fc5defc941d,
0x8ffc4bffef02cc07,
0xf79788c5ad05368f,
0xb69b3f6793e584db,
0xa7a31fb34f2ff516,
0xba93dd63f5f2f8bd,
0x9e839cfbc5294975,
0x35fdafd88fc6ae84,
0x2b0198237e3db5d5,
}
// Use the exponent to extract the 3 appropriate u64 digits from bdpi,
// B ~ (z0, z1, z2), such that the product leading digit has the exponent -64.
// Note, exp >= 50 since x >= REDUCE_THRESHOLD and exp < 971 for maximum f64.
digit, bitshift := uint(exp+64)/64, uint(exp+64)%64
z0 := (bdpi[digit] << bitshift) | (bdpi[digit+1] >> (64 - bitshift))
z1 := (bdpi[digit+1] << bitshift) | (bdpi[digit+2] >> (64 - bitshift))
z2 := (bdpi[digit+2] << bitshift) | (bdpi[digit+3] >> (64 - bitshift))
// Multiply mantissa by the digits and extract the upper two digits (hi, lo).
z2hi, _ := bits.mul(z2, ix)
z1hi, z1lo := bits.mul(z1, ix)
z0lo := z0 * ix
lo, c := bits.add(z1lo, z2hi, 0)
hi, _ := bits.add(z0lo, z1hi, c)
// Find the magnitude of the fraction.
lz := uint(bits.leading_zeros(hi))
e := u64(BIAS - (lz + 1))
// Clear implicit mantissa bit and shift into place.
hi = (hi << (lz + 1)) | (lo >> (64 - (lz + 1)))
hi >>= 64 - SHIFT
// Include the exponent and convert to a float.
hi |= e << SHIFT
x = transmute(f64)(hi)
// map to (-PI/2, PI/2]
if x > 0.5 {
x -= 1
}
return math.PI * x
}
+68 -33
View File
@@ -11,11 +11,13 @@ import "core:time"
// with additional enum based call
// Modeled after the parabola y = x^2
@(require_results)
quadratic_in :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T) {
return p * p
}
// Modeled after the parabola y = -x^2 + 2x
@(require_results)
quadratic_out :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T) {
return -(p * (p - 2))
}
@@ -23,6 +25,7 @@ quadratic_out :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(
// Modeled after the piecewise quadratic
// y = (1/2)((2x)^2) ; [0, 0.5)
// y = -(1/2)((2x-1)*(2x-3) - 1) ; [0.5, 1]
@(require_results)
quadratic_in_out :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T) {
if p < 0.5 {
return 2 * p * p
@@ -32,11 +35,13 @@ quadratic_in_out :: proc "contextless" (p: $T) -> T where intrinsics.type_is_flo
}
// Modeled after the cubic y = x^3
@(require_results)
cubic_in :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T) {
return p * p * p
}
// Modeled after the cubic y = (x - 1)^3 + 1
@(require_results)
cubic_out :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T) {
f := p - 1
return f * f * f + 1
@@ -45,6 +50,7 @@ cubic_out :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T) {
// Modeled after the piecewise cubic
// y = (1/2)((2x)^3) ; [0, 0.5)
// y = (1/2)((2x-2)^3 + 2) ; [0.5, 1]
@(require_results)
cubic_in_out :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T) {
if p < 0.5 {
return 4 * p * p * p
@@ -55,11 +61,13 @@ cubic_in_out :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T
}
// Modeled after the quartic x^4
@(require_results)
quartic_in :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T) {
return p * p * p * p
}
// Modeled after the quartic y = 1 - (x - 1)^4
@(require_results)
quartic_out :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T) {
f := p - 1
return f * f * f * (1 - p) + 1
@@ -68,6 +76,7 @@ quartic_out :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T)
// Modeled after the piecewise quartic
// y = (1/2)((2x)^4) ; [0, 0.5)
// y = -(1/2)((2x-2)^4 - 2) ; [0.5, 1]
@(require_results)
quartic_in_out :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T) {
if p < 0.5 {
return 8 * p * p * p * p
@@ -78,11 +87,13 @@ quartic_in_out :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float
}
// Modeled after the quintic y = x^5
@(require_results)
quintic_in :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T) {
return p * p * p * p * p
}
// Modeled after the quintic y = (x - 1)^5 + 1
@(require_results)
quintic_out :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T) {
f := p - 1
return f * f * f * f * f + 1
@@ -91,6 +102,7 @@ quintic_out :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T)
// Modeled after the piecewise quintic
// y = (1/2)((2x)^5) ; [0, 0.5)
// y = (1/2)((2x-2)^5 + 2) ; [0.5, 1]
@(require_results)
quintic_in_out :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T) {
if p < 0.5 {
return 16 * p * p * p * p * p
@@ -101,26 +113,31 @@ quintic_in_out :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float
}
// Modeled after quarter-cycle of sine wave
@(require_results)
sine_in :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T) {
return math.sin((p - 1) * PI_2) + 1
}
// Modeled after quarter-cycle of sine wave (different phase)
@(require_results)
sine_out :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T) {
return math.sin(p * PI_2)
}
// Modeled after half sine wave
@(require_results)
sine_in_out :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T) {
return 0.5 * (1 - math.cos(p * math.PI))
}
// Modeled after shifted quadrant IV of unit circle
@(require_results)
circular_in :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T) {
return 1 - math.sqrt(1 - (p * p))
}
// Modeled after shifted quadrant II of unit circle
@(require_results)
circular_out :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T) {
return math.sqrt((2 - p) * p)
}
@@ -128,6 +145,7 @@ circular_out :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T
// Modeled after the piecewise circular function
// y = (1/2)(1 - sqrt(1 - 4x^2)) ; [0, 0.5)
// y = (1/2)(sqrt(-(2x - 3)*(2x - 1)) + 1) ; [0.5, 1]
@(require_results)
circular_in_out :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T) {
if p < 0.5 {
return 0.5 * (1 - math.sqrt(1 - 4 * (p * p)))
@@ -137,11 +155,13 @@ circular_in_out :: proc "contextless" (p: $T) -> T where intrinsics.type_is_floa
}
// Modeled after the exponential function y = 2^(10(x - 1))
@(require_results)
exponential_in :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T) {
return p == 0.0 ? p : math.pow(2, 10 * (p - 1))
}
// Modeled after the exponential function y = -2^(-10x) + 1
@(require_results)
exponential_out :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T) {
return p == 1.0 ? p : 1 - math.pow(2, -10 * p)
}
@@ -149,6 +169,7 @@ exponential_out :: proc "contextless" (p: $T) -> T where intrinsics.type_is_floa
// Modeled after the piecewise exponential
// y = (1/2)2^(10(2x - 1)) ; [0,0.5)
// y = -(1/2)*2^(-10(2x - 1))) + 1 ; [0.5,1]
@(require_results)
exponential_in_out :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T) {
if p == 0.0 || p == 1.0 {
return p
@@ -162,11 +183,13 @@ exponential_in_out :: proc "contextless" (p: $T) -> T where intrinsics.type_is_f
}
// Modeled after the damped sine wave y = sin(13pi/2*x)*pow(2, 10 * (x - 1))
@(require_results)
elastic_in :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T) {
return math.sin(13 * PI_2 * p) * math.pow(2, 10 * (p - 1))
}
// Modeled after the damped sine wave y = sin(-13pi/2*(x + 1))*pow(2, -10x) + 1
@(require_results)
elastic_out :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T) {
return math.sin(-13 * PI_2 * (p + 1)) * math.pow(2, -10 * p) + 1
}
@@ -174,6 +197,7 @@ elastic_out :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T)
// Modeled after the piecewise exponentially-damped sine wave:
// y = (1/2)*sin(13pi/2*(2*x))*pow(2, 10 * ((2*x) - 1)) ; [0,0.5)
// y = (1/2)*(sin(-13pi/2*((2x-1)+1))*pow(2,-10(2*x-1)) + 2) ; [0.5, 1]
@(require_results)
elastic_in_out :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T) {
if p < 0.5 {
return 0.5 * math.sin(13 * PI_2 * (2 * p)) * math.pow(2, 10 * ((2 * p) - 1))
@@ -183,11 +207,13 @@ elastic_in_out :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float
}
// Modeled after the overshooting cubic y = x^3-x*sin(x*pi)
@(require_results)
back_in :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T) {
return p * p * p - p * math.sin(p * math.PI)
}
// Modeled after overshooting cubic y = 1-((1-x)^3-(1-x)*sin((1-x)*pi))
@(require_results)
back_out :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T) {
f := 1 - p
return 1 - (f * f * f - f * math.sin(f * math.PI))
@@ -196,6 +222,7 @@ back_out :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T) {
// Modeled after the piecewise overshooting cubic function:
// y = (1/2)*((2x)^3-(2x)*sin(2*x*pi)) ; [0, 0.5)
// y = (1/2)*(1-((1-x)^3-(1-x)*sin((1-x)*pi))+1) ; [0.5, 1]
@(require_results)
back_in_out :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T) {
if p < 0.5 {
f := 2 * p
@@ -206,10 +233,12 @@ back_in_out :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T)
}
}
@(require_results)
bounce_in :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T) {
return 1 - bounce_out(1 - p)
}
@(require_results)
bounce_out :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T) {
if p < 4/11.0 {
return (121 * p * p)/16.0
@@ -222,6 +251,7 @@ bounce_out :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T)
}
}
@(require_results)
bounce_in_out :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T) {
if p < 0.5 {
return 0.5 * bounce_in(p*2)
@@ -276,50 +306,51 @@ Ease :: enum {
Bounce_In_Out,
}
@(require_results)
ease :: proc "contextless" (type: Ease, p: $T) -> T
where intrinsics.type_is_float(T) {
switch type {
case .Linear: return p
case .Quadratic_In: return quadratic_in(p)
case .Quadratic_Out: return quadratic_out(p)
case .Quadratic_In_Out: return quadratic_in_out(p)
case .Linear: return p
case .Cubic_In: return cubic_in(p)
case .Cubic_Out: return cubic_out(p)
case .Cubic_In_Out: return cubic_in_out(p)
case .Quadratic_In: return quadratic_in(p)
case .Quadratic_Out: return quadratic_out(p)
case .Quadratic_In_Out: return quadratic_in_out(p)
case .Quartic_In: return quartic_in(p)
case .Quartic_Out: return quartic_out(p)
case .Quartic_In_Out: return quartic_in_out(p)
case .Cubic_In: return cubic_in(p)
case .Cubic_Out: return cubic_out(p)
case .Cubic_In_Out: return cubic_in_out(p)
case .Quintic_In: return quintic_in(p)
case .Quintic_Out: return quintic_out(p)
case .Quintic_In_Out: return quintic_in_out(p)
case .Quartic_In: return quartic_in(p)
case .Quartic_Out: return quartic_out(p)
case .Quartic_In_Out: return quartic_in_out(p)
case .Sine_In: return sine_in(p)
case .Sine_Out: return sine_out(p)
case .Sine_In_Out: return sine_in_out(p)
case .Quintic_In: return quintic_in(p)
case .Quintic_Out: return quintic_out(p)
case .Quintic_In_Out: return quintic_in_out(p)
case .Circular_In: return circular_in(p)
case .Circular_Out: return circular_out(p)
case .Circular_In_Out: return circular_in_out(p)
case .Sine_In: return sine_in(p)
case .Sine_Out: return sine_out(p)
case .Sine_In_Out: return sine_in_out(p)
case .Exponential_In: return exponential_in(p)
case .Exponential_Out: return exponential_out(p)
case .Exponential_In_Out: return exponential_in_out(p)
case .Circular_In: return circular_in(p)
case .Circular_Out: return circular_out(p)
case .Circular_In_Out: return circular_in_out(p)
case .Elastic_In: return elastic_in(p)
case .Elastic_Out: return elastic_out(p)
case .Elastic_In_Out: return elastic_in_out(p)
case .Exponential_In: return exponential_in(p)
case .Exponential_Out: return exponential_out(p)
case .Exponential_In_Out: return exponential_in_out(p)
case .Back_In: return back_in(p)
case .Back_Out: return back_out(p)
case .Back_In_Out: return back_in_out(p)
case .Elastic_In: return elastic_in(p)
case .Elastic_Out: return elastic_out(p)
case .Elastic_In_Out: return elastic_in_out(p)
case .Bounce_In: return bounce_in(p)
case .Bounce_Out: return bounce_out(p)
case .Bounce_In_Out: return bounce_in_out(p)
case .Back_In: return back_in(p)
case .Back_Out: return back_out(p)
case .Back_In_Out: return back_in_out(p)
case .Bounce_In: return bounce_in(p)
case .Bounce_Out: return bounce_out(p)
case .Bounce_In_Out: return bounce_in_out(p)
}
// in case type was invalid
@@ -353,6 +384,7 @@ Flux_Tween :: struct($T: typeid) {
}
// init flux map to a float type and a wanted cap
@(require_results)
flux_init :: proc($T: typeid, value_capacity := 8) -> Flux_Map(T) where intrinsics.type_is_float(T) {
return {
values = make(map[^T]Flux_Tween(T), value_capacity),
@@ -374,6 +406,7 @@ flux_clear :: proc(flux: ^Flux_Map($T)) where intrinsics.type_is_float(T) {
// append / overwrite existing tween value to parameters
// rest is initialized in flux_tween_init, inside update
// return value can be used to set callbacks
@(require_results)
flux_to :: proc(
flux: ^Flux_Map($T),
value: ^T,
@@ -417,7 +450,7 @@ flux_tween_init :: proc(tween: ^Flux_Tween($T), duration: time.Duration) where i
flux_update :: proc(flux: ^Flux_Map($T), dt: f64) where intrinsics.type_is_float(T) {
clear(&flux.keys_to_be_deleted)
for key, tween in &flux.values {
for key, &tween in flux.values {
delay_remainder := f64(0)
// Update delay if necessary.
@@ -475,6 +508,7 @@ flux_update :: proc(flux: ^Flux_Map($T), dt: f64) where intrinsics.type_is_float
// stop a specific key inside the map
// returns true when it successfully removed the key
@(require_results)
flux_stop :: proc(flux: ^Flux_Map($T), key: ^T) -> bool where intrinsics.type_is_float(T) {
if key in flux.values {
delete_key(&flux.values, key)
@@ -486,6 +520,7 @@ flux_stop :: proc(flux: ^Flux_Map($T), key: ^T) -> bool where intrinsics.type_is
// returns the amount of time left for the tween animation, if the key exists in the map
// returns 0 if the tween doesnt exist on the map
@(require_results)
flux_tween_time_left :: proc(flux: Flux_Map($T), key: ^T) -> f64 {
if tween, ok := flux.values[key]; ok {
return ((1 - tween.progress) * tween.rate) + tween.delay
+11
View File
@@ -50,39 +50,48 @@ to_f64 :: proc(x: $T/Fixed($Backing, $Fraction_Width)) -> f64 {
}
@(require_results)
add :: proc(x, y: $T/Fixed) -> T {
return {x.i + y.i}
}
@(require_results)
sub :: proc(x, y: $T/Fixed) -> T {
return {x.i - y.i}
}
@(require_results)
mul :: proc(x, y: $T/Fixed($Backing, $Fraction_Width)) -> (z: T) {
z.i = intrinsics.fixed_point_mul(x.i, y.i, Fraction_Width)
return
}
@(require_results)
mul_sat :: proc(x, y: $T/Fixed($Backing, $Fraction_Width)) -> (z: T) {
z.i = intrinsics.fixed_point_mul_sat(x.i, y.i, Fraction_Width)
return
}
@(require_results)
div :: proc(x, y: $T/Fixed($Backing, $Fraction_Width)) -> (z: T) {
z.i = intrinsics.fixed_point_div(x.i, y.i, Fraction_Width)
return
}
@(require_results)
div_sat :: proc(x, y: $T/Fixed($Backing, $Fraction_Width)) -> (z: T) {
z.i = intrinsics.fixed_point_div_sat(x.i, y.i, Fraction_Width)
return
}
@(require_results)
floor :: proc(x: $T/Fixed($Backing, $Fraction_Width)) -> Backing {
return x.i >> Fraction_Width
}
@(require_results)
ceil :: proc(x: $T/Fixed($Backing, $Fraction_Width)) -> Backing {
Integer :: 8*size_of(Backing) - Fraction_Width
return (x.i + (1 << Integer-1)) >> Fraction_Width
}
@(require_results)
round :: proc(x: $T/Fixed($Backing, $Fraction_Width)) -> Backing {
Integer :: 8*size_of(Backing) - Fraction_Width
return (x.i + (1 << (Integer - 1))) >> Fraction_Width
@@ -90,6 +99,7 @@ round :: proc(x: $T/Fixed($Backing, $Fraction_Width)) -> Backing {
@(require_results)
append :: proc(dst: []byte, x: $T/Fixed($Backing, $Fraction_Width)) -> string {
x := x
buf: [48]byte
@@ -123,6 +133,7 @@ append :: proc(dst: []byte, x: $T/Fixed($Backing, $Fraction_Width)) -> string {
}
@(require_results)
to_string :: proc(x: $T/Fixed($Backing, $Fraction_Width), allocator := context.allocator) -> string {
buf: [48]byte
s := append(buf[:], x)
+124 -65
View File
@@ -3,7 +3,8 @@ package linalg
import "core:builtin"
import "core:math"
to_radians :: proc(degrees: $T) -> (out: T) where IS_NUMERIC(ELEM_TYPE(T)) {
@(require_results)
to_radians :: proc "contextless" (degrees: $T) -> (out: T) where IS_NUMERIC(ELEM_TYPE(T)) {
when IS_ARRAY(T) {
for i in 0..<len(T) {
out[i] = degrees[i] * RAD_PER_DEG
@@ -14,7 +15,8 @@ to_radians :: proc(degrees: $T) -> (out: T) where IS_NUMERIC(ELEM_TYPE(T)) {
return
}
to_degrees :: proc(radians: $T) -> (out: T) where IS_NUMERIC(ELEM_TYPE(T)) {
@(require_results)
to_degrees :: proc "contextless" (radians: $T) -> (out: T) where IS_NUMERIC(ELEM_TYPE(T)) {
when IS_ARRAY(T) {
for i in 0..<len(T) {
out[i] = radians[i] * DEG_PER_RAD
@@ -25,7 +27,8 @@ to_degrees :: proc(radians: $T) -> (out: T) where IS_NUMERIC(ELEM_TYPE(T)) {
return
}
min_double :: proc(a, b: $T) -> (out: T) where IS_NUMERIC(ELEM_TYPE(T)) {
@(require_results)
min_double :: proc "contextless" (a, b: $T) -> (out: T) where IS_NUMERIC(ELEM_TYPE(T)) {
when IS_ARRAY(T) {
for i in 0..<len(T) {
out[i] = builtin.min(a[i], b[i])
@@ -36,7 +39,8 @@ min_double :: proc(a, b: $T) -> (out: T) where IS_NUMERIC(ELEM_TYPE(T)) {
return
}
min_single :: proc(a: $T) -> (out: ELEM_TYPE(T)) where IS_NUMERIC(ELEM_TYPE(T)) {
@(require_results)
min_single :: proc "contextless" (a: $T) -> (out: ELEM_TYPE(T)) where IS_NUMERIC(ELEM_TYPE(T)) {
when IS_ARRAY(T) {
N :: len(T)
@@ -56,13 +60,15 @@ min_single :: proc(a: $T) -> (out: ELEM_TYPE(T)) where IS_NUMERIC(ELEM_TYPE(T))
return
}
min_triple :: proc(a, b, c: $T) -> T where IS_NUMERIC(ELEM_TYPE(T)) {
@(require_results)
min_triple :: proc "contextless" (a, b, c: $T) -> T where IS_NUMERIC(ELEM_TYPE(T)) {
return min_double(a, min_double(b, c))
}
min :: proc{min_single, min_double, min_triple}
max_double :: proc(a, b: $T) -> (out: T) where IS_NUMERIC(ELEM_TYPE(T)) {
@(require_results)
max_double :: proc "contextless" (a, b: $T) -> (out: T) where IS_NUMERIC(ELEM_TYPE(T)) {
when IS_ARRAY(T) {
for i in 0..<len(T) {
out[i] = builtin.max(a[i], b[i])
@@ -73,7 +79,8 @@ max_double :: proc(a, b: $T) -> (out: T) where IS_NUMERIC(ELEM_TYPE(T)) {
return
}
max_single :: proc(a: $T) -> (out: ELEM_TYPE(T)) where IS_NUMERIC(ELEM_TYPE(T)) {
@(require_results)
max_single :: proc "contextless" (a: $T) -> (out: ELEM_TYPE(T)) where IS_NUMERIC(ELEM_TYPE(T)) {
when IS_ARRAY(T) {
N :: len(T)
@@ -95,13 +102,15 @@ max_single :: proc(a: $T) -> (out: ELEM_TYPE(T)) where IS_NUMERIC(ELEM_TYPE(T))
return
}
max_triple :: proc(a, b, c: $T) -> T where IS_NUMERIC(ELEM_TYPE(T)) {
@(require_results)
max_triple :: proc "contextless" (a, b, c: $T) -> T where IS_NUMERIC(ELEM_TYPE(T)) {
return max_double(a, max_double(b, c))
}
max :: proc{max_single, max_double, max_triple}
abs :: proc(a: $T) -> (out: T) where IS_NUMERIC(ELEM_TYPE(T)) {
@(require_results)
abs :: proc "contextless" (a: $T) -> (out: T) where IS_NUMERIC(ELEM_TYPE(T)) {
when IS_ARRAY(T) {
for i in 0..<len(T) {
out[i] = auto_cast builtin.abs(a[i])
@@ -112,7 +121,8 @@ abs :: proc(a: $T) -> (out: T) where IS_NUMERIC(ELEM_TYPE(T)) {
return
}
sign :: proc(a: $T) -> (out: T) where IS_NUMERIC(ELEM_TYPE(T)) {
@(require_results)
sign :: proc "contextless" (a: $T) -> (out: T) where IS_NUMERIC(ELEM_TYPE(T)) {
when IS_ARRAY(T) {
for i in 0..<len(T) {
out[i] = #force_inline math.sign(a[i])
@@ -123,7 +133,8 @@ sign :: proc(a: $T) -> (out: T) where IS_NUMERIC(ELEM_TYPE(T)) {
return
}
clamp :: proc(x, a, b: $T) -> (out: T) where IS_NUMERIC(ELEM_TYPE(T)) {
@(require_results)
clamp :: proc "contextless" (x, a, b: $T) -> (out: T) where IS_NUMERIC(ELEM_TYPE(T)) {
when IS_ARRAY(T) {
for i in 0..<len(T) {
out[i] = builtin.clamp(x[i], a[i], b[i])
@@ -135,11 +146,13 @@ clamp :: proc(x, a, b: $T) -> (out: T) where IS_NUMERIC(ELEM_TYPE(T)) {
}
saturate :: proc(x: $T) -> T where IS_FLOAT(ELEM_TYPE(T)) {
@(require_results)
saturate :: proc "contextless" (x: $T) -> T where IS_FLOAT(ELEM_TYPE(T)) {
return clamp(x, 0.0, 1.0)
}
lerp :: proc(a, b, t: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
@(require_results)
lerp :: proc "contextless" (a, b, t: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
when IS_ARRAY(T) {
for i in 0..<len(T) {
out[i] = a[i]*(1-t[i]) + b[i]*t[i]
@@ -149,7 +162,8 @@ lerp :: proc(a, b, t: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
}
return
}
mix :: proc(a, b, t: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
@(require_results)
mix :: proc "contextless" (a, b, t: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
when IS_ARRAY(T) {
for i in 0..<len(T) {
out[i] = a[i]*(1-t[i]) + b[i]*t[i]
@@ -160,11 +174,13 @@ mix :: proc(a, b, t: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
return
}
unlerp :: proc(a, b, x: $T) -> T where IS_FLOAT(ELEM_TYPE(T)) {
@(require_results)
unlerp :: proc "contextless" (a, b, x: $T) -> T where IS_FLOAT(ELEM_TYPE(T)) {
return (x - a) / (b - a)
}
step :: proc(e, x: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
@(require_results)
step :: proc "contextless" (e, x: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
when IS_ARRAY(T) {
for i in 0..<len(T) {
out[i] = x[i] < e[i] ? 0.0 : 1.0
@@ -175,18 +191,21 @@ step :: proc(e, x: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
return
}
smoothstep :: proc(e0, e1, x: $T) -> T where IS_FLOAT(ELEM_TYPE(T)) {
@(require_results)
smoothstep :: proc "contextless" (e0, e1, x: $T) -> T where IS_FLOAT(ELEM_TYPE(T)) {
t := saturate(unlerp(e0, e1, x))
return t * t * (3.0 - 2.0 * t)
}
smootherstep :: proc(e0, e1, x: $T) -> T where IS_FLOAT(ELEM_TYPE(T)) {
@(require_results)
smootherstep :: proc "contextless" (e0, e1, x: $T) -> T where IS_FLOAT(ELEM_TYPE(T)) {
t := saturate(unlerp(e0, e1, x))
return t * t * t * (t * (6*t - 15) + 10)
}
sqrt :: proc(x: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
@(require_results)
sqrt :: proc "contextless" (x: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
when IS_ARRAY(T) {
for i in 0..<len(T) {
out[i] = math.sqrt(x[i])
@@ -197,7 +216,8 @@ sqrt :: proc(x: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
return
}
inverse_sqrt :: proc(x: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
@(require_results)
inverse_sqrt :: proc "contextless" (x: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
when IS_ARRAY(T) {
for i in 0..<len(T) {
out[i] = 1.0/math.sqrt(x[i])
@@ -208,7 +228,8 @@ inverse_sqrt :: proc(x: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
return
}
cos :: proc(x: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
@(require_results)
cos :: proc "contextless" (x: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
when IS_ARRAY(T) {
for i in 0..<len(T) {
out[i] = math.cos(x[i])
@@ -219,7 +240,8 @@ cos :: proc(x: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
return
}
sin :: proc(x: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
@(require_results)
sin :: proc "contextless" (x: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
when IS_ARRAY(T) {
for i in 0..<len(T) {
out[i] = math.sin(x[i])
@@ -230,7 +252,8 @@ sin :: proc(x: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
return
}
tan :: proc(x: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
@(require_results)
tan :: proc "contextless" (x: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
when IS_ARRAY(T) {
for i in 0..<len(T) {
out[i] = math.tan(x[i])
@@ -241,7 +264,8 @@ tan :: proc(x: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
return
}
acos :: proc(x: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
@(require_results)
acos :: proc "contextless" (x: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
when IS_ARRAY(T) {
for i in 0..<len(T) {
out[i] = math.acos(x[i])
@@ -252,7 +276,8 @@ acos :: proc(x: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
return
}
asin :: proc(x: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
@(require_results)
asin :: proc "contextless" (x: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
when IS_ARRAY(T) {
for i in 0..<len(T) {
out[i] = math.asin(x[i])
@@ -263,7 +288,8 @@ asin :: proc(x: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
return
}
atan :: proc(x: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
@(require_results)
atan :: proc "contextless" (x: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
when IS_ARRAY(T) {
for i in 0..<len(T) {
out[i] = math.atan(x[i])
@@ -273,7 +299,8 @@ atan :: proc(x: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
}
return
}
atan2 :: proc(y, x: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
@(require_results)
atan2 :: proc "contextless" (y, x: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
when IS_ARRAY(T) {
for i in 0..<len(T) {
out[i] = math.atan2(y[i], x[i])
@@ -285,7 +312,8 @@ atan2 :: proc(y, x: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
}
ln :: proc(x: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
@(require_results)
ln :: proc "contextless" (x: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
when IS_ARRAY(T) {
for i in 0..<len(T) {
out[i] = math.ln(x[i])
@@ -296,7 +324,8 @@ ln :: proc(x: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
return
}
log2 :: proc(x: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
@(require_results)
log2 :: proc "contextless" (x: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
when IS_ARRAY(T) {
for i in 0..<len(T) {
out[i] = INVLN2 * math.ln(x[i])
@@ -307,7 +336,8 @@ log2 :: proc(x: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
return
}
log10 :: proc(x: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
@(require_results)
log10 :: proc "contextless" (x: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
when IS_ARRAY(T) {
for i in 0..<len(T) {
out[i] = INVLN10 * math.ln(x[i])
@@ -318,7 +348,8 @@ log10 :: proc(x: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
return
}
log :: proc(x, b: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
@(require_results)
log :: proc "contextless" (x, b: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
when IS_ARRAY(T) {
for i in 0..<len(T) {
out[i] = math.ln(x[i]) / math.ln(cast(ELEM_TYPE(T))b[i])
@@ -329,7 +360,8 @@ log :: proc(x, b: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
return
}
exp :: proc(x: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
@(require_results)
exp :: proc "contextless" (x: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
when IS_ARRAY(T) {
for i in 0..<len(T) {
out[i] = math.exp(x[i])
@@ -340,7 +372,8 @@ exp :: proc(x: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
return
}
exp2 :: proc(x: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
@(require_results)
exp2 :: proc "contextless" (x: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
when IS_ARRAY(T) {
for i in 0..<len(T) {
out[i] = math.exp(LN2 * x[i])
@@ -351,7 +384,8 @@ exp2 :: proc(x: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
return
}
exp10 :: proc(x: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
@(require_results)
exp10 :: proc "contextless" (x: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
when IS_ARRAY(T) {
for i in 0..<len(T) {
out[i] = math.exp(LN10 * x[i])
@@ -362,7 +396,8 @@ exp10 :: proc(x: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
return
}
pow :: proc(x, e: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
@(require_results)
pow :: proc "contextless" (x, e: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
when IS_ARRAY(T) {
for i in 0..<len(T) {
out[i] = math.pow(x[i], e[i])
@@ -374,7 +409,8 @@ pow :: proc(x, e: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
}
ceil :: proc(x: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
@(require_results)
ceil :: proc "contextless" (x: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
when IS_ARRAY(T) {
for i in 0..<len(T) {
out[i] = #force_inline math.ceil(x[i])
@@ -385,7 +421,8 @@ ceil :: proc(x: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
return
}
floor :: proc(x: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
@(require_results)
floor :: proc "contextless" (x: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
when IS_ARRAY(T) {
for i in 0..<len(T) {
out[i] = #force_inline math.floor(x[i])
@@ -396,7 +433,8 @@ floor :: proc(x: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
return
}
round :: proc(x: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
@(require_results)
round :: proc "contextless" (x: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
when IS_ARRAY(T) {
for i in 0..<len(T) {
out[i] = #force_inline math.round(x[i])
@@ -407,30 +445,36 @@ round :: proc(x: $T) -> (out: T) where IS_FLOAT(ELEM_TYPE(T)) {
return
}
fract :: proc(x: $T) -> T where IS_FLOAT(ELEM_TYPE(T)) {
@(require_results)
fract :: proc "contextless" (x: $T) -> T where IS_FLOAT(ELEM_TYPE(T)) {
f := #force_inline floor(x)
return x - f
}
mod :: proc(x, m: $T) -> T where IS_FLOAT(ELEM_TYPE(T)) {
@(require_results)
mod :: proc "contextless" (x, m: $T) -> T where IS_FLOAT(ELEM_TYPE(T)) {
f := #force_inline floor(x / m)
return x - f * m
}
face_forward :: proc(N, I, N_ref: $T) -> (out: T) where IS_ARRAY(T), IS_FLOAT(ELEM_TYPE(T)) {
@(require_results)
face_forward :: proc "contextless" (N, I, N_ref: $T) -> (out: T) where IS_ARRAY(T), IS_FLOAT(ELEM_TYPE(T)) {
return dot(N_ref, I) < 0 ? N : -N
}
distance :: proc(p0, p1: $V/[$N]$E) -> E where IS_NUMERIC(E) {
@(require_results)
distance :: proc "contextless" (p0, p1: $V/[$N]$E) -> E where IS_NUMERIC(E) {
return length(p1 - p0)
}
reflect :: proc(I, N: $T) -> (out: T) where IS_ARRAY(T), IS_FLOAT(ELEM_TYPE(T)) {
@(require_results)
reflect :: proc "contextless" (I, N: $T) -> (out: T) where IS_ARRAY(T), IS_FLOAT(ELEM_TYPE(T)) {
b := N * (2 * dot(N, I))
return I - b
}
refract :: proc(I, Normal: $V/[$N]$E, eta: E) -> (out: V) where IS_ARRAY(V), IS_FLOAT(ELEM_TYPE(V)) {
@(require_results)
refract :: proc "contextless" (I, Normal: $V/[$N]$E, eta: E) -> (out: V) where IS_ARRAY(V), IS_FLOAT(ELEM_TYPE(V)) {
dv := dot(Normal, I)
k := 1 - eta*eta * (1 - dv*dv)
a := I * eta
@@ -441,33 +485,39 @@ refract :: proc(I, Normal: $V/[$N]$E, eta: E) -> (out: V) where IS_ARRAY(V), IS_
is_nan_single :: proc(x: $T) -> bool where IS_FLOAT(T) {
@(require_results)
is_nan_single :: proc "contextless" (x: $T) -> bool where IS_FLOAT(T) {
return #force_inline math.is_nan(x)
}
is_nan_array :: proc(x: $A/[$N]$T) -> (out: [N]bool) where IS_FLOAT(T) {
@(require_results)
is_nan_array :: proc "contextless" (x: $A/[$N]$T) -> (out: [N]bool) where IS_FLOAT(T) {
for i in 0..<N {
out[i] = #force_inline is_nan(x[i])
}
return
}
is_inf_single :: proc(x: $T) -> bool where IS_FLOAT(T) {
@(require_results)
is_inf_single :: proc "contextless" (x: $T) -> bool where IS_FLOAT(T) {
return #force_inline math.is_inf(x)
}
is_inf_array :: proc(x: $A/[$N]$T) -> (out: [N]bool) where IS_FLOAT(T) {
@(require_results)
is_inf_array :: proc "contextless" (x: $A/[$N]$T) -> (out: [N]bool) where IS_FLOAT(T) {
for i in 0..<N {
out[i] = #force_inline is_inf(x[i])
}
return
}
classify_single :: proc(x: $T) -> math.Float_Class where IS_FLOAT(T) {
@(require_results)
classify_single :: proc "contextless" (x: $T) -> math.Float_Class where IS_FLOAT(T) {
return #force_inline math.classify(x)
}
classify_array :: proc(x: $A/[$N]$T) -> (out: [N]math.Float_Class) where IS_FLOAT(T) {
@(require_results)
classify_array :: proc "contextless" (x: $A/[$N]$T) -> (out: [N]math.Float_Class) where IS_FLOAT(T) {
for i in 0..<N {
out[i] = #force_inline classify_single(x[i])
}
@@ -479,44 +529,50 @@ is_inf :: proc{is_inf_single, is_inf_array}
classify :: proc{classify_single, classify_array}
less_than_single :: proc(x, y: $T) -> (out: bool) where !IS_ARRAY(T), IS_FLOAT(T) { return x < y }
less_than_equal_single :: proc(x, y: $T) -> (out: bool) where !IS_ARRAY(T), IS_FLOAT(T) { return x <= y }
greater_than_single :: proc(x, y: $T) -> (out: bool) where !IS_ARRAY(T), IS_FLOAT(T) { return x > y }
greater_than_equal_single :: proc(x, y: $T) -> (out: bool) where !IS_ARRAY(T), IS_FLOAT(T) { return x >= y }
equal_single :: proc(x, y: $T) -> (out: bool) where !IS_ARRAY(T), IS_FLOAT(T) { return x == y }
not_equal_single :: proc(x, y: $T) -> (out: bool) where !IS_ARRAY(T), IS_FLOAT(T) { return x != y }
@(require_results) less_than_single :: proc "contextless" (x, y: $T) -> (out: bool) where !IS_ARRAY(T), IS_FLOAT(T) { return x < y }
@(require_results) less_than_equal_single :: proc "contextless" (x, y: $T) -> (out: bool) where !IS_ARRAY(T), IS_FLOAT(T) { return x <= y }
@(require_results) greater_than_single :: proc "contextless" (x, y: $T) -> (out: bool) where !IS_ARRAY(T), IS_FLOAT(T) { return x > y }
@(require_results) greater_than_equal_single :: proc "contextless" (x, y: $T) -> (out: bool) where !IS_ARRAY(T), IS_FLOAT(T) { return x >= y }
@(require_results) equal_single :: proc "contextless" (x, y: $T) -> (out: bool) where !IS_ARRAY(T), IS_FLOAT(T) { return x == y }
@(require_results) not_equal_single :: proc "contextless" (x, y: $T) -> (out: bool) where !IS_ARRAY(T), IS_FLOAT(T) { return x != y }
less_than_array :: proc(x, y: $A/[$N]$T) -> (out: [N]bool) where IS_ARRAY(A), IS_FLOAT(ELEM_TYPE(A)) {
@(require_results)
less_than_array :: proc "contextless" (x, y: $A/[$N]$T) -> (out: [N]bool) where IS_ARRAY(A), IS_FLOAT(ELEM_TYPE(A)) {
for i in 0..<N {
out[i] = x[i] < y[i]
}
return
}
less_than_equal_array :: proc(x, y: $A/[$N]$T) -> (out: [N]bool) where IS_ARRAY(A), IS_FLOAT(ELEM_TYPE(A)) {
@(require_results)
less_than_equal_array :: proc "contextless" (x, y: $A/[$N]$T) -> (out: [N]bool) where IS_ARRAY(A), IS_FLOAT(ELEM_TYPE(A)) {
for i in 0..<N {
out[i] = x[i] <= y[i]
}
return
}
greater_than_array :: proc(x, y: $A/[$N]$T) -> (out: [N]bool) where IS_ARRAY(A), IS_FLOAT(ELEM_TYPE(A)) {
@(require_results)
greater_than_array :: proc "contextless" (x, y: $A/[$N]$T) -> (out: [N]bool) where IS_ARRAY(A), IS_FLOAT(ELEM_TYPE(A)) {
for i in 0..<N {
out[i] = x[i] > y[i]
}
return
}
greater_than_equal_array :: proc(x, y: $A/[$N]$T) -> (out: [N]bool) where IS_ARRAY(A), IS_FLOAT(ELEM_TYPE(A)) {
@(require_results)
greater_than_equal_array :: proc "contextless" (x, y: $A/[$N]$T) -> (out: [N]bool) where IS_ARRAY(A), IS_FLOAT(ELEM_TYPE(A)) {
for i in 0..<N {
out[i] = x[i] >= y[i]
}
return
}
equal_array :: proc(x, y: $A/[$N]$T) -> (out: [N]bool) where IS_ARRAY(A), IS_FLOAT(ELEM_TYPE(A)) {
@(require_results)
equal_array :: proc "contextless" (x, y: $A/[$N]$T) -> (out: [N]bool) where IS_ARRAY(A), IS_FLOAT(ELEM_TYPE(A)) {
for i in 0..<N {
out[i] = x[i] == y[i]
}
return
}
not_equal_array :: proc(x, y: $A/[$N]$T) -> (out: [N]bool) where IS_ARRAY(A), IS_FLOAT(ELEM_TYPE(A)) {
@(require_results)
not_equal_array :: proc "contextless" (x, y: $A/[$N]$T) -> (out: [N]bool) where IS_ARRAY(A), IS_FLOAT(ELEM_TYPE(A)) {
for i in 0..<N {
out[i] = x[i] != y[i]
}
@@ -530,7 +586,8 @@ greater_than_equal :: proc{greater_than_equal_single, greater_than_equal_array}
equal :: proc{equal_single, equal_array}
not_equal :: proc{not_equal_single, not_equal_array}
any :: proc(x: $A/[$N]bool) -> (out: bool) {
@(require_results)
any :: proc "contextless" (x: $A/[$N]bool) -> (out: bool) {
for e in x {
if e {
return true
@@ -538,7 +595,8 @@ any :: proc(x: $A/[$N]bool) -> (out: bool) {
}
return false
}
all :: proc(x: $A/[$N]bool) -> (out: bool) {
@(require_results)
all :: proc "contextless" (x: $A/[$N]bool) -> (out: bool) {
for e in x {
if !e {
return false
@@ -546,7 +604,8 @@ all :: proc(x: $A/[$N]bool) -> (out: bool) {
}
return true
}
not :: proc(x: $A/[$N]bool) -> (out: A) {
@(require_results)
not :: proc "contextless" (x: $A/[$N]bool) -> (out: A) {
for e, i in x {
out[i] = !e
}
+94 -56
View File
@@ -38,23 +38,28 @@ DEG_PER_RAD :: 360.0/TAU
@private ELEM_TYPE :: intrinsics.type_elem_type
scalar_dot :: proc(a, b: $T) -> T where IS_FLOAT(T), !IS_ARRAY(T) {
@(require_results)
scalar_dot :: proc "contextless" (a, b: $T) -> T where IS_FLOAT(T), !IS_ARRAY(T) {
return a * b
}
vector_dot :: proc(a, b: $T/[$N]$E) -> (c: E) where IS_NUMERIC(E) #no_bounds_check {
@(require_results)
vector_dot :: proc "contextless" (a, b: $T/[$N]$E) -> (c: E) where IS_NUMERIC(E) #no_bounds_check {
for i in 0..<N {
c += a[i] * b[i]
}
return
}
quaternion64_dot :: proc(a, b: $T/quaternion64) -> (c: f16) {
@(require_results)
quaternion64_dot :: proc "contextless" (a, b: $T/quaternion64) -> (c: f16) {
return a.w*a.w + a.x*b.x + a.y*b.y + a.z*b.z
}
quaternion128_dot :: proc(a, b: $T/quaternion128) -> (c: f32) {
@(require_results)
quaternion128_dot :: proc "contextless" (a, b: $T/quaternion128) -> (c: f32) {
return a.w*a.w + a.x*b.x + a.y*b.y + a.z*b.z
}
quaternion256_dot :: proc(a, b: $T/quaternion256) -> (c: f64) {
@(require_results)
quaternion256_dot :: proc "contextless" (a, b: $T/quaternion256) -> (c: f64) {
return a.w*a.w + a.x*b.x + a.y*b.y + a.z*b.z
}
@@ -63,27 +68,32 @@ dot :: proc{scalar_dot, vector_dot, quaternion64_dot, quaternion128_dot, quatern
inner_product :: dot
outer_product :: builtin.outer_product
quaternion_inverse :: proc(q: $Q) -> Q where IS_QUATERNION(Q) {
@(require_results)
quaternion_inverse :: proc "contextless" (q: $Q) -> Q where IS_QUATERNION(Q) {
return conj(q) * quaternion(1.0/dot(q, q), 0, 0, 0)
}
scalar_cross :: proc(a, b: $T) -> T where IS_FLOAT(T), !IS_ARRAY(T) {
@(require_results)
scalar_cross :: proc "contextless" (a, b: $T) -> T where IS_FLOAT(T), !IS_ARRAY(T) {
return a * b
}
vector_cross2 :: proc(a, b: $T/[2]$E) -> E where IS_NUMERIC(E) {
@(require_results)
vector_cross2 :: proc "contextless" (a, b: $T/[2]$E) -> E where IS_NUMERIC(E) {
return a[0]*b[1] - b[0]*a[1]
}
vector_cross3 :: proc(a, b: $T/[3]$E) -> (c: T) where IS_NUMERIC(E) {
@(require_results)
vector_cross3 :: proc "contextless" (a, b: $T/[3]$E) -> (c: T) where IS_NUMERIC(E) {
c[0] = a[1]*b[2] - b[1]*a[2]
c[1] = a[2]*b[0] - b[2]*a[0]
c[2] = a[0]*b[1] - b[0]*a[1]
return
}
quaternion_cross :: proc(q1, q2: $Q) -> (q3: Q) where IS_QUATERNION(Q) {
@(require_results)
quaternion_cross :: proc "contextless" (q1, q2: $Q) -> (q3: Q) where IS_QUATERNION(Q) {
q3.x = q1.w * q2.x + q1.x * q2.w + q1.y * q2.z - q1.z * q2.y
q3.y = q1.w * q2.y + q1.y * q2.w + q1.z * q2.x - q1.x * q2.z
q3.z = q1.w * q2.z + q1.z * q2.w + q1.x * q2.y - q1.y * q2.x
@@ -94,49 +104,59 @@ quaternion_cross :: proc(q1, q2: $Q) -> (q3: Q) where IS_QUATERNION(Q) {
vector_cross :: proc{scalar_cross, vector_cross2, vector_cross3}
cross :: proc{scalar_cross, vector_cross2, vector_cross3, quaternion_cross}
vector_normalize :: proc(v: $T/[$N]$E) -> T where IS_FLOAT(E) {
@(require_results)
vector_normalize :: proc "contextless" (v: $T/[$N]$E) -> T where IS_FLOAT(E) {
return v / length(v)
}
quaternion_normalize :: proc(q: $Q) -> Q where IS_QUATERNION(Q) {
@(require_results)
quaternion_normalize :: proc "contextless" (q: $Q) -> Q where IS_QUATERNION(Q) {
return q/abs(q)
}
normalize :: proc{vector_normalize, quaternion_normalize}
vector_normalize0 :: proc(v: $T/[$N]$E) -> T where IS_FLOAT(E) {
@(require_results)
vector_normalize0 :: proc "contextless" (v: $T/[$N]$E) -> T where IS_FLOAT(E) {
m := length(v)
return 0 if m == 0 else v/m
}
quaternion_normalize0 :: proc(q: $Q) -> Q where IS_QUATERNION(Q) {
@(require_results)
quaternion_normalize0 :: proc "contextless" (q: $Q) -> Q where IS_QUATERNION(Q) {
m := abs(q)
return 0 if m == 0 else q/m
}
normalize0 :: proc{vector_normalize0, quaternion_normalize0}
vector_length :: proc(v: $T/[$N]$E) -> E where IS_FLOAT(E) {
@(require_results)
vector_length :: proc "contextless" (v: $T/[$N]$E) -> E where IS_FLOAT(E) {
return math.sqrt(dot(v, v))
}
vector_length2 :: proc(v: $T/[$N]$E) -> E where IS_NUMERIC(E) {
@(require_results)
vector_length2 :: proc "contextless" (v: $T/[$N]$E) -> E where IS_NUMERIC(E) {
return dot(v, v)
}
quaternion_length :: proc(q: $Q) -> Q where IS_QUATERNION(Q) {
@(require_results)
quaternion_length :: proc "contextless" (q: $Q) -> Q where IS_QUATERNION(Q) {
return abs(q)
}
quaternion_length2 :: proc(q: $Q) -> Q where IS_QUATERNION(Q) {
@(require_results)
quaternion_length2 :: proc "contextless" (q: $Q) -> Q where IS_QUATERNION(Q) {
return dot(q, q)
}
scalar_triple_product :: proc(a, b, c: $T/[$N]$E) -> E where IS_NUMERIC(E) {
@(require_results)
scalar_triple_product :: proc "contextless" (a, b, c: $T/[$N]$E) -> E where IS_NUMERIC(E) {
// a . (b x c)
// b . (c x a)
// c . (a x b)
return dot(a, cross(b, c))
}
vector_triple_product :: proc(a, b, c: $T/[$N]$E) -> T where IS_NUMERIC(E) {
@(require_results)
vector_triple_product :: proc "contextless" (a, b, c: $T/[$N]$E) -> T where IS_NUMERIC(E) {
// a x (b x c)
// (a . c)b - (a . b)c
return cross(a, cross(b, c))
@@ -146,11 +166,13 @@ vector_triple_product :: proc(a, b, c: $T/[$N]$E) -> T where IS_NUMERIC(E) {
length :: proc{vector_length, quaternion_length}
length2 :: proc{vector_length2, quaternion_length2}
projection :: proc(x, normal: $T/[$N]$E) -> T where IS_NUMERIC(E) {
@(require_results)
projection :: proc "contextless" (x, normal: $T/[$N]$E) -> T where IS_NUMERIC(E) {
return dot(x, normal) / dot(normal, normal) * normal
}
identity :: proc($T: typeid/[$N][N]$E) -> (m: T) #no_bounds_check {
@(require_results)
identity :: proc "contextless" ($T: typeid/[$N][N]$E) -> (m: T) #no_bounds_check {
for i in 0..<N {
m[i][i] = E(1)
}
@@ -160,32 +182,38 @@ identity :: proc($T: typeid/[$N][N]$E) -> (m: T) #no_bounds_check {
trace :: builtin.matrix_trace
transpose :: builtin.transpose
matrix_mul :: proc(a, b: $M/matrix[$N, N]$E) -> (c: M)
@(require_results)
matrix_mul :: proc "contextless" (a, b: $M/matrix[$N, N]$E) -> (c: M)
where !IS_ARRAY(E), IS_NUMERIC(E) #no_bounds_check {
return a * b
}
matrix_comp_mul :: proc(a, b: $M/matrix[$I, $J]$E) -> (c: M)
@(require_results)
matrix_comp_mul :: proc "contextless" (a, b: $M/matrix[$I, $J]$E) -> (c: M)
where !IS_ARRAY(E), IS_NUMERIC(E) #no_bounds_check {
return hadamard_product(a, b)
}
matrix_mul_differ :: proc(a: $A/matrix[$I, $J]$E, b: $B/matrix[J, $K]E) -> (c: matrix[I, K]E)
@(require_results)
matrix_mul_differ :: proc "contextless" (a: $A/matrix[$I, $J]$E, b: $B/matrix[J, $K]E) -> (c: matrix[I, K]E)
where !IS_ARRAY(E), IS_NUMERIC(E), I != K #no_bounds_check {
return a * b
}
matrix_mul_vector :: proc(a: $A/matrix[$I, $J]$E, b: $B/[J]E) -> (c: B)
@(require_results)
matrix_mul_vector :: proc "contextless" (a: $A/matrix[$I, $J]$E, b: $B/[J]E) -> (c: B)
where !IS_ARRAY(E), IS_NUMERIC(E) #no_bounds_check {
return a * b
}
quaternion_mul_quaternion :: proc(q1, q2: $Q) -> Q where IS_QUATERNION(Q) {
@(require_results)
quaternion_mul_quaternion :: proc "contextless" (q1, q2: $Q) -> Q where IS_QUATERNION(Q) {
return q1 * q2
}
quaternion64_mul_vector3 :: proc(q: $Q/quaternion64, v: $V/[3]$F/f16) -> V {
@(require_results)
quaternion64_mul_vector3 :: proc "contextless" (q: $Q/quaternion64, v: $V/[3]$F/f16) -> V {
Raw_Quaternion :: struct {xyz: [3]f16, r: f16}
q := transmute(Raw_Quaternion)q
@@ -194,7 +222,8 @@ quaternion64_mul_vector3 :: proc(q: $Q/quaternion64, v: $V/[3]$F/f16) -> V {
t := cross(2*q.xyz, v)
return V(v + q.r*t + cross(q.xyz, t))
}
quaternion128_mul_vector3 :: proc(q: $Q/quaternion128, v: $V/[3]$F/f32) -> V {
@(require_results)
quaternion128_mul_vector3 :: proc "contextless" (q: $Q/quaternion128, v: $V/[3]$F/f32) -> V {
Raw_Quaternion :: struct {xyz: [3]f32, r: f32}
q := transmute(Raw_Quaternion)q
@@ -203,7 +232,8 @@ quaternion128_mul_vector3 :: proc(q: $Q/quaternion128, v: $V/[3]$F/f32) -> V {
t := cross(2*q.xyz, v)
return V(v + q.r*t + cross(q.xyz, t))
}
quaternion256_mul_vector3 :: proc(q: $Q/quaternion256, v: $V/[3]$F/f64) -> V {
@(require_results)
quaternion256_mul_vector3 :: proc "contextless" (q: $Q/quaternion256, v: $V/[3]$F/f64) -> V {
Raw_Quaternion :: struct {xyz: [3]f64, r: f64}
q := transmute(Raw_Quaternion)q
@@ -224,10 +254,12 @@ mul :: proc{
quaternion_mul_quaternion,
}
vector_to_ptr :: proc(v: ^$V/[$N]$E) -> ^E where IS_NUMERIC(E), N > 0 #no_bounds_check {
@(require_results)
vector_to_ptr :: proc "contextless" (v: ^$V/[$N]$E) -> ^E where IS_NUMERIC(E), N > 0 #no_bounds_check {
return &v[0]
}
matrix_to_ptr :: proc(m: ^$A/matrix[$I, $J]$E) -> ^E where IS_NUMERIC(E), I > 0, J > 0 #no_bounds_check {
@(require_results)
matrix_to_ptr :: proc "contextless" (m: ^$A/matrix[$I, $J]$E) -> ^E where IS_NUMERIC(E), I > 0, J > 0 #no_bounds_check {
return &m[0, 0]
}
@@ -239,7 +271,8 @@ to_ptr :: proc{vector_to_ptr, matrix_to_ptr}
// Splines
vector_slerp :: proc(x, y: $T/[$N]$E, a: E) -> T {
@(require_results)
vector_slerp :: proc "contextless" (x, y: $T/[$N]$E, a: E) -> T {
cos_alpha := dot(x, y)
alpha := math.acos(cos_alpha)
sin_alpha := math.sin(alpha)
@@ -250,7 +283,8 @@ vector_slerp :: proc(x, y: $T/[$N]$E, a: E) -> T {
return x * t1 + y * t2
}
catmull_rom :: proc(v1, v2, v3, v4: $T/[$N]$E, s: E) -> T {
@(require_results)
catmull_rom :: proc "contextless" (v1, v2, v3, v4: $T/[$N]$E, s: E) -> T {
s2 := s*s
s3 := s2*s
@@ -262,7 +296,8 @@ catmull_rom :: proc(v1, v2, v3, v4: $T/[$N]$E, s: E) -> T {
return (f1 * v1 + f2 * v2 + f3 * v3 + f4 * v4) * 0.5
}
hermite :: proc(v1, t1, v2, t2: $T/[$N]$E, s: E) -> T {
@(require_results)
hermite :: proc "contextless" (v1, t1, v2, t2: $T/[$N]$E, s: E) -> T {
s2 := s*s
s3 := s2*s
@@ -274,20 +309,23 @@ hermite :: proc(v1, t1, v2, t2: $T/[$N]$E, s: E) -> T {
return f1 * v1 + f2 * v2 + f3 * t1 + f4 * t2
}
cubic :: proc(v1, v2, v3, v4: $T/[$N]$E, s: E) -> T {
@(require_results)
cubic :: proc "contextless" (v1, v2, v3, v4: $T/[$N]$E, s: E) -> T {
return ((v1 * s + v2) * s + v3) * s + v4
}
array_cast :: proc(v: $A/[$N]$T, $Elem_Type: typeid) -> (w: [N]Elem_Type) #no_bounds_check {
@(require_results)
array_cast :: proc "contextless" (v: $A/[$N]$T, $Elem_Type: typeid) -> (w: [N]Elem_Type) #no_bounds_check {
for i in 0..<N {
w[i] = Elem_Type(v[i])
}
return
}
matrix_cast :: proc(v: $A/matrix[$M, $N]$T, $Elem_Type: typeid) -> (w: matrix[M, N]Elem_Type) #no_bounds_check {
@(require_results)
matrix_cast :: proc "contextless" (v: $A/matrix[$M, $N]$T, $Elem_Type: typeid) -> (w: matrix[M, N]Elem_Type) #no_bounds_check {
for j in 0..<N {
for i in 0..<M {
w[i, j] = Elem_Type(v[i, j])
@@ -296,24 +334,24 @@ matrix_cast :: proc(v: $A/matrix[$M, $N]$T, $Elem_Type: typeid) -> (w: matrix[M,
return
}
to_f32 :: #force_inline proc(v: $A/[$N]$T) -> [N]f32 { return array_cast(v, f32) }
to_f64 :: #force_inline proc(v: $A/[$N]$T) -> [N]f64 { return array_cast(v, f64) }
@(require_results) to_f32 :: #force_inline proc(v: $A/[$N]$T) -> [N]f32 { return array_cast(v, f32) }
@(require_results) to_f64 :: #force_inline proc(v: $A/[$N]$T) -> [N]f64 { return array_cast(v, f64) }
to_i8 :: #force_inline proc(v: $A/[$N]$T) -> [N]i8 { return array_cast(v, i8) }
to_i16 :: #force_inline proc(v: $A/[$N]$T) -> [N]i16 { return array_cast(v, i16) }
to_i32 :: #force_inline proc(v: $A/[$N]$T) -> [N]i32 { return array_cast(v, i32) }
to_i64 :: #force_inline proc(v: $A/[$N]$T) -> [N]i64 { return array_cast(v, i64) }
to_int :: #force_inline proc(v: $A/[$N]$T) -> [N]int { return array_cast(v, int) }
@(require_results) to_i8 :: #force_inline proc(v: $A/[$N]$T) -> [N]i8 { return array_cast(v, i8) }
@(require_results) to_i16 :: #force_inline proc(v: $A/[$N]$T) -> [N]i16 { return array_cast(v, i16) }
@(require_results) to_i32 :: #force_inline proc(v: $A/[$N]$T) -> [N]i32 { return array_cast(v, i32) }
@(require_results) to_i64 :: #force_inline proc(v: $A/[$N]$T) -> [N]i64 { return array_cast(v, i64) }
@(require_results) to_int :: #force_inline proc(v: $A/[$N]$T) -> [N]int { return array_cast(v, int) }
to_u8 :: #force_inline proc(v: $A/[$N]$T) -> [N]u8 { return array_cast(v, u8) }
to_u16 :: #force_inline proc(v: $A/[$N]$T) -> [N]u16 { return array_cast(v, u16) }
to_u32 :: #force_inline proc(v: $A/[$N]$T) -> [N]u32 { return array_cast(v, u32) }
to_u64 :: #force_inline proc(v: $A/[$N]$T) -> [N]u64 { return array_cast(v, u64) }
to_uint :: #force_inline proc(v: $A/[$N]$T) -> [N]uint { return array_cast(v, uint) }
@(require_results) to_u8 :: #force_inline proc(v: $A/[$N]$T) -> [N]u8 { return array_cast(v, u8) }
@(require_results) to_u16 :: #force_inline proc(v: $A/[$N]$T) -> [N]u16 { return array_cast(v, u16) }
@(require_results) to_u32 :: #force_inline proc(v: $A/[$N]$T) -> [N]u32 { return array_cast(v, u32) }
@(require_results) to_u64 :: #force_inline proc(v: $A/[$N]$T) -> [N]u64 { return array_cast(v, u64) }
@(require_results) to_uint :: #force_inline proc(v: $A/[$N]$T) -> [N]uint { return array_cast(v, uint) }
to_complex32 :: #force_inline proc(v: $A/[$N]$T) -> [N]complex32 { return array_cast(v, complex32) }
to_complex64 :: #force_inline proc(v: $A/[$N]$T) -> [N]complex64 { return array_cast(v, complex64) }
to_complex128 :: #force_inline proc(v: $A/[$N]$T) -> [N]complex128 { return array_cast(v, complex128) }
to_quaternion64 :: #force_inline proc(v: $A/[$N]$T) -> [N]quaternion64 { return array_cast(v, quaternion64) }
to_quaternion128 :: #force_inline proc(v: $A/[$N]$T) -> [N]quaternion128 { return array_cast(v, quaternion128) }
to_quaternion256 :: #force_inline proc(v: $A/[$N]$T) -> [N]quaternion256 { return array_cast(v, quaternion256) }
@(require_results) to_complex32 :: #force_inline proc(v: $A/[$N]$T) -> [N]complex32 { return array_cast(v, complex32) }
@(require_results) to_complex64 :: #force_inline proc(v: $A/[$N]$T) -> [N]complex64 { return array_cast(v, complex64) }
@(require_results) to_complex128 :: #force_inline proc(v: $A/[$N]$T) -> [N]complex128 { return array_cast(v, complex128) }
@(require_results) to_quaternion64 :: #force_inline proc(v: $A/[$N]$T) -> [N]quaternion64 { return array_cast(v, quaternion64) }
@(require_results) to_quaternion128 :: #force_inline proc(v: $A/[$N]$T) -> [N]quaternion128 { return array_cast(v, quaternion128) }
@(require_results) to_quaternion256 :: #force_inline proc(v: $A/[$N]$T) -> [N]quaternion256 { return array_cast(v, quaternion256) }
File diff suppressed because it is too large Load Diff
+50 -48
View File
@@ -2,30 +2,31 @@ package math_linalg_glsl
import "core:math"
cos_f32 :: proc "c" (x: f32) -> f32 { return math.cos(x) }
sin_f32 :: proc "c" (x: f32) -> f32 { return math.sin(x) }
tan_f32 :: proc "c" (x: f32) -> f32 { return math.tan(x) }
acos_f32 :: proc "c" (x: f32) -> f32 { return math.acos(x) }
asin_f32 :: proc "c" (x: f32) -> f32 { return math.asin(x) }
atan_f32 :: proc "c" (x: f32) -> f32 { return math.atan(x) }
atan2_f32 :: proc "c" (y, x: f32) -> f32 { return math.atan2(y, x) }
cosh_f32 :: proc "c" (x: f32) -> f32 { return math.cosh(x) }
sinh_f32 :: proc "c" (x: f32) -> f32 { return math.sinh(x) }
tanh_f32 :: proc "c" (x: f32) -> f32 { return math.tanh(x) }
acosh_f32 :: proc "c" (x: f32) -> f32 { return math.acosh(x) }
asinh_f32 :: proc "c" (x: f32) -> f32 { return math.asinh(x) }
atanh_f32 :: proc "c" (x: f32) -> f32 { return math.atanh(x) }
sqrt_f32 :: proc "c" (x: f32) -> f32 { return math.sqrt(x) }
inversesqrt_f32 :: proc "c" (x: f32) -> f32 { return 1.0/math.sqrt(x) }
pow_f32 :: proc "c" (x, y: f32) -> f32 { return math.pow(x, y) }
exp_f32 :: proc "c" (x: f32) -> f32 { return math.exp(x) }
log_f32 :: proc "c" (x: f32) -> f32 { return math.ln(x) }
exp2_f32 :: proc "c" (x: f32) -> f32 { return math.pow(f32(2), x) }
sign_f32 :: proc "c" (x: f32) -> f32 { return math.sign(x) }
floor_f32 :: proc "c" (x: f32) -> f32 { return math.floor(x) }
round_f32 :: proc "c" (x: f32) -> f32 { return math.round(x) }
ceil_f32 :: proc "c" (x: f32) -> f32 { return math.ceil(x) }
mod_f32 :: proc "c" (x, y: f32) -> f32 { return math.mod(x, y) }
@(require_results) cos_f32 :: proc "c" (x: f32) -> f32 { return math.cos(x) }
@(require_results) sin_f32 :: proc "c" (x: f32) -> f32 { return math.sin(x) }
@(require_results) tan_f32 :: proc "c" (x: f32) -> f32 { return math.tan(x) }
@(require_results) acos_f32 :: proc "c" (x: f32) -> f32 { return math.acos(x) }
@(require_results) asin_f32 :: proc "c" (x: f32) -> f32 { return math.asin(x) }
@(require_results) atan_f32 :: proc "c" (x: f32) -> f32 { return math.atan(x) }
@(require_results) atan2_f32 :: proc "c" (y, x: f32) -> f32 { return math.atan2(y, x) }
@(require_results) cosh_f32 :: proc "c" (x: f32) -> f32 { return math.cosh(x) }
@(require_results) sinh_f32 :: proc "c" (x: f32) -> f32 { return math.sinh(x) }
@(require_results) tanh_f32 :: proc "c" (x: f32) -> f32 { return math.tanh(x) }
@(require_results) acosh_f32 :: proc "c" (x: f32) -> f32 { return math.acosh(x) }
@(require_results) asinh_f32 :: proc "c" (x: f32) -> f32 { return math.asinh(x) }
@(require_results) atanh_f32 :: proc "c" (x: f32) -> f32 { return math.atanh(x) }
@(require_results) sqrt_f32 :: proc "c" (x: f32) -> f32 { return math.sqrt(x) }
@(require_results) inversesqrt_f32 :: proc "c" (x: f32) -> f32 { return 1.0/math.sqrt(x) }
@(require_results) pow_f32 :: proc "c" (x, y: f32) -> f32 { return math.pow(x, y) }
@(require_results) exp_f32 :: proc "c" (x: f32) -> f32 { return math.exp(x) }
@(require_results) log_f32 :: proc "c" (x: f32) -> f32 { return math.ln(x) }
@(require_results) exp2_f32 :: proc "c" (x: f32) -> f32 { return math.pow(f32(2), x) }
@(require_results) sign_f32 :: proc "c" (x: f32) -> f32 { return math.sign(x) }
@(require_results) floor_f32 :: proc "c" (x: f32) -> f32 { return math.floor(x) }
@(require_results) round_f32 :: proc "c" (x: f32) -> f32 { return math.round(x) }
@(require_results) ceil_f32 :: proc "c" (x: f32) -> f32 { return math.ceil(x) }
@(require_results) mod_f32 :: proc "c" (x, y: f32) -> f32 { return math.mod(x, y) }
@(require_results)
fract_f32 :: proc "c" (x: f32) -> f32 {
if x >= 0 {
return x - math.trunc(x)
@@ -33,30 +34,31 @@ fract_f32 :: proc "c" (x: f32) -> f32 {
return math.trunc(-x) + x
}
cos_f64 :: proc "c" (x: f64) -> f64 { return math.cos(x) }
sin_f64 :: proc "c" (x: f64) -> f64 { return math.sin(x) }
tan_f64 :: proc "c" (x: f64) -> f64 { return math.tan(x) }
acos_f64 :: proc "c" (x: f64) -> f64 { return math.acos(x) }
asin_f64 :: proc "c" (x: f64) -> f64 { return math.asin(x) }
atan_f64 :: proc "c" (x: f64) -> f64 { return math.atan(x) }
atan2_f64 :: proc "c" (y, x: f64) -> f64 { return math.atan2(y, x) }
cosh_f64 :: proc "c" (x: f64) -> f64 { return math.cosh(x) }
sinh_f64 :: proc "c" (x: f64) -> f64 { return math.sinh(x) }
tanh_f64 :: proc "c" (x: f64) -> f64 { return math.tanh(x) }
acosh_f64 :: proc "c" (x: f64) -> f64 { return math.acosh(x) }
asinh_f64 :: proc "c" (x: f64) -> f64 { return math.asinh(x) }
atanh_f64 :: proc "c" (x: f64) -> f64 { return math.atanh(x) }
sqrt_f64 :: proc "c" (x: f64) -> f64 { return math.sqrt(x) }
inversesqrt_f64 :: proc "c" (x: f64) -> f64 { return 1.0/math.sqrt(x) }
pow_f64 :: proc "c" (x, y: f64) -> f64 { return math.pow(x, y) }
exp_f64 :: proc "c" (x: f64) -> f64 { return math.exp(x) }
log_f64 :: proc "c" (x: f64) -> f64 { return math.ln(x) }
exp2_f64 :: proc "c" (x: f64) -> f64 { return math.pow(f64(2), x) }
sign_f64 :: proc "c" (x: f64) -> f64 { return math.sign(x) }
floor_f64 :: proc "c" (x: f64) -> f64 { return math.floor(x) }
round_f64 :: proc "c" (x: f64) -> f64 { return math.round(x) }
ceil_f64 :: proc "c" (x: f64) -> f64 { return math.ceil(x) }
mod_f64 :: proc "c" (x, y: f64) -> f64 { return math.mod(x, y) }
@(require_results) cos_f64 :: proc "c" (x: f64) -> f64 { return math.cos(x) }
@(require_results) sin_f64 :: proc "c" (x: f64) -> f64 { return math.sin(x) }
@(require_results) tan_f64 :: proc "c" (x: f64) -> f64 { return math.tan(x) }
@(require_results) acos_f64 :: proc "c" (x: f64) -> f64 { return math.acos(x) }
@(require_results) asin_f64 :: proc "c" (x: f64) -> f64 { return math.asin(x) }
@(require_results) atan_f64 :: proc "c" (x: f64) -> f64 { return math.atan(x) }
@(require_results) atan2_f64 :: proc "c" (y, x: f64) -> f64 { return math.atan2(y, x) }
@(require_results) cosh_f64 :: proc "c" (x: f64) -> f64 { return math.cosh(x) }
@(require_results) sinh_f64 :: proc "c" (x: f64) -> f64 { return math.sinh(x) }
@(require_results) tanh_f64 :: proc "c" (x: f64) -> f64 { return math.tanh(x) }
@(require_results) acosh_f64 :: proc "c" (x: f64) -> f64 { return math.acosh(x) }
@(require_results) asinh_f64 :: proc "c" (x: f64) -> f64 { return math.asinh(x) }
@(require_results) atanh_f64 :: proc "c" (x: f64) -> f64 { return math.atanh(x) }
@(require_results) sqrt_f64 :: proc "c" (x: f64) -> f64 { return math.sqrt(x) }
@(require_results) inversesqrt_f64 :: proc "c" (x: f64) -> f64 { return 1.0/math.sqrt(x) }
@(require_results) pow_f64 :: proc "c" (x, y: f64) -> f64 { return math.pow(x, y) }
@(require_results) exp_f64 :: proc "c" (x: f64) -> f64 { return math.exp(x) }
@(require_results) log_f64 :: proc "c" (x: f64) -> f64 { return math.ln(x) }
@(require_results) exp2_f64 :: proc "c" (x: f64) -> f64 { return math.pow(f64(2), x) }
@(require_results) sign_f64 :: proc "c" (x: f64) -> f64 { return math.sign(x) }
@(require_results) floor_f64 :: proc "c" (x: f64) -> f64 { return math.floor(x) }
@(require_results) round_f64 :: proc "c" (x: f64) -> f64 { return math.round(x) }
@(require_results) ceil_f64 :: proc "c" (x: f64) -> f64 { return math.ceil(x) }
@(require_results) mod_f64 :: proc "c" (x, y: f64) -> f64 { return math.mod(x, y) }
@(require_results)
fract_f64 :: proc "c" (x: f64) -> f64 {
if x >= 0 {
return x - math.trunc(x)
File diff suppressed because it is too large Load Diff
+58 -56
View File
@@ -2,34 +2,35 @@ package math_linalg_hlsl
import "core:math"
cos_float :: proc "c" (x: float) -> float { return math.cos(x) }
sin_float :: proc "c" (x: float) -> float { return math.sin(x) }
tan_float :: proc "c" (x: float) -> float { return math.tan(x) }
acos_float :: proc "c" (x: float) -> float { return math.acos(x) }
asin_float :: proc "c" (x: float) -> float { return math.asin(x) }
atan_float :: proc "c" (x: float) -> float { return math.atan(x) }
atan2_float :: proc "c" (y, x: float) -> float { return math.atan2(y, x) }
cosh_float :: proc "c" (x: float) -> float { return math.cosh(x) }
sinh_float :: proc "c" (x: float) -> float { return math.sinh(x) }
tanh_float :: proc "c" (x: float) -> float { return math.tanh(x) }
acosh_float :: proc "c" (x: float) -> float { return math.acosh(x) }
asinh_float :: proc "c" (x: float) -> float { return math.asinh(x) }
atanh_float :: proc "c" (x: float) -> float { return math.atanh(x) }
sqrt_float :: proc "c" (x: float) -> float { return math.sqrt(x) }
rsqrt_float :: proc "c" (x: float) -> float { return 1.0/math.sqrt(x) }
rcp_float :: proc "c" (x: float) -> float { return 1.0/x }
pow_float :: proc "c" (x, y: float) -> float { return math.pow(x, y) }
exp_float :: proc "c" (x: float) -> float { return math.exp(x) }
log_float :: proc "c" (x: float) -> float { return math.ln(x) }
log2_float :: proc "c" (x: float) -> float { return math.log(x, 2) }
log10_float :: proc "c" (x: float) -> float { return math.log(x, 10) }
exp2_float :: proc "c" (x: float) -> float { return math.pow(float(2), x) }
sign_float :: proc "c" (x: float) -> float { return math.sign(x) }
floor_float :: proc "c" (x: float) -> float { return math.floor(x) }
round_float :: proc "c" (x: float) -> float { return math.round(x) }
ceil_float :: proc "c" (x: float) -> float { return math.ceil(x) }
isnan_float :: proc "c" (x: float) -> bool { return math.classify(x) == .NaN}
fmod_float :: proc "c" (x, y: float) -> float { return math.mod(x, y) }
@(require_results) cos_float :: proc "c" (x: float) -> float { return math.cos(x) }
@(require_results) sin_float :: proc "c" (x: float) -> float { return math.sin(x) }
@(require_results) tan_float :: proc "c" (x: float) -> float { return math.tan(x) }
@(require_results) acos_float :: proc "c" (x: float) -> float { return math.acos(x) }
@(require_results) asin_float :: proc "c" (x: float) -> float { return math.asin(x) }
@(require_results) atan_float :: proc "c" (x: float) -> float { return math.atan(x) }
@(require_results) atan2_float :: proc "c" (y, x: float) -> float { return math.atan2(y, x) }
@(require_results) cosh_float :: proc "c" (x: float) -> float { return math.cosh(x) }
@(require_results) sinh_float :: proc "c" (x: float) -> float { return math.sinh(x) }
@(require_results) tanh_float :: proc "c" (x: float) -> float { return math.tanh(x) }
@(require_results) acosh_float :: proc "c" (x: float) -> float { return math.acosh(x) }
@(require_results) asinh_float :: proc "c" (x: float) -> float { return math.asinh(x) }
@(require_results) atanh_float :: proc "c" (x: float) -> float { return math.atanh(x) }
@(require_results) sqrt_float :: proc "c" (x: float) -> float { return math.sqrt(x) }
@(require_results) rsqrt_float :: proc "c" (x: float) -> float { return 1.0/math.sqrt(x) }
@(require_results) rcp_float :: proc "c" (x: float) -> float { return 1.0/x }
@(require_results) pow_float :: proc "c" (x, y: float) -> float { return math.pow(x, y) }
@(require_results) exp_float :: proc "c" (x: float) -> float { return math.exp(x) }
@(require_results) log_float :: proc "c" (x: float) -> float { return math.ln(x) }
@(require_results) log2_float :: proc "c" (x: float) -> float { return math.log(x, 2) }
@(require_results) log10_float :: proc "c" (x: float) -> float { return math.log(x, 10) }
@(require_results) exp2_float :: proc "c" (x: float) -> float { return math.pow(float(2), x) }
@(require_results) sign_float :: proc "c" (x: float) -> float { return math.sign(x) }
@(require_results) floor_float :: proc "c" (x: float) -> float { return math.floor(x) }
@(require_results) round_float :: proc "c" (x: float) -> float { return math.round(x) }
@(require_results) ceil_float :: proc "c" (x: float) -> float { return math.ceil(x) }
@(require_results) isnan_float :: proc "c" (x: float) -> bool { return math.classify(x) == .NaN}
@(require_results) fmod_float :: proc "c" (x, y: float) -> float { return math.mod(x, y) }
@(require_results)
frac_float :: proc "c" (x: float) -> float {
if x >= 0 {
return x - math.trunc(x)
@@ -38,34 +39,35 @@ frac_float :: proc "c" (x: float) -> float {
}
cos_double :: proc "c" (x: double) -> double { return math.cos(x) }
sin_double :: proc "c" (x: double) -> double { return math.sin(x) }
tan_double :: proc "c" (x: double) -> double { return math.tan(x) }
acos_double :: proc "c" (x: double) -> double { return math.acos(x) }
asin_double :: proc "c" (x: double) -> double { return math.asin(x) }
atan_double :: proc "c" (x: double) -> double { return math.atan(x) }
atan2_double :: proc "c" (y, x: double) -> double { return math.atan2(y, x) }
cosh_double :: proc "c" (x: double) -> double { return math.cosh(x) }
sinh_double :: proc "c" (x: double) -> double { return math.sinh(x) }
tanh_double :: proc "c" (x: double) -> double { return math.tanh(x) }
acosh_double :: proc "c" (x: double) -> double { return math.acosh(x) }
asinh_double :: proc "c" (x: double) -> double { return math.asinh(x) }
atanh_double :: proc "c" (x: double) -> double { return math.atanh(x) }
sqrt_double :: proc "c" (x: double) -> double { return math.sqrt(x) }
rsqrt_double :: proc "c" (x: double) -> double { return 1.0/math.sqrt(x) }
rcp_double :: proc "c" (x: double) -> double { return 1.0/x }
pow_double :: proc "c" (x, y: double) -> double { return math.pow(x, y) }
exp_double :: proc "c" (x: double) -> double { return math.exp(x) }
log_double :: proc "c" (x: double) -> double { return math.ln(x) }
log2_double :: proc "c" (x: double) -> double { return math.log(x, 2) }
log10_double :: proc "c" (x: double) -> double { return math.log(x, 10) }
exp2_double :: proc "c" (x: double) -> double { return math.pow(double(2), x) }
sign_double :: proc "c" (x: double) -> double { return math.sign(x) }
floor_double :: proc "c" (x: double) -> double { return math.floor(x) }
round_double :: proc "c" (x: double) -> double { return math.round(x) }
ceil_double :: proc "c" (x: double) -> double { return math.ceil(x) }
isnan_double :: proc "c" (x: double) -> bool { return math.classify(x) == .NaN}
fmod_double :: proc "c" (x, y: double) -> double { return math.mod(x, y) }
@(require_results) cos_double :: proc "c" (x: double) -> double { return math.cos(x) }
@(require_results) sin_double :: proc "c" (x: double) -> double { return math.sin(x) }
@(require_results) tan_double :: proc "c" (x: double) -> double { return math.tan(x) }
@(require_results) acos_double :: proc "c" (x: double) -> double { return math.acos(x) }
@(require_results) asin_double :: proc "c" (x: double) -> double { return math.asin(x) }
@(require_results) atan_double :: proc "c" (x: double) -> double { return math.atan(x) }
@(require_results) atan2_double :: proc "c" (y, x: double) -> double { return math.atan2(y, x) }
@(require_results) cosh_double :: proc "c" (x: double) -> double { return math.cosh(x) }
@(require_results) sinh_double :: proc "c" (x: double) -> double { return math.sinh(x) }
@(require_results) tanh_double :: proc "c" (x: double) -> double { return math.tanh(x) }
@(require_results) acosh_double :: proc "c" (x: double) -> double { return math.acosh(x) }
@(require_results) asinh_double :: proc "c" (x: double) -> double { return math.asinh(x) }
@(require_results) atanh_double :: proc "c" (x: double) -> double { return math.atanh(x) }
@(require_results) sqrt_double :: proc "c" (x: double) -> double { return math.sqrt(x) }
@(require_results) rsqrt_double :: proc "c" (x: double) -> double { return 1.0/math.sqrt(x) }
@(require_results) rcp_double :: proc "c" (x: double) -> double { return 1.0/x }
@(require_results) pow_double :: proc "c" (x, y: double) -> double { return math.pow(x, y) }
@(require_results) exp_double :: proc "c" (x: double) -> double { return math.exp(x) }
@(require_results) log_double :: proc "c" (x: double) -> double { return math.ln(x) }
@(require_results) log2_double :: proc "c" (x: double) -> double { return math.log(x, 2) }
@(require_results) log10_double :: proc "c" (x: double) -> double { return math.log(x, 10) }
@(require_results) exp2_double :: proc "c" (x: double) -> double { return math.pow(double(2), x) }
@(require_results) sign_double :: proc "c" (x: double) -> double { return math.sign(x) }
@(require_results) floor_double :: proc "c" (x: double) -> double { return math.floor(x) }
@(require_results) round_double :: proc "c" (x: double) -> double { return math.round(x) }
@(require_results) ceil_double :: proc "c" (x: double) -> double { return math.ceil(x) }
@(require_results) isnan_double :: proc "c" (x: double) -> bool { return math.classify(x) == .NaN}
@(require_results) fmod_double :: proc "c" (x, y: double) -> double { return math.mod(x, y) }
@(require_results)
frac_double :: proc "c" (x: double) -> double {
if x >= 0 {
return x - math.trunc(x)
File diff suppressed because it is too large Load Diff
+200 -100
View File
@@ -2,7 +2,8 @@ package linalg
import "core:math"
euler_angles_from_matrix3_f16 :: proc(m: Matrix3f16, order: Euler_Angle_Order) -> (t1, t2, t3: f16) {
@(require_results)
euler_angles_from_matrix3_f16 :: proc "contextless" (m: Matrix3f16, order: Euler_Angle_Order) -> (t1, t2, t3: f16) {
switch order {
case .XYZ: t1, t2, t3 = euler_angles_xyz_from_matrix3(m)
case .XZY: t1, t2, t3 = euler_angles_xzy_from_matrix3(m)
@@ -19,7 +20,8 @@ euler_angles_from_matrix3_f16 :: proc(m: Matrix3f16, order: Euler_Angle_Order) -
}
return
}
euler_angles_from_matrix4_f16 :: proc(m: Matrix4f16, order: Euler_Angle_Order) -> (t1, t2, t3: f16) {
@(require_results)
euler_angles_from_matrix4_f16 :: proc "contextless" (m: Matrix4f16, order: Euler_Angle_Order) -> (t1, t2, t3: f16) {
switch order {
case .XYZ: t1, t2, t3 = euler_angles_xyz_from_matrix4(m)
case .XZY: t1, t2, t3 = euler_angles_xzy_from_matrix4(m)
@@ -36,7 +38,8 @@ euler_angles_from_matrix4_f16 :: proc(m: Matrix4f16, order: Euler_Angle_Order) -
}
return
}
euler_angles_from_quaternion_f16 :: proc(m: Quaternionf16, order: Euler_Angle_Order) -> (t1, t2, t3: f16) {
@(require_results)
euler_angles_from_quaternion_f16 :: proc "contextless" (m: Quaternionf16, order: Euler_Angle_Order) -> (t1, t2, t3: f16) {
switch order {
case .XYZ: t1, t2, t3 = euler_angles_xyz_from_quaternion(m)
case .XZY: t1, t2, t3 = euler_angles_xzy_from_quaternion(m)
@@ -54,7 +57,8 @@ euler_angles_from_quaternion_f16 :: proc(m: Quaternionf16, order: Euler_Angle_Or
return
}
matrix3_from_euler_angles_f16 :: proc(t1, t2, t3: f16, order: Euler_Angle_Order) -> (m: Matrix3f16) {
@(require_results)
matrix3_from_euler_angles_f16 :: proc "contextless" (t1, t2, t3: f16, order: Euler_Angle_Order) -> (m: Matrix3f16) {
switch order {
case .XYZ: return matrix3_from_euler_angles_xyz(t1, t2, t3) // m1, m2, m3 = X(t1), Y(t2), Z(t3);
case .XZY: return matrix3_from_euler_angles_xzy(t1, t2, t3) // m1, m2, m3 = X(t1), Z(t2), Y(t3);
@@ -71,7 +75,8 @@ matrix3_from_euler_angles_f16 :: proc(t1, t2, t3: f16, order: Euler_Angle_Order)
}
return
}
matrix4_from_euler_angles_f16 :: proc(t1, t2, t3: f16, order: Euler_Angle_Order) -> (m: Matrix4f16) {
@(require_results)
matrix4_from_euler_angles_f16 :: proc "contextless" (t1, t2, t3: f16, order: Euler_Angle_Order) -> (m: Matrix4f16) {
switch order {
case .XYZ: return matrix4_from_euler_angles_xyz(t1, t2, t3) // m1, m2, m3 = X(t1), Y(t2), Z(t3);
case .XZY: return matrix4_from_euler_angles_xzy(t1, t2, t3) // m1, m2, m3 = X(t1), Z(t2), Y(t3);
@@ -89,7 +94,8 @@ matrix4_from_euler_angles_f16 :: proc(t1, t2, t3: f16, order: Euler_Angle_Order)
return
}
quaternion_from_euler_angles_f16 :: proc(t1, t2, t3: f16, order: Euler_Angle_Order) -> Quaternionf16 {
@(require_results)
quaternion_from_euler_angles_f16 :: proc "contextless" (t1, t2, t3: f16, order: Euler_Angle_Order) -> Quaternionf16 {
X :: quaternion_from_euler_angle_x
Y :: quaternion_from_euler_angle_y
Z :: quaternion_from_euler_angle_z
@@ -117,17 +123,21 @@ quaternion_from_euler_angles_f16 :: proc(t1, t2, t3: f16, order: Euler_Angle_Ord
// Quaternionf16s
quaternion_from_euler_angle_x_f16 :: proc(angle_x: f16) -> (q: Quaternionf16) {
@(require_results)
quaternion_from_euler_angle_x_f16 :: proc "contextless" (angle_x: f16) -> (q: Quaternionf16) {
return quaternion_angle_axis_f16(angle_x, {1, 0, 0})
}
quaternion_from_euler_angle_y_f16 :: proc(angle_y: f16) -> (q: Quaternionf16) {
@(require_results)
quaternion_from_euler_angle_y_f16 :: proc "contextless" (angle_y: f16) -> (q: Quaternionf16) {
return quaternion_angle_axis_f16(angle_y, {0, 1, 0})
}
quaternion_from_euler_angle_z_f16 :: proc(angle_z: f16) -> (q: Quaternionf16) {
@(require_results)
quaternion_from_euler_angle_z_f16 :: proc "contextless" (angle_z: f16) -> (q: Quaternionf16) {
return quaternion_angle_axis_f16(angle_z, {0, 0, 1})
}
quaternion_from_pitch_yaw_roll_f16 :: proc(pitch, yaw, roll: f16) -> Quaternionf16 {
@(require_results)
quaternion_from_pitch_yaw_roll_f16 :: proc "contextless" (pitch, yaw, roll: f16) -> Quaternionf16 {
a, b, c := pitch, yaw, roll
ca, sa := math.cos(a*0.5), math.sin(a*0.5)
@@ -142,11 +152,13 @@ quaternion_from_pitch_yaw_roll_f16 :: proc(pitch, yaw, roll: f16) -> Quaternionf
return q
}
roll_from_quaternion_f16 :: proc(q: Quaternionf16) -> f16 {
@(require_results)
roll_from_quaternion_f16 :: proc "contextless" (q: Quaternionf16) -> f16 {
return math.atan2(2 * q.x*q.y + q.w*q.z, q.w*q.w + q.x*q.x - q.y*q.y - q.z*q.z)
}
pitch_from_quaternion_f16 :: proc(q: Quaternionf16) -> f16 {
@(require_results)
pitch_from_quaternion_f16 :: proc "contextless" (q: Quaternionf16) -> f16 {
y := 2 * (q.y*q.z + q.w*q.w)
x := q.w*q.w - q.x*q.x - q.y*q.y + q.z*q.z
@@ -157,52 +169,66 @@ pitch_from_quaternion_f16 :: proc(q: Quaternionf16) -> f16 {
return math.atan2(y, x)
}
yaw_from_quaternion_f16 :: proc(q: Quaternionf16) -> f16 {
@(require_results)
yaw_from_quaternion_f16 :: proc "contextless" (q: Quaternionf16) -> f16 {
return math.asin(clamp(-2 * (q.x*q.z - q.w*q.y), -1, 1))
}
pitch_yaw_roll_from_quaternion_f16 :: proc(q: Quaternionf16) -> (pitch, yaw, roll: f16) {
@(require_results)
pitch_yaw_roll_from_quaternion_f16 :: proc "contextless" (q: Quaternionf16) -> (pitch, yaw, roll: f16) {
pitch = pitch_from_quaternion(q)
yaw = yaw_from_quaternion(q)
roll = roll_from_quaternion(q)
return
}
euler_angles_xyz_from_quaternion_f16 :: proc(q: Quaternionf16) -> (t1, t2, t3: f16) {
@(require_results)
euler_angles_xyz_from_quaternion_f16 :: proc "contextless" (q: Quaternionf16) -> (t1, t2, t3: f16) {
return euler_angles_xyz_from_matrix4(matrix4_from_quaternion(q))
}
euler_angles_yxz_from_quaternion_f16 :: proc(q: Quaternionf16) -> (t1, t2, t3: f16) {
@(require_results)
euler_angles_yxz_from_quaternion_f16 :: proc "contextless" (q: Quaternionf16) -> (t1, t2, t3: f16) {
return euler_angles_yxz_from_matrix4(matrix4_from_quaternion(q))
}
euler_angles_xzx_from_quaternion_f16 :: proc(q: Quaternionf16) -> (t1, t2, t3: f16) {
@(require_results)
euler_angles_xzx_from_quaternion_f16 :: proc "contextless" (q: Quaternionf16) -> (t1, t2, t3: f16) {
return euler_angles_xzx_from_matrix4(matrix4_from_quaternion(q))
}
euler_angles_xyx_from_quaternion_f16 :: proc(q: Quaternionf16) -> (t1, t2, t3: f16) {
@(require_results)
euler_angles_xyx_from_quaternion_f16 :: proc "contextless" (q: Quaternionf16) -> (t1, t2, t3: f16) {
return euler_angles_xyx_from_matrix4(matrix4_from_quaternion(q))
}
euler_angles_yxy_from_quaternion_f16 :: proc(q: Quaternionf16) -> (t1, t2, t3: f16) {
@(require_results)
euler_angles_yxy_from_quaternion_f16 :: proc "contextless" (q: Quaternionf16) -> (t1, t2, t3: f16) {
return euler_angles_yxy_from_matrix4(matrix4_from_quaternion(q))
}
euler_angles_yzy_from_quaternion_f16 :: proc(q: Quaternionf16) -> (t1, t2, t3: f16) {
@(require_results)
euler_angles_yzy_from_quaternion_f16 :: proc "contextless" (q: Quaternionf16) -> (t1, t2, t3: f16) {
return euler_angles_yzy_from_matrix4(matrix4_from_quaternion(q))
}
euler_angles_zyz_from_quaternion_f16 :: proc(q: Quaternionf16) -> (t1, t2, t3: f16) {
@(require_results)
euler_angles_zyz_from_quaternion_f16 :: proc "contextless" (q: Quaternionf16) -> (t1, t2, t3: f16) {
return euler_angles_zyz_from_matrix4(matrix4_from_quaternion(q))
}
euler_angles_zxz_from_quaternion_f16 :: proc(q: Quaternionf16) -> (t1, t2, t3: f16) {
@(require_results)
euler_angles_zxz_from_quaternion_f16 :: proc "contextless" (q: Quaternionf16) -> (t1, t2, t3: f16) {
return euler_angles_zxz_from_matrix4(matrix4_from_quaternion(q))
}
euler_angles_xzy_from_quaternion_f16 :: proc(q: Quaternionf16) -> (t1, t2, t3: f16) {
@(require_results)
euler_angles_xzy_from_quaternion_f16 :: proc "contextless" (q: Quaternionf16) -> (t1, t2, t3: f16) {
return euler_angles_xzy_from_matrix4(matrix4_from_quaternion(q))
}
euler_angles_yzx_from_quaternion_f16 :: proc(q: Quaternionf16) -> (t1, t2, t3: f16) {
@(require_results)
euler_angles_yzx_from_quaternion_f16 :: proc "contextless" (q: Quaternionf16) -> (t1, t2, t3: f16) {
return euler_angles_yzx_from_matrix4(matrix4_from_quaternion(q))
}
euler_angles_zyx_from_quaternion_f16 :: proc(q: Quaternionf16) -> (t1, t2, t3: f16) {
@(require_results)
euler_angles_zyx_from_quaternion_f16 :: proc "contextless" (q: Quaternionf16) -> (t1, t2, t3: f16) {
return euler_angles_zyx_from_matrix4(matrix4_from_quaternion(q))
}
euler_angles_zxy_from_quaternion_f16 :: proc(q: Quaternionf16) -> (t1, t2, t3: f16) {
@(require_results)
euler_angles_zxy_from_quaternion_f16 :: proc "contextless" (q: Quaternionf16) -> (t1, t2, t3: f16) {
return euler_angles_zxy_from_matrix4(matrix4_from_quaternion(q))
}
@@ -210,7 +236,8 @@ euler_angles_zxy_from_quaternion_f16 :: proc(q: Quaternionf16) -> (t1, t2, t3: f
// Matrix3
matrix3_from_euler_angle_x_f16 :: proc(angle_x: f16) -> (m: Matrix3f16) {
@(require_results)
matrix3_from_euler_angle_x_f16 :: proc "contextless" (angle_x: f16) -> (m: Matrix3f16) {
cos_x, sin_x := math.cos(angle_x), math.sin(angle_x)
m[0, 0] = 1
m[1, 1] = +cos_x
@@ -219,7 +246,8 @@ matrix3_from_euler_angle_x_f16 :: proc(angle_x: f16) -> (m: Matrix3f16) {
m[2, 2] = +cos_x
return
}
matrix3_from_euler_angle_y_f16 :: proc(angle_y: f16) -> (m: Matrix3f16) {
@(require_results)
matrix3_from_euler_angle_y_f16 :: proc "contextless" (angle_y: f16) -> (m: Matrix3f16) {
cos_y, sin_y := math.cos(angle_y), math.sin(angle_y)
m[0, 0] = +cos_y
m[0, 2] = -sin_y
@@ -228,7 +256,8 @@ matrix3_from_euler_angle_y_f16 :: proc(angle_y: f16) -> (m: Matrix3f16) {
m[2, 2] = +cos_y
return
}
matrix3_from_euler_angle_z_f16 :: proc(angle_z: f16) -> (m: Matrix3f16) {
@(require_results)
matrix3_from_euler_angle_z_f16 :: proc "contextless" (angle_z: f16) -> (m: Matrix3f16) {
cos_z, sin_z := math.cos(angle_z), math.sin(angle_z)
m[0, 0] = +cos_z
m[0, 1] = +sin_z
@@ -239,7 +268,8 @@ matrix3_from_euler_angle_z_f16 :: proc(angle_z: f16) -> (m: Matrix3f16) {
}
matrix3_from_derived_euler_angle_x_f16 :: proc(angle_x: f16, angular_velocity_x: f16) -> (m: Matrix3f16) {
@(require_results)
matrix3_from_derived_euler_angle_x_f16 :: proc "contextless" (angle_x: f16, angular_velocity_x: f16) -> (m: Matrix3f16) {
cos_x := math.cos(angle_x) * angular_velocity_x
sin_x := math.sin(angle_x) * angular_velocity_x
m[0, 0] = 1
@@ -249,7 +279,8 @@ matrix3_from_derived_euler_angle_x_f16 :: proc(angle_x: f16, angular_velocity_x:
m[2, 2] = +cos_x
return
}
matrix3_from_derived_euler_angle_y_f16 :: proc(angle_y: f16, angular_velocity_y: f16) -> (m: Matrix3f16) {
@(require_results)
matrix3_from_derived_euler_angle_y_f16 :: proc "contextless" (angle_y: f16, angular_velocity_y: f16) -> (m: Matrix3f16) {
cos_y := math.cos(angle_y) * angular_velocity_y
sin_y := math.sin(angle_y) * angular_velocity_y
m[0, 0] = +cos_y
@@ -259,7 +290,8 @@ matrix3_from_derived_euler_angle_y_f16 :: proc(angle_y: f16, angular_velocity_y:
m[2, 2] = +cos_y
return
}
matrix3_from_derived_euler_angle_z_f16 :: proc(angle_z: f16, angular_velocity_z: f16) -> (m: Matrix3f16) {
@(require_results)
matrix3_from_derived_euler_angle_z_f16 :: proc "contextless" (angle_z: f16, angular_velocity_z: f16) -> (m: Matrix3f16) {
cos_z := math.cos(angle_z) * angular_velocity_z
sin_z := math.sin(angle_z) * angular_velocity_z
m[0, 0] = +cos_z
@@ -271,7 +303,8 @@ matrix3_from_derived_euler_angle_z_f16 :: proc(angle_z: f16, angular_velocity_z:
}
matrix3_from_euler_angles_xy_f16 :: proc(angle_x, angle_y: f16) -> (m: Matrix3f16) {
@(require_results)
matrix3_from_euler_angles_xy_f16 :: proc "contextless" (angle_x, angle_y: f16) -> (m: Matrix3f16) {
cos_x, sin_x := math.cos(angle_x), math.sin(angle_x)
cos_y, sin_y := math.cos(angle_y), math.sin(angle_y)
m[0, 0] = cos_y
@@ -286,7 +319,8 @@ matrix3_from_euler_angles_xy_f16 :: proc(angle_x, angle_y: f16) -> (m: Matrix3f1
}
matrix3_from_euler_angles_yx_f16 :: proc(angle_y, angle_x: f16) -> (m: Matrix3f16) {
@(require_results)
matrix3_from_euler_angles_yx_f16 :: proc "contextless" (angle_y, angle_x: f16) -> (m: Matrix3f16) {
cos_x, sin_x := math.cos(angle_x), math.sin(angle_x)
cos_y, sin_y := math.cos(angle_y), math.sin(angle_y)
m[0, 0] = cos_y
@@ -300,21 +334,26 @@ matrix3_from_euler_angles_yx_f16 :: proc(angle_y, angle_x: f16) -> (m: Matrix3f1
return
}
matrix3_from_euler_angles_xz_f16 :: proc(angle_x, angle_z: f16) -> (m: Matrix3f16) {
@(require_results)
matrix3_from_euler_angles_xz_f16 :: proc "contextless" (angle_x, angle_z: f16) -> (m: Matrix3f16) {
return mul(matrix3_from_euler_angle_x(angle_x), matrix3_from_euler_angle_z(angle_z))
}
matrix3_from_euler_angles_zx_f16 :: proc(angle_z, angle_x: f16) -> (m: Matrix3f16) {
@(require_results)
matrix3_from_euler_angles_zx_f16 :: proc "contextless" (angle_z, angle_x: f16) -> (m: Matrix3f16) {
return mul(matrix3_from_euler_angle_z(angle_z), matrix3_from_euler_angle_x(angle_x))
}
matrix3_from_euler_angles_yz_f16 :: proc(angle_y, angle_z: f16) -> (m: Matrix3f16) {
@(require_results)
matrix3_from_euler_angles_yz_f16 :: proc "contextless" (angle_y, angle_z: f16) -> (m: Matrix3f16) {
return mul(matrix3_from_euler_angle_y(angle_y), matrix3_from_euler_angle_z(angle_z))
}
matrix3_from_euler_angles_zy_f16 :: proc(angle_z, angle_y: f16) -> (m: Matrix3f16) {
@(require_results)
matrix3_from_euler_angles_zy_f16 :: proc "contextless" (angle_z, angle_y: f16) -> (m: Matrix3f16) {
return mul(matrix3_from_euler_angle_z(angle_z), matrix3_from_euler_angle_y(angle_y))
}
matrix3_from_euler_angles_xyz_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix3f16) {
@(require_results)
matrix3_from_euler_angles_xyz_f16 :: proc "contextless" (t1, t2, t3: f16) -> (m: Matrix3f16) {
c1 := math.cos(-t1)
c2 := math.cos(-t2)
c3 := math.cos(-t3)
@@ -334,7 +373,8 @@ matrix3_from_euler_angles_xyz_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix3f16) {
return
}
matrix3_from_euler_angles_yxz_f16 :: proc(yaw, pitch, roll: f16) -> (m: Matrix3f16) {
@(require_results)
matrix3_from_euler_angles_yxz_f16 :: proc "contextless" (yaw, pitch, roll: f16) -> (m: Matrix3f16) {
ch := math.cos(yaw)
sh := math.sin(yaw)
cp := math.cos(pitch)
@@ -354,7 +394,8 @@ matrix3_from_euler_angles_yxz_f16 :: proc(yaw, pitch, roll: f16) -> (m: Matrix3f
return
}
matrix3_from_euler_angles_xzx_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix3f16) {
@(require_results)
matrix3_from_euler_angles_xzx_f16 :: proc "contextless" (t1, t2, t3: f16) -> (m: Matrix3f16) {
c1 := math.cos(t1)
s1 := math.sin(t1)
c2 := math.cos(t2)
@@ -374,7 +415,8 @@ matrix3_from_euler_angles_xzx_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix3f16) {
return
}
matrix3_from_euler_angles_xyx_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix3f16) {
@(require_results)
matrix3_from_euler_angles_xyx_f16 :: proc "contextless" (t1, t2, t3: f16) -> (m: Matrix3f16) {
c1 := math.cos(t1)
s1 := math.sin(t1)
c2 := math.cos(t2)
@@ -394,7 +436,8 @@ matrix3_from_euler_angles_xyx_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix3f16) {
return
}
matrix3_from_euler_angles_yxy_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix3f16) {
@(require_results)
matrix3_from_euler_angles_yxy_f16 :: proc "contextless" (t1, t2, t3: f16) -> (m: Matrix3f16) {
c1 := math.cos(t1)
s1 := math.sin(t1)
c2 := math.cos(t2)
@@ -414,7 +457,8 @@ matrix3_from_euler_angles_yxy_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix3f16) {
return
}
matrix3_from_euler_angles_yzy_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix3f16) {
@(require_results)
matrix3_from_euler_angles_yzy_f16 :: proc "contextless" (t1, t2, t3: f16) -> (m: Matrix3f16) {
c1 := math.cos(t1)
s1 := math.sin(t1)
c2 := math.cos(t2)
@@ -434,7 +478,8 @@ matrix3_from_euler_angles_yzy_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix3f16) {
return
}
matrix3_from_euler_angles_zyz_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix3f16) {
@(require_results)
matrix3_from_euler_angles_zyz_f16 :: proc "contextless" (t1, t2, t3: f16) -> (m: Matrix3f16) {
c1 := math.cos(t1)
s1 := math.sin(t1)
c2 := math.cos(t2)
@@ -454,7 +499,8 @@ matrix3_from_euler_angles_zyz_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix3f16) {
return
}
matrix3_from_euler_angles_zxz_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix3f16) {
@(require_results)
matrix3_from_euler_angles_zxz_f16 :: proc "contextless" (t1, t2, t3: f16) -> (m: Matrix3f16) {
c1 := math.cos(t1)
s1 := math.sin(t1)
c2 := math.cos(t2)
@@ -475,7 +521,8 @@ matrix3_from_euler_angles_zxz_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix3f16) {
}
matrix3_from_euler_angles_xzy_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix3f16) {
@(require_results)
matrix3_from_euler_angles_xzy_f16 :: proc "contextless" (t1, t2, t3: f16) -> (m: Matrix3f16) {
c1 := math.cos(t1)
s1 := math.sin(t1)
c2 := math.cos(t2)
@@ -495,7 +542,8 @@ matrix3_from_euler_angles_xzy_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix3f16) {
return
}
matrix3_from_euler_angles_yzx_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix3f16) {
@(require_results)
matrix3_from_euler_angles_yzx_f16 :: proc "contextless" (t1, t2, t3: f16) -> (m: Matrix3f16) {
c1 := math.cos(t1)
s1 := math.sin(t1)
c2 := math.cos(t2)
@@ -515,7 +563,8 @@ matrix3_from_euler_angles_yzx_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix3f16) {
return
}
matrix3_from_euler_angles_zyx_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix3f16) {
@(require_results)
matrix3_from_euler_angles_zyx_f16 :: proc "contextless" (t1, t2, t3: f16) -> (m: Matrix3f16) {
c1 := math.cos(t1)
s1 := math.sin(t1)
c2 := math.cos(t2)
@@ -535,7 +584,8 @@ matrix3_from_euler_angles_zyx_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix3f16) {
return
}
matrix3_from_euler_angles_zxy_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix3f16) {
@(require_results)
matrix3_from_euler_angles_zxy_f16 :: proc "contextless" (t1, t2, t3: f16) -> (m: Matrix3f16) {
c1 := math.cos(t1)
s1 := math.sin(t1)
c2 := math.cos(t2)
@@ -556,7 +606,8 @@ matrix3_from_euler_angles_zxy_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix3f16) {
}
matrix3_from_yaw_pitch_roll_f16 :: proc(yaw, pitch, roll: f16) -> (m: Matrix3f16) {
@(require_results)
matrix3_from_yaw_pitch_roll_f16 :: proc "contextless" (yaw, pitch, roll: f16) -> (m: Matrix3f16) {
ch := math.cos(yaw)
sh := math.sin(yaw)
cp := math.cos(pitch)
@@ -576,7 +627,8 @@ matrix3_from_yaw_pitch_roll_f16 :: proc(yaw, pitch, roll: f16) -> (m: Matrix3f16
return m
}
euler_angles_xyz_from_matrix3_f16 :: proc(m: Matrix3f16) -> (t1, t2, t3: f16) {
@(require_results)
euler_angles_xyz_from_matrix3_f16 :: proc "contextless" (m: Matrix3f16) -> (t1, t2, t3: f16) {
T1 := math.atan2(m[1, 2], m[2, 2])
C2 := math.sqrt(m[0, 0]*m[0, 0] + m[0, 1]*m[0, 1])
T2 := math.atan2(-m[0, 2], C2)
@@ -589,7 +641,8 @@ euler_angles_xyz_from_matrix3_f16 :: proc(m: Matrix3f16) -> (t1, t2, t3: f16) {
return
}
euler_angles_yxz_from_matrix3_f16 :: proc(m: Matrix3f16) -> (t1, t2, t3: f16) {
@(require_results)
euler_angles_yxz_from_matrix3_f16 :: proc "contextless" (m: Matrix3f16) -> (t1, t2, t3: f16) {
T1 := math.atan2(m[0, 2], m[2, 2])
C2 := math.sqrt(m[1, 0]*m[1, 0] + m[1, 1]*m[1, 1])
T2 := math.atan2(-m[1, 2], C2)
@@ -602,7 +655,8 @@ euler_angles_yxz_from_matrix3_f16 :: proc(m: Matrix3f16) -> (t1, t2, t3: f16) {
return
}
euler_angles_xzx_from_matrix3_f16 :: proc(m: Matrix3f16) -> (t1, t2, t3: f16) {
@(require_results)
euler_angles_xzx_from_matrix3_f16 :: proc "contextless" (m: Matrix3f16) -> (t1, t2, t3: f16) {
T1 := math.atan2(m[2, 0], m[1, 0])
S2 := math.sqrt(m[0, 1]*m[0, 1] + m[0, 2]*m[0, 2])
T2 := math.atan2(S2, m[0, 0])
@@ -615,7 +669,8 @@ euler_angles_xzx_from_matrix3_f16 :: proc(m: Matrix3f16) -> (t1, t2, t3: f16) {
return
}
euler_angles_xyx_from_matrix3_f16 :: proc(m: Matrix3f16) -> (t1, t2, t3: f16) {
@(require_results)
euler_angles_xyx_from_matrix3_f16 :: proc "contextless" (m: Matrix3f16) -> (t1, t2, t3: f16) {
T1 := math.atan2(m[1, 0], -m[2, 0])
S2 := math.sqrt(m[0, 1]*m[0, 1] + m[0, 2]*m[0, 2])
T2 := math.atan2(S2, m[0, 0])
@@ -628,7 +683,8 @@ euler_angles_xyx_from_matrix3_f16 :: proc(m: Matrix3f16) -> (t1, t2, t3: f16) {
return
}
euler_angles_yxy_from_matrix3_f16 :: proc(m: Matrix3f16) -> (t1, t2, t3: f16) {
@(require_results)
euler_angles_yxy_from_matrix3_f16 :: proc "contextless" (m: Matrix3f16) -> (t1, t2, t3: f16) {
T1 := math.atan2(m[0, 1], m[2, 1])
S2 := math.sqrt(m[1, 0]*m[1, 0] + m[1, 2]*m[1, 2])
T2 := math.atan2(S2, m[1, 1])
@@ -641,7 +697,8 @@ euler_angles_yxy_from_matrix3_f16 :: proc(m: Matrix3f16) -> (t1, t2, t3: f16) {
return
}
euler_angles_yzy_from_matrix3_f16 :: proc(m: Matrix3f16) -> (t1, t2, t3: f16) {
@(require_results)
euler_angles_yzy_from_matrix3_f16 :: proc "contextless" (m: Matrix3f16) -> (t1, t2, t3: f16) {
T1 := math.atan2(m[2, 1], -m[0, 1])
S2 := math.sqrt(m[1, 0]*m[1, 0] + m[1, 2]*m[1, 2])
T2 := math.atan2(S2, m[1, 1])
@@ -653,7 +710,8 @@ euler_angles_yzy_from_matrix3_f16 :: proc(m: Matrix3f16) -> (t1, t2, t3: f16) {
t3 = T3
return
}
euler_angles_zyz_from_matrix3_f16 :: proc(m: Matrix3f16) -> (t1, t2, t3: f16) {
@(require_results)
euler_angles_zyz_from_matrix3_f16 :: proc "contextless" (m: Matrix3f16) -> (t1, t2, t3: f16) {
T1 := math.atan2(m[1, 2], m[0, 2])
S2 := math.sqrt(m[2, 0]*m[2, 0] + m[2, 1]*m[2, 1])
T2 := math.atan2(S2, m[2, 2])
@@ -666,7 +724,8 @@ euler_angles_zyz_from_matrix3_f16 :: proc(m: Matrix3f16) -> (t1, t2, t3: f16) {
return
}
euler_angles_zxz_from_matrix3_f16 :: proc(m: Matrix3f16) -> (t1, t2, t3: f16) {
@(require_results)
euler_angles_zxz_from_matrix3_f16 :: proc "contextless" (m: Matrix3f16) -> (t1, t2, t3: f16) {
T1 := math.atan2(m[0, 2], -m[1, 2])
S2 := math.sqrt(m[2, 0]*m[2, 0] + m[2, 1]*m[2, 1])
T2 := math.atan2(S2, m[2, 2])
@@ -679,7 +738,8 @@ euler_angles_zxz_from_matrix3_f16 :: proc(m: Matrix3f16) -> (t1, t2, t3: f16) {
return
}
euler_angles_xzy_from_matrix3_f16 :: proc(m: Matrix3f16) -> (t1, t2, t3: f16) {
@(require_results)
euler_angles_xzy_from_matrix3_f16 :: proc "contextless" (m: Matrix3f16) -> (t1, t2, t3: f16) {
T1 := math.atan2(m[2, 1], m[1, 1])
C2 := math.sqrt(m[0, 0]*m[0, 0] + m[0, 2]*m[0, 2])
T2 := math.atan2(-m[0, 1], C2)
@@ -692,7 +752,8 @@ euler_angles_xzy_from_matrix3_f16 :: proc(m: Matrix3f16) -> (t1, t2, t3: f16) {
return
}
euler_angles_yzx_from_matrix3_f16 :: proc(m: Matrix3f16) -> (t1, t2, t3: f16) {
@(require_results)
euler_angles_yzx_from_matrix3_f16 :: proc "contextless" (m: Matrix3f16) -> (t1, t2, t3: f16) {
T1 := math.atan2(-m[2, 0], m[0, 0])
C2 := math.sqrt(m[1, 1]*m[1, 1] + m[1, 2]*m[1, 2])
T2 := math.atan2(m[1, 0], C2)
@@ -705,7 +766,8 @@ euler_angles_yzx_from_matrix3_f16 :: proc(m: Matrix3f16) -> (t1, t2, t3: f16) {
return
}
euler_angles_zyx_from_matrix3_f16 :: proc(m: Matrix3f16) -> (t1, t2, t3: f16) {
@(require_results)
euler_angles_zyx_from_matrix3_f16 :: proc "contextless" (m: Matrix3f16) -> (t1, t2, t3: f16) {
T1 := math.atan2(m[1, 0], m[0, 0])
C2 := math.sqrt(m[2, 1]*m[2, 1] + m[2, 2]*m[2, 2])
T2 := math.atan2(-m[2, 0], C2)
@@ -718,7 +780,8 @@ euler_angles_zyx_from_matrix3_f16 :: proc(m: Matrix3f16) -> (t1, t2, t3: f16) {
return
}
euler_angles_zxy_from_matrix3_f16 :: proc(m: Matrix3f16) -> (t1, t2, t3: f16) {
@(require_results)
euler_angles_zxy_from_matrix3_f16 :: proc "contextless" (m: Matrix3f16) -> (t1, t2, t3: f16) {
T1 := math.atan2(-m[0, 1], m[1, 1])
C2 := math.sqrt(m[2, 0]*m[2, 0] + m[2, 2]*m[2, 2])
T2 := math.atan2(m[2, 1], C2)
@@ -735,7 +798,8 @@ euler_angles_zxy_from_matrix3_f16 :: proc(m: Matrix3f16) -> (t1, t2, t3: f16) {
// Matrix4
matrix4_from_euler_angle_x_f16 :: proc(angle_x: f16) -> (m: Matrix4f16) {
@(require_results)
matrix4_from_euler_angle_x_f16 :: proc "contextless" (angle_x: f16) -> (m: Matrix4f16) {
cos_x, sin_x := math.cos(angle_x), math.sin(angle_x)
m[0, 0] = 1
m[1, 1] = +cos_x
@@ -745,7 +809,8 @@ matrix4_from_euler_angle_x_f16 :: proc(angle_x: f16) -> (m: Matrix4f16) {
m[3, 3] = 1
return
}
matrix4_from_euler_angle_y_f16 :: proc(angle_y: f16) -> (m: Matrix4f16) {
@(require_results)
matrix4_from_euler_angle_y_f16 :: proc "contextless" (angle_y: f16) -> (m: Matrix4f16) {
cos_y, sin_y := math.cos(angle_y), math.sin(angle_y)
m[0, 0] = +cos_y
m[0, 2] = -sin_y
@@ -755,7 +820,8 @@ matrix4_from_euler_angle_y_f16 :: proc(angle_y: f16) -> (m: Matrix4f16) {
m[3, 3] = 1
return
}
matrix4_from_euler_angle_z_f16 :: proc(angle_z: f16) -> (m: Matrix4f16) {
@(require_results)
matrix4_from_euler_angle_z_f16 :: proc "contextless" (angle_z: f16) -> (m: Matrix4f16) {
cos_z, sin_z := math.cos(angle_z), math.sin(angle_z)
m[0, 0] = +cos_z
m[0, 1] = +sin_z
@@ -767,7 +833,8 @@ matrix4_from_euler_angle_z_f16 :: proc(angle_z: f16) -> (m: Matrix4f16) {
}
matrix4_from_derived_euler_angle_x_f16 :: proc(angle_x: f16, angular_velocity_x: f16) -> (m: Matrix4f16) {
@(require_results)
matrix4_from_derived_euler_angle_x_f16 :: proc "contextless" (angle_x: f16, angular_velocity_x: f16) -> (m: Matrix4f16) {
cos_x := math.cos(angle_x) * angular_velocity_x
sin_x := math.sin(angle_x) * angular_velocity_x
m[0, 0] = 1
@@ -778,7 +845,8 @@ matrix4_from_derived_euler_angle_x_f16 :: proc(angle_x: f16, angular_velocity_x:
m[3, 3] = 1
return
}
matrix4_from_derived_euler_angle_y_f16 :: proc(angle_y: f16, angular_velocity_y: f16) -> (m: Matrix4f16) {
@(require_results)
matrix4_from_derived_euler_angle_y_f16 :: proc "contextless" (angle_y: f16, angular_velocity_y: f16) -> (m: Matrix4f16) {
cos_y := math.cos(angle_y) * angular_velocity_y
sin_y := math.sin(angle_y) * angular_velocity_y
m[0, 0] = +cos_y
@@ -789,7 +857,8 @@ matrix4_from_derived_euler_angle_y_f16 :: proc(angle_y: f16, angular_velocity_y:
m[3, 3] = 1
return
}
matrix4_from_derived_euler_angle_z_f16 :: proc(angle_z: f16, angular_velocity_z: f16) -> (m: Matrix4f16) {
@(require_results)
matrix4_from_derived_euler_angle_z_f16 :: proc "contextless" (angle_z: f16, angular_velocity_z: f16) -> (m: Matrix4f16) {
cos_z := math.cos(angle_z) * angular_velocity_z
sin_z := math.sin(angle_z) * angular_velocity_z
m[0, 0] = +cos_z
@@ -802,7 +871,8 @@ matrix4_from_derived_euler_angle_z_f16 :: proc(angle_z: f16, angular_velocity_z:
}
matrix4_from_euler_angles_xy_f16 :: proc(angle_x, angle_y: f16) -> (m: Matrix4f16) {
@(require_results)
matrix4_from_euler_angles_xy_f16 :: proc "contextless" (angle_x, angle_y: f16) -> (m: Matrix4f16) {
cos_x, sin_x := math.cos(angle_x), math.sin(angle_x)
cos_y, sin_y := math.cos(angle_y), math.sin(angle_y)
m[0, 0] = cos_y
@@ -818,7 +888,8 @@ matrix4_from_euler_angles_xy_f16 :: proc(angle_x, angle_y: f16) -> (m: Matrix4f1
}
matrix4_from_euler_angles_yx_f16 :: proc(angle_y, angle_x: f16) -> (m: Matrix4f16) {
@(require_results)
matrix4_from_euler_angles_yx_f16 :: proc "contextless" (angle_y, angle_x: f16) -> (m: Matrix4f16) {
cos_x, sin_x := math.cos(angle_x), math.sin(angle_x)
cos_y, sin_y := math.cos(angle_y), math.sin(angle_y)
m[0, 0] = cos_y
@@ -833,21 +904,26 @@ matrix4_from_euler_angles_yx_f16 :: proc(angle_y, angle_x: f16) -> (m: Matrix4f1
return
}
matrix4_from_euler_angles_xz_f16 :: proc(angle_x, angle_z: f16) -> (m: Matrix4f16) {
@(require_results)
matrix4_from_euler_angles_xz_f16 :: proc "contextless" (angle_x, angle_z: f16) -> (m: Matrix4f16) {
return mul(matrix4_from_euler_angle_x(angle_x), matrix4_from_euler_angle_z(angle_z))
}
matrix4_from_euler_angles_zx_f16 :: proc(angle_z, angle_x: f16) -> (m: Matrix4f16) {
@(require_results)
matrix4_from_euler_angles_zx_f16 :: proc "contextless" (angle_z, angle_x: f16) -> (m: Matrix4f16) {
return mul(matrix4_from_euler_angle_z(angle_z), matrix4_from_euler_angle_x(angle_x))
}
matrix4_from_euler_angles_yz_f16 :: proc(angle_y, angle_z: f16) -> (m: Matrix4f16) {
@(require_results)
matrix4_from_euler_angles_yz_f16 :: proc "contextless" (angle_y, angle_z: f16) -> (m: Matrix4f16) {
return mul(matrix4_from_euler_angle_y(angle_y), matrix4_from_euler_angle_z(angle_z))
}
matrix4_from_euler_angles_zy_f16 :: proc(angle_z, angle_y: f16) -> (m: Matrix4f16) {
@(require_results)
matrix4_from_euler_angles_zy_f16 :: proc "contextless" (angle_z, angle_y: f16) -> (m: Matrix4f16) {
return mul(matrix4_from_euler_angle_z(angle_z), matrix4_from_euler_angle_y(angle_y))
}
matrix4_from_euler_angles_xyz_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix4f16) {
@(require_results)
matrix4_from_euler_angles_xyz_f16 :: proc "contextless" (t1, t2, t3: f16) -> (m: Matrix4f16) {
c1 := math.cos(-t1)
c2 := math.cos(-t2)
c3 := math.cos(-t3)
@@ -874,7 +950,8 @@ matrix4_from_euler_angles_xyz_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix4f16) {
return
}
matrix4_from_euler_angles_yxz_f16 :: proc(yaw, pitch, roll: f16) -> (m: Matrix4f16) {
@(require_results)
matrix4_from_euler_angles_yxz_f16 :: proc "contextless" (yaw, pitch, roll: f16) -> (m: Matrix4f16) {
ch := math.cos(yaw)
sh := math.sin(yaw)
cp := math.cos(pitch)
@@ -901,7 +978,8 @@ matrix4_from_euler_angles_yxz_f16 :: proc(yaw, pitch, roll: f16) -> (m: Matrix4f
return
}
matrix4_from_euler_angles_xzx_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix4f16) {
@(require_results)
matrix4_from_euler_angles_xzx_f16 :: proc "contextless" (t1, t2, t3: f16) -> (m: Matrix4f16) {
c1 := math.cos(t1)
s1 := math.sin(t1)
c2 := math.cos(t2)
@@ -928,7 +1006,8 @@ matrix4_from_euler_angles_xzx_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix4f16) {
return
}
matrix4_from_euler_angles_xyx_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix4f16) {
@(require_results)
matrix4_from_euler_angles_xyx_f16 :: proc "contextless" (t1, t2, t3: f16) -> (m: Matrix4f16) {
c1 := math.cos(t1)
s1 := math.sin(t1)
c2 := math.cos(t2)
@@ -955,7 +1034,8 @@ matrix4_from_euler_angles_xyx_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix4f16) {
return
}
matrix4_from_euler_angles_yxy_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix4f16) {
@(require_results)
matrix4_from_euler_angles_yxy_f16 :: proc "contextless" (t1, t2, t3: f16) -> (m: Matrix4f16) {
c1 := math.cos(t1)
s1 := math.sin(t1)
c2 := math.cos(t2)
@@ -982,7 +1062,8 @@ matrix4_from_euler_angles_yxy_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix4f16) {
return
}
matrix4_from_euler_angles_yzy_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix4f16) {
@(require_results)
matrix4_from_euler_angles_yzy_f16 :: proc "contextless" (t1, t2, t3: f16) -> (m: Matrix4f16) {
c1 := math.cos(t1)
s1 := math.sin(t1)
c2 := math.cos(t2)
@@ -1009,7 +1090,8 @@ matrix4_from_euler_angles_yzy_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix4f16) {
return
}
matrix4_from_euler_angles_zyz_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix4f16) {
@(require_results)
matrix4_from_euler_angles_zyz_f16 :: proc "contextless" (t1, t2, t3: f16) -> (m: Matrix4f16) {
c1 := math.cos(t1)
s1 := math.sin(t1)
c2 := math.cos(t2)
@@ -1036,7 +1118,8 @@ matrix4_from_euler_angles_zyz_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix4f16) {
return
}
matrix4_from_euler_angles_zxz_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix4f16) {
@(require_results)
matrix4_from_euler_angles_zxz_f16 :: proc "contextless" (t1, t2, t3: f16) -> (m: Matrix4f16) {
c1 := math.cos(t1)
s1 := math.sin(t1)
c2 := math.cos(t2)
@@ -1064,7 +1147,8 @@ matrix4_from_euler_angles_zxz_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix4f16) {
}
matrix4_from_euler_angles_xzy_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix4f16) {
@(require_results)
matrix4_from_euler_angles_xzy_f16 :: proc "contextless" (t1, t2, t3: f16) -> (m: Matrix4f16) {
c1 := math.cos(t1)
s1 := math.sin(t1)
c2 := math.cos(t2)
@@ -1091,7 +1175,8 @@ matrix4_from_euler_angles_xzy_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix4f16) {
return
}
matrix4_from_euler_angles_yzx_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix4f16) {
@(require_results)
matrix4_from_euler_angles_yzx_f16 :: proc "contextless" (t1, t2, t3: f16) -> (m: Matrix4f16) {
c1 := math.cos(t1)
s1 := math.sin(t1)
c2 := math.cos(t2)
@@ -1118,7 +1203,8 @@ matrix4_from_euler_angles_yzx_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix4f16) {
return
}
matrix4_from_euler_angles_zyx_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix4f16) {
@(require_results)
matrix4_from_euler_angles_zyx_f16 :: proc "contextless" (t1, t2, t3: f16) -> (m: Matrix4f16) {
c1 := math.cos(t1)
s1 := math.sin(t1)
c2 := math.cos(t2)
@@ -1145,7 +1231,8 @@ matrix4_from_euler_angles_zyx_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix4f16) {
return
}
matrix4_from_euler_angles_zxy_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix4f16) {
@(require_results)
matrix4_from_euler_angles_zxy_f16 :: proc "contextless" (t1, t2, t3: f16) -> (m: Matrix4f16) {
c1 := math.cos(t1)
s1 := math.sin(t1)
c2 := math.cos(t2)
@@ -1173,7 +1260,8 @@ matrix4_from_euler_angles_zxy_f16 :: proc(t1, t2, t3: f16) -> (m: Matrix4f16) {
}
matrix4_from_yaw_pitch_roll_f16 :: proc(yaw, pitch, roll: f16) -> (m: Matrix4f16) {
@(require_results)
matrix4_from_yaw_pitch_roll_f16 :: proc "contextless" (yaw, pitch, roll: f16) -> (m: Matrix4f16) {
ch := math.cos(yaw)
sh := math.sin(yaw)
cp := math.cos(pitch)
@@ -1200,7 +1288,8 @@ matrix4_from_yaw_pitch_roll_f16 :: proc(yaw, pitch, roll: f16) -> (m: Matrix4f16
return m
}
euler_angles_xyz_from_matrix4_f16 :: proc(m: Matrix4f16) -> (t1, t2, t3: f16) {
@(require_results)
euler_angles_xyz_from_matrix4_f16 :: proc "contextless" (m: Matrix4f16) -> (t1, t2, t3: f16) {
T1 := math.atan2(m[1, 2], m[2, 2])
C2 := math.sqrt(m[0, 0]*m[0, 0] + m[0, 1]*m[0, 1])
T2 := math.atan2(-m[0, 2], C2)
@@ -1213,7 +1302,8 @@ euler_angles_xyz_from_matrix4_f16 :: proc(m: Matrix4f16) -> (t1, t2, t3: f16) {
return
}
euler_angles_yxz_from_matrix4_f16 :: proc(m: Matrix4f16) -> (t1, t2, t3: f16) {
@(require_results)
euler_angles_yxz_from_matrix4_f16 :: proc "contextless" (m: Matrix4f16) -> (t1, t2, t3: f16) {
T1 := math.atan2(m[0, 2], m[2, 2])
C2 := math.sqrt(m[1, 0]*m[1, 0] + m[1, 1]*m[1, 1])
T2 := math.atan2(-m[1, 2], C2)
@@ -1226,7 +1316,8 @@ euler_angles_yxz_from_matrix4_f16 :: proc(m: Matrix4f16) -> (t1, t2, t3: f16) {
return
}
euler_angles_xzx_from_matrix4_f16 :: proc(m: Matrix4f16) -> (t1, t2, t3: f16) {
@(require_results)
euler_angles_xzx_from_matrix4_f16 :: proc "contextless" (m: Matrix4f16) -> (t1, t2, t3: f16) {
T1 := math.atan2(m[2, 0], m[1, 0])
S2 := math.sqrt(m[0, 1]*m[0, 1] + m[0, 2]*m[0, 2])
T2 := math.atan2(S2, m[0, 0])
@@ -1239,7 +1330,8 @@ euler_angles_xzx_from_matrix4_f16 :: proc(m: Matrix4f16) -> (t1, t2, t3: f16) {
return
}
euler_angles_xyx_from_matrix4_f16 :: proc(m: Matrix4f16) -> (t1, t2, t3: f16) {
@(require_results)
euler_angles_xyx_from_matrix4_f16 :: proc "contextless" (m: Matrix4f16) -> (t1, t2, t3: f16) {
T1 := math.atan2(m[1, 0], -m[2, 0])
S2 := math.sqrt(m[0, 1]*m[0, 1] + m[0, 2]*m[0, 2])
T2 := math.atan2(S2, m[0, 0])
@@ -1252,7 +1344,8 @@ euler_angles_xyx_from_matrix4_f16 :: proc(m: Matrix4f16) -> (t1, t2, t3: f16) {
return
}
euler_angles_yxy_from_matrix4_f16 :: proc(m: Matrix4f16) -> (t1, t2, t3: f16) {
@(require_results)
euler_angles_yxy_from_matrix4_f16 :: proc "contextless" (m: Matrix4f16) -> (t1, t2, t3: f16) {
T1 := math.atan2(m[0, 1], m[2, 1])
S2 := math.sqrt(m[1, 0]*m[1, 0] + m[1, 2]*m[1, 2])
T2 := math.atan2(S2, m[1, 1])
@@ -1265,7 +1358,8 @@ euler_angles_yxy_from_matrix4_f16 :: proc(m: Matrix4f16) -> (t1, t2, t3: f16) {
return
}
euler_angles_yzy_from_matrix4_f16 :: proc(m: Matrix4f16) -> (t1, t2, t3: f16) {
@(require_results)
euler_angles_yzy_from_matrix4_f16 :: proc "contextless" (m: Matrix4f16) -> (t1, t2, t3: f16) {
T1 := math.atan2(m[2, 1], -m[0, 1])
S2 := math.sqrt(m[1, 0]*m[1, 0] + m[1, 2]*m[1, 2])
T2 := math.atan2(S2, m[1, 1])
@@ -1277,7 +1371,8 @@ euler_angles_yzy_from_matrix4_f16 :: proc(m: Matrix4f16) -> (t1, t2, t3: f16) {
t3 = T3
return
}
euler_angles_zyz_from_matrix4_f16 :: proc(m: Matrix4f16) -> (t1, t2, t3: f16) {
@(require_results)
euler_angles_zyz_from_matrix4_f16 :: proc "contextless" (m: Matrix4f16) -> (t1, t2, t3: f16) {
T1 := math.atan2(m[1, 2], m[0, 2])
S2 := math.sqrt(m[2, 0]*m[2, 0] + m[2, 1]*m[2, 1])
T2 := math.atan2(S2, m[2, 2])
@@ -1290,7 +1385,8 @@ euler_angles_zyz_from_matrix4_f16 :: proc(m: Matrix4f16) -> (t1, t2, t3: f16) {
return
}
euler_angles_zxz_from_matrix4_f16 :: proc(m: Matrix4f16) -> (t1, t2, t3: f16) {
@(require_results)
euler_angles_zxz_from_matrix4_f16 :: proc "contextless" (m: Matrix4f16) -> (t1, t2, t3: f16) {
T1 := math.atan2(m[0, 2], -m[1, 2])
S2 := math.sqrt(m[2, 0]*m[2, 0] + m[2, 1]*m[2, 1])
T2 := math.atan2(S2, m[2, 2])
@@ -1303,7 +1399,8 @@ euler_angles_zxz_from_matrix4_f16 :: proc(m: Matrix4f16) -> (t1, t2, t3: f16) {
return
}
euler_angles_xzy_from_matrix4_f16 :: proc(m: Matrix4f16) -> (t1, t2, t3: f16) {
@(require_results)
euler_angles_xzy_from_matrix4_f16 :: proc "contextless" (m: Matrix4f16) -> (t1, t2, t3: f16) {
T1 := math.atan2(m[2, 1], m[1, 1])
C2 := math.sqrt(m[0, 0]*m[0, 0] + m[0, 2]*m[0, 2])
T2 := math.atan2(-m[0, 1], C2)
@@ -1316,7 +1413,8 @@ euler_angles_xzy_from_matrix4_f16 :: proc(m: Matrix4f16) -> (t1, t2, t3: f16) {
return
}
euler_angles_yzx_from_matrix4_f16 :: proc(m: Matrix4f16) -> (t1, t2, t3: f16) {
@(require_results)
euler_angles_yzx_from_matrix4_f16 :: proc "contextless" (m: Matrix4f16) -> (t1, t2, t3: f16) {
T1 := math.atan2(-m[2, 0], m[0, 0])
C2 := math.sqrt(m[1, 1]*m[1, 1] + m[1, 2]*m[1, 2])
T2 := math.atan2(m[1, 0], C2)
@@ -1329,7 +1427,8 @@ euler_angles_yzx_from_matrix4_f16 :: proc(m: Matrix4f16) -> (t1, t2, t3: f16) {
return
}
euler_angles_zyx_from_matrix4_f16 :: proc(m: Matrix4f16) -> (t1, t2, t3: f16) {
@(require_results)
euler_angles_zyx_from_matrix4_f16 :: proc "contextless" (m: Matrix4f16) -> (t1, t2, t3: f16) {
T1 := math.atan2(m[1, 0], m[0, 0])
C2 := math.sqrt(m[2, 1]*m[2, 1] + m[2, 2]*m[2, 2])
T2 := math.atan2(-m[2, 0], C2)
@@ -1342,7 +1441,8 @@ euler_angles_zyx_from_matrix4_f16 :: proc(m: Matrix4f16) -> (t1, t2, t3: f16) {
return
}
euler_angles_zxy_from_matrix4_f16 :: proc(m: Matrix4f16) -> (t1, t2, t3: f16) {
@(require_results)
euler_angles_zxy_from_matrix4_f16 :: proc "contextless" (m: Matrix4f16) -> (t1, t2, t3: f16) {
T1 := math.atan2(-m[0, 1], m[1, 1])
C2 := math.sqrt(m[2, 0]*m[2, 0] + m[2, 2]*m[2, 2])
T2 := math.atan2(m[2, 1], C2)
+200 -100
View File
@@ -2,7 +2,8 @@ package linalg
import "core:math"
euler_angles_from_matrix3_f32 :: proc(m: Matrix3f32, order: Euler_Angle_Order) -> (t1, t2, t3: f32) {
@(require_results)
euler_angles_from_matrix3_f32 :: proc "contextless" (m: Matrix3f32, order: Euler_Angle_Order) -> (t1, t2, t3: f32) {
switch order {
case .XYZ: t1, t2, t3 = euler_angles_xyz_from_matrix3(m)
case .XZY: t1, t2, t3 = euler_angles_xzy_from_matrix3(m)
@@ -19,7 +20,8 @@ euler_angles_from_matrix3_f32 :: proc(m: Matrix3f32, order: Euler_Angle_Order) -
}
return
}
euler_angles_from_matrix4_f32 :: proc(m: Matrix4f32, order: Euler_Angle_Order) -> (t1, t2, t3: f32) {
@(require_results)
euler_angles_from_matrix4_f32 :: proc "contextless" (m: Matrix4f32, order: Euler_Angle_Order) -> (t1, t2, t3: f32) {
switch order {
case .XYZ: t1, t2, t3 = euler_angles_xyz_from_matrix4(m)
case .XZY: t1, t2, t3 = euler_angles_xzy_from_matrix4(m)
@@ -36,7 +38,8 @@ euler_angles_from_matrix4_f32 :: proc(m: Matrix4f32, order: Euler_Angle_Order) -
}
return
}
euler_angles_from_quaternion_f32 :: proc(m: Quaternionf32, order: Euler_Angle_Order) -> (t1, t2, t3: f32) {
@(require_results)
euler_angles_from_quaternion_f32 :: proc "contextless" (m: Quaternionf32, order: Euler_Angle_Order) -> (t1, t2, t3: f32) {
switch order {
case .XYZ: t1, t2, t3 = euler_angles_xyz_from_quaternion(m)
case .XZY: t1, t2, t3 = euler_angles_xzy_from_quaternion(m)
@@ -54,7 +57,8 @@ euler_angles_from_quaternion_f32 :: proc(m: Quaternionf32, order: Euler_Angle_Or
return
}
matrix3_from_euler_angles_f32 :: proc(t1, t2, t3: f32, order: Euler_Angle_Order) -> (m: Matrix3f32) {
@(require_results)
matrix3_from_euler_angles_f32 :: proc "contextless" (t1, t2, t3: f32, order: Euler_Angle_Order) -> (m: Matrix3f32) {
switch order {
case .XYZ: return matrix3_from_euler_angles_xyz(t1, t2, t3) // m1, m2, m3 = X(t1), Y(t2), Z(t3);
case .XZY: return matrix3_from_euler_angles_xzy(t1, t2, t3) // m1, m2, m3 = X(t1), Z(t2), Y(t3);
@@ -71,7 +75,8 @@ matrix3_from_euler_angles_f32 :: proc(t1, t2, t3: f32, order: Euler_Angle_Order)
}
return
}
matrix4_from_euler_angles_f32 :: proc(t1, t2, t3: f32, order: Euler_Angle_Order) -> (m: Matrix4f32) {
@(require_results)
matrix4_from_euler_angles_f32 :: proc "contextless" (t1, t2, t3: f32, order: Euler_Angle_Order) -> (m: Matrix4f32) {
switch order {
case .XYZ: return matrix4_from_euler_angles_xyz(t1, t2, t3) // m1, m2, m3 = X(t1), Y(t2), Z(t3);
case .XZY: return matrix4_from_euler_angles_xzy(t1, t2, t3) // m1, m2, m3 = X(t1), Z(t2), Y(t3);
@@ -89,7 +94,8 @@ matrix4_from_euler_angles_f32 :: proc(t1, t2, t3: f32, order: Euler_Angle_Order)
return
}
quaternion_from_euler_angles_f32 :: proc(t1, t2, t3: f32, order: Euler_Angle_Order) -> Quaternionf32 {
@(require_results)
quaternion_from_euler_angles_f32 :: proc "contextless" (t1, t2, t3: f32, order: Euler_Angle_Order) -> Quaternionf32 {
X :: quaternion_from_euler_angle_x
Y :: quaternion_from_euler_angle_y
Z :: quaternion_from_euler_angle_z
@@ -117,17 +123,21 @@ quaternion_from_euler_angles_f32 :: proc(t1, t2, t3: f32, order: Euler_Angle_Ord
// Quaternionf32s
quaternion_from_euler_angle_x_f32 :: proc(angle_x: f32) -> (q: Quaternionf32) {
@(require_results)
quaternion_from_euler_angle_x_f32 :: proc "contextless" (angle_x: f32) -> (q: Quaternionf32) {
return quaternion_angle_axis_f32(angle_x, {1, 0, 0})
}
quaternion_from_euler_angle_y_f32 :: proc(angle_y: f32) -> (q: Quaternionf32) {
@(require_results)
quaternion_from_euler_angle_y_f32 :: proc "contextless" (angle_y: f32) -> (q: Quaternionf32) {
return quaternion_angle_axis_f32(angle_y, {0, 1, 0})
}
quaternion_from_euler_angle_z_f32 :: proc(angle_z: f32) -> (q: Quaternionf32) {
@(require_results)
quaternion_from_euler_angle_z_f32 :: proc "contextless" (angle_z: f32) -> (q: Quaternionf32) {
return quaternion_angle_axis_f32(angle_z, {0, 0, 1})
}
quaternion_from_pitch_yaw_roll_f32 :: proc(pitch, yaw, roll: f32) -> Quaternionf32 {
@(require_results)
quaternion_from_pitch_yaw_roll_f32 :: proc "contextless" (pitch, yaw, roll: f32) -> Quaternionf32 {
a, b, c := pitch, yaw, roll
ca, sa := math.cos(a*0.5), math.sin(a*0.5)
@@ -142,11 +152,13 @@ quaternion_from_pitch_yaw_roll_f32 :: proc(pitch, yaw, roll: f32) -> Quaternionf
return q
}
roll_from_quaternion_f32 :: proc(q: Quaternionf32) -> f32 {
@(require_results)
roll_from_quaternion_f32 :: proc "contextless" (q: Quaternionf32) -> f32 {
return math.atan2(2 * q.x*q.y + q.w*q.z, q.w*q.w + q.x*q.x - q.y*q.y - q.z*q.z)
}
pitch_from_quaternion_f32 :: proc(q: Quaternionf32) -> f32 {
@(require_results)
pitch_from_quaternion_f32 :: proc "contextless" (q: Quaternionf32) -> f32 {
y := 2 * (q.y*q.z + q.w*q.w)
x := q.w*q.w - q.x*q.x - q.y*q.y + q.z*q.z
@@ -157,52 +169,66 @@ pitch_from_quaternion_f32 :: proc(q: Quaternionf32) -> f32 {
return math.atan2(y, x)
}
yaw_from_quaternion_f32 :: proc(q: Quaternionf32) -> f32 {
@(require_results)
yaw_from_quaternion_f32 :: proc "contextless" (q: Quaternionf32) -> f32 {
return math.asin(clamp(-2 * (q.x*q.z - q.w*q.y), -1, 1))
}
pitch_yaw_roll_from_quaternion_f32 :: proc(q: Quaternionf32) -> (pitch, yaw, roll: f32) {
@(require_results)
pitch_yaw_roll_from_quaternion_f32 :: proc "contextless" (q: Quaternionf32) -> (pitch, yaw, roll: f32) {
pitch = pitch_from_quaternion(q)
yaw = yaw_from_quaternion(q)
roll = roll_from_quaternion(q)
return
}
euler_angles_xyz_from_quaternion_f32 :: proc(q: Quaternionf32) -> (t1, t2, t3: f32) {
@(require_results)
euler_angles_xyz_from_quaternion_f32 :: proc "contextless" (q: Quaternionf32) -> (t1, t2, t3: f32) {
return euler_angles_xyz_from_matrix4(matrix4_from_quaternion(q))
}
euler_angles_yxz_from_quaternion_f32 :: proc(q: Quaternionf32) -> (t1, t2, t3: f32) {
@(require_results)
euler_angles_yxz_from_quaternion_f32 :: proc "contextless" (q: Quaternionf32) -> (t1, t2, t3: f32) {
return euler_angles_yxz_from_matrix4(matrix4_from_quaternion(q))
}
euler_angles_xzx_from_quaternion_f32 :: proc(q: Quaternionf32) -> (t1, t2, t3: f32) {
@(require_results)
euler_angles_xzx_from_quaternion_f32 :: proc "contextless" (q: Quaternionf32) -> (t1, t2, t3: f32) {
return euler_angles_xzx_from_matrix4(matrix4_from_quaternion(q))
}
euler_angles_xyx_from_quaternion_f32 :: proc(q: Quaternionf32) -> (t1, t2, t3: f32) {
@(require_results)
euler_angles_xyx_from_quaternion_f32 :: proc "contextless" (q: Quaternionf32) -> (t1, t2, t3: f32) {
return euler_angles_xyx_from_matrix4(matrix4_from_quaternion(q))
}
euler_angles_yxy_from_quaternion_f32 :: proc(q: Quaternionf32) -> (t1, t2, t3: f32) {
@(require_results)
euler_angles_yxy_from_quaternion_f32 :: proc "contextless" (q: Quaternionf32) -> (t1, t2, t3: f32) {
return euler_angles_yxy_from_matrix4(matrix4_from_quaternion(q))
}
euler_angles_yzy_from_quaternion_f32 :: proc(q: Quaternionf32) -> (t1, t2, t3: f32) {
@(require_results)
euler_angles_yzy_from_quaternion_f32 :: proc "contextless" (q: Quaternionf32) -> (t1, t2, t3: f32) {
return euler_angles_yzy_from_matrix4(matrix4_from_quaternion(q))
}
euler_angles_zyz_from_quaternion_f32 :: proc(q: Quaternionf32) -> (t1, t2, t3: f32) {
@(require_results)
euler_angles_zyz_from_quaternion_f32 :: proc "contextless" (q: Quaternionf32) -> (t1, t2, t3: f32) {
return euler_angles_zyz_from_matrix4(matrix4_from_quaternion(q))
}
euler_angles_zxz_from_quaternion_f32 :: proc(q: Quaternionf32) -> (t1, t2, t3: f32) {
@(require_results)
euler_angles_zxz_from_quaternion_f32 :: proc "contextless" (q: Quaternionf32) -> (t1, t2, t3: f32) {
return euler_angles_zxz_from_matrix4(matrix4_from_quaternion(q))
}
euler_angles_xzy_from_quaternion_f32 :: proc(q: Quaternionf32) -> (t1, t2, t3: f32) {
@(require_results)
euler_angles_xzy_from_quaternion_f32 :: proc "contextless" (q: Quaternionf32) -> (t1, t2, t3: f32) {
return euler_angles_xzy_from_matrix4(matrix4_from_quaternion(q))
}
euler_angles_yzx_from_quaternion_f32 :: proc(q: Quaternionf32) -> (t1, t2, t3: f32) {
@(require_results)
euler_angles_yzx_from_quaternion_f32 :: proc "contextless" (q: Quaternionf32) -> (t1, t2, t3: f32) {
return euler_angles_yzx_from_matrix4(matrix4_from_quaternion(q))
}
euler_angles_zyx_from_quaternion_f32 :: proc(q: Quaternionf32) -> (t1, t2, t3: f32) {
@(require_results)
euler_angles_zyx_from_quaternion_f32 :: proc "contextless" (q: Quaternionf32) -> (t1, t2, t3: f32) {
return euler_angles_zyx_from_matrix4(matrix4_from_quaternion(q))
}
euler_angles_zxy_from_quaternion_f32 :: proc(q: Quaternionf32) -> (t1, t2, t3: f32) {
@(require_results)
euler_angles_zxy_from_quaternion_f32 :: proc "contextless" (q: Quaternionf32) -> (t1, t2, t3: f32) {
return euler_angles_zxy_from_matrix4(matrix4_from_quaternion(q))
}
@@ -210,7 +236,8 @@ euler_angles_zxy_from_quaternion_f32 :: proc(q: Quaternionf32) -> (t1, t2, t3: f
// Matrix3
matrix3_from_euler_angle_x_f32 :: proc(angle_x: f32) -> (m: Matrix3f32) {
@(require_results)
matrix3_from_euler_angle_x_f32 :: proc "contextless" (angle_x: f32) -> (m: Matrix3f32) {
cos_x, sin_x := math.cos(angle_x), math.sin(angle_x)
m[0, 0] = 1
m[1, 1] = +cos_x
@@ -219,7 +246,8 @@ matrix3_from_euler_angle_x_f32 :: proc(angle_x: f32) -> (m: Matrix3f32) {
m[2, 2] = +cos_x
return
}
matrix3_from_euler_angle_y_f32 :: proc(angle_y: f32) -> (m: Matrix3f32) {
@(require_results)
matrix3_from_euler_angle_y_f32 :: proc "contextless" (angle_y: f32) -> (m: Matrix3f32) {
cos_y, sin_y := math.cos(angle_y), math.sin(angle_y)
m[0, 0] = +cos_y
m[0, 2] = -sin_y
@@ -228,7 +256,8 @@ matrix3_from_euler_angle_y_f32 :: proc(angle_y: f32) -> (m: Matrix3f32) {
m[2, 2] = +cos_y
return
}
matrix3_from_euler_angle_z_f32 :: proc(angle_z: f32) -> (m: Matrix3f32) {
@(require_results)
matrix3_from_euler_angle_z_f32 :: proc "contextless" (angle_z: f32) -> (m: Matrix3f32) {
cos_z, sin_z := math.cos(angle_z), math.sin(angle_z)
m[0, 0] = +cos_z
m[0, 1] = +sin_z
@@ -239,7 +268,8 @@ matrix3_from_euler_angle_z_f32 :: proc(angle_z: f32) -> (m: Matrix3f32) {
}
matrix3_from_derived_euler_angle_x_f32 :: proc(angle_x: f32, angular_velocity_x: f32) -> (m: Matrix3f32) {
@(require_results)
matrix3_from_derived_euler_angle_x_f32 :: proc "contextless" (angle_x: f32, angular_velocity_x: f32) -> (m: Matrix3f32) {
cos_x := math.cos(angle_x) * angular_velocity_x
sin_x := math.sin(angle_x) * angular_velocity_x
m[0, 0] = 1
@@ -249,7 +279,8 @@ matrix3_from_derived_euler_angle_x_f32 :: proc(angle_x: f32, angular_velocity_x:
m[2, 2] = +cos_x
return
}
matrix3_from_derived_euler_angle_y_f32 :: proc(angle_y: f32, angular_velocity_y: f32) -> (m: Matrix3f32) {
@(require_results)
matrix3_from_derived_euler_angle_y_f32 :: proc "contextless" (angle_y: f32, angular_velocity_y: f32) -> (m: Matrix3f32) {
cos_y := math.cos(angle_y) * angular_velocity_y
sin_y := math.sin(angle_y) * angular_velocity_y
m[0, 0] = +cos_y
@@ -259,7 +290,8 @@ matrix3_from_derived_euler_angle_y_f32 :: proc(angle_y: f32, angular_velocity_y:
m[2, 2] = +cos_y
return
}
matrix3_from_derived_euler_angle_z_f32 :: proc(angle_z: f32, angular_velocity_z: f32) -> (m: Matrix3f32) {
@(require_results)
matrix3_from_derived_euler_angle_z_f32 :: proc "contextless" (angle_z: f32, angular_velocity_z: f32) -> (m: Matrix3f32) {
cos_z := math.cos(angle_z) * angular_velocity_z
sin_z := math.sin(angle_z) * angular_velocity_z
m[0, 0] = +cos_z
@@ -271,7 +303,8 @@ matrix3_from_derived_euler_angle_z_f32 :: proc(angle_z: f32, angular_velocity_z:
}
matrix3_from_euler_angles_xy_f32 :: proc(angle_x, angle_y: f32) -> (m: Matrix3f32) {
@(require_results)
matrix3_from_euler_angles_xy_f32 :: proc "contextless" (angle_x, angle_y: f32) -> (m: Matrix3f32) {
cos_x, sin_x := math.cos(angle_x), math.sin(angle_x)
cos_y, sin_y := math.cos(angle_y), math.sin(angle_y)
m[0, 0] = cos_y
@@ -286,7 +319,8 @@ matrix3_from_euler_angles_xy_f32 :: proc(angle_x, angle_y: f32) -> (m: Matrix3f3
}
matrix3_from_euler_angles_yx_f32 :: proc(angle_y, angle_x: f32) -> (m: Matrix3f32) {
@(require_results)
matrix3_from_euler_angles_yx_f32 :: proc "contextless" (angle_y, angle_x: f32) -> (m: Matrix3f32) {
cos_x, sin_x := math.cos(angle_x), math.sin(angle_x)
cos_y, sin_y := math.cos(angle_y), math.sin(angle_y)
m[0, 0] = cos_y
@@ -300,21 +334,26 @@ matrix3_from_euler_angles_yx_f32 :: proc(angle_y, angle_x: f32) -> (m: Matrix3f3
return
}
matrix3_from_euler_angles_xz_f32 :: proc(angle_x, angle_z: f32) -> (m: Matrix3f32) {
@(require_results)
matrix3_from_euler_angles_xz_f32 :: proc "contextless" (angle_x, angle_z: f32) -> (m: Matrix3f32) {
return mul(matrix3_from_euler_angle_x(angle_x), matrix3_from_euler_angle_z(angle_z))
}
matrix3_from_euler_angles_zx_f32 :: proc(angle_z, angle_x: f32) -> (m: Matrix3f32) {
@(require_results)
matrix3_from_euler_angles_zx_f32 :: proc "contextless" (angle_z, angle_x: f32) -> (m: Matrix3f32) {
return mul(matrix3_from_euler_angle_z(angle_z), matrix3_from_euler_angle_x(angle_x))
}
matrix3_from_euler_angles_yz_f32 :: proc(angle_y, angle_z: f32) -> (m: Matrix3f32) {
@(require_results)
matrix3_from_euler_angles_yz_f32 :: proc "contextless" (angle_y, angle_z: f32) -> (m: Matrix3f32) {
return mul(matrix3_from_euler_angle_y(angle_y), matrix3_from_euler_angle_z(angle_z))
}
matrix3_from_euler_angles_zy_f32 :: proc(angle_z, angle_y: f32) -> (m: Matrix3f32) {
@(require_results)
matrix3_from_euler_angles_zy_f32 :: proc "contextless" (angle_z, angle_y: f32) -> (m: Matrix3f32) {
return mul(matrix3_from_euler_angle_z(angle_z), matrix3_from_euler_angle_y(angle_y))
}
matrix3_from_euler_angles_xyz_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix3f32) {
@(require_results)
matrix3_from_euler_angles_xyz_f32 :: proc "contextless" (t1, t2, t3: f32) -> (m: Matrix3f32) {
c1 := math.cos(-t1)
c2 := math.cos(-t2)
c3 := math.cos(-t3)
@@ -334,7 +373,8 @@ matrix3_from_euler_angles_xyz_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix3f32) {
return
}
matrix3_from_euler_angles_yxz_f32 :: proc(yaw, pitch, roll: f32) -> (m: Matrix3f32) {
@(require_results)
matrix3_from_euler_angles_yxz_f32 :: proc "contextless" (yaw, pitch, roll: f32) -> (m: Matrix3f32) {
ch := math.cos(yaw)
sh := math.sin(yaw)
cp := math.cos(pitch)
@@ -354,7 +394,8 @@ matrix3_from_euler_angles_yxz_f32 :: proc(yaw, pitch, roll: f32) -> (m: Matrix3f
return
}
matrix3_from_euler_angles_xzx_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix3f32) {
@(require_results)
matrix3_from_euler_angles_xzx_f32 :: proc "contextless" (t1, t2, t3: f32) -> (m: Matrix3f32) {
c1 := math.cos(t1)
s1 := math.sin(t1)
c2 := math.cos(t2)
@@ -374,7 +415,8 @@ matrix3_from_euler_angles_xzx_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix3f32) {
return
}
matrix3_from_euler_angles_xyx_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix3f32) {
@(require_results)
matrix3_from_euler_angles_xyx_f32 :: proc "contextless" (t1, t2, t3: f32) -> (m: Matrix3f32) {
c1 := math.cos(t1)
s1 := math.sin(t1)
c2 := math.cos(t2)
@@ -394,7 +436,8 @@ matrix3_from_euler_angles_xyx_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix3f32) {
return
}
matrix3_from_euler_angles_yxy_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix3f32) {
@(require_results)
matrix3_from_euler_angles_yxy_f32 :: proc "contextless" (t1, t2, t3: f32) -> (m: Matrix3f32) {
c1 := math.cos(t1)
s1 := math.sin(t1)
c2 := math.cos(t2)
@@ -414,7 +457,8 @@ matrix3_from_euler_angles_yxy_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix3f32) {
return
}
matrix3_from_euler_angles_yzy_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix3f32) {
@(require_results)
matrix3_from_euler_angles_yzy_f32 :: proc "contextless" (t1, t2, t3: f32) -> (m: Matrix3f32) {
c1 := math.cos(t1)
s1 := math.sin(t1)
c2 := math.cos(t2)
@@ -434,7 +478,8 @@ matrix3_from_euler_angles_yzy_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix3f32) {
return
}
matrix3_from_euler_angles_zyz_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix3f32) {
@(require_results)
matrix3_from_euler_angles_zyz_f32 :: proc "contextless" (t1, t2, t3: f32) -> (m: Matrix3f32) {
c1 := math.cos(t1)
s1 := math.sin(t1)
c2 := math.cos(t2)
@@ -454,7 +499,8 @@ matrix3_from_euler_angles_zyz_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix3f32) {
return
}
matrix3_from_euler_angles_zxz_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix3f32) {
@(require_results)
matrix3_from_euler_angles_zxz_f32 :: proc "contextless" (t1, t2, t3: f32) -> (m: Matrix3f32) {
c1 := math.cos(t1)
s1 := math.sin(t1)
c2 := math.cos(t2)
@@ -475,7 +521,8 @@ matrix3_from_euler_angles_zxz_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix3f32) {
}
matrix3_from_euler_angles_xzy_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix3f32) {
@(require_results)
matrix3_from_euler_angles_xzy_f32 :: proc "contextless" (t1, t2, t3: f32) -> (m: Matrix3f32) {
c1 := math.cos(t1)
s1 := math.sin(t1)
c2 := math.cos(t2)
@@ -495,7 +542,8 @@ matrix3_from_euler_angles_xzy_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix3f32) {
return
}
matrix3_from_euler_angles_yzx_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix3f32) {
@(require_results)
matrix3_from_euler_angles_yzx_f32 :: proc "contextless" (t1, t2, t3: f32) -> (m: Matrix3f32) {
c1 := math.cos(t1)
s1 := math.sin(t1)
c2 := math.cos(t2)
@@ -515,7 +563,8 @@ matrix3_from_euler_angles_yzx_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix3f32) {
return
}
matrix3_from_euler_angles_zyx_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix3f32) {
@(require_results)
matrix3_from_euler_angles_zyx_f32 :: proc "contextless" (t1, t2, t3: f32) -> (m: Matrix3f32) {
c1 := math.cos(t1)
s1 := math.sin(t1)
c2 := math.cos(t2)
@@ -535,7 +584,8 @@ matrix3_from_euler_angles_zyx_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix3f32) {
return
}
matrix3_from_euler_angles_zxy_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix3f32) {
@(require_results)
matrix3_from_euler_angles_zxy_f32 :: proc "contextless" (t1, t2, t3: f32) -> (m: Matrix3f32) {
c1 := math.cos(t1)
s1 := math.sin(t1)
c2 := math.cos(t2)
@@ -556,7 +606,8 @@ matrix3_from_euler_angles_zxy_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix3f32) {
}
matrix3_from_yaw_pitch_roll_f32 :: proc(yaw, pitch, roll: f32) -> (m: Matrix3f32) {
@(require_results)
matrix3_from_yaw_pitch_roll_f32 :: proc "contextless" (yaw, pitch, roll: f32) -> (m: Matrix3f32) {
ch := math.cos(yaw)
sh := math.sin(yaw)
cp := math.cos(pitch)
@@ -576,7 +627,8 @@ matrix3_from_yaw_pitch_roll_f32 :: proc(yaw, pitch, roll: f32) -> (m: Matrix3f32
return m
}
euler_angles_xyz_from_matrix3_f32 :: proc(m: Matrix3f32) -> (t1, t2, t3: f32) {
@(require_results)
euler_angles_xyz_from_matrix3_f32 :: proc "contextless" (m: Matrix3f32) -> (t1, t2, t3: f32) {
T1 := math.atan2(m[1, 2], m[2, 2])
C2 := math.sqrt(m[0, 0]*m[0, 0] + m[0, 1]*m[0, 1])
T2 := math.atan2(-m[0, 2], C2)
@@ -589,7 +641,8 @@ euler_angles_xyz_from_matrix3_f32 :: proc(m: Matrix3f32) -> (t1, t2, t3: f32) {
return
}
euler_angles_yxz_from_matrix3_f32 :: proc(m: Matrix3f32) -> (t1, t2, t3: f32) {
@(require_results)
euler_angles_yxz_from_matrix3_f32 :: proc "contextless" (m: Matrix3f32) -> (t1, t2, t3: f32) {
T1 := math.atan2(m[0, 2], m[2, 2])
C2 := math.sqrt(m[1, 0]*m[1, 0] + m[1, 1]*m[1, 1])
T2 := math.atan2(-m[1, 2], C2)
@@ -602,7 +655,8 @@ euler_angles_yxz_from_matrix3_f32 :: proc(m: Matrix3f32) -> (t1, t2, t3: f32) {
return
}
euler_angles_xzx_from_matrix3_f32 :: proc(m: Matrix3f32) -> (t1, t2, t3: f32) {
@(require_results)
euler_angles_xzx_from_matrix3_f32 :: proc "contextless" (m: Matrix3f32) -> (t1, t2, t3: f32) {
T1 := math.atan2(m[2, 0], m[1, 0])
S2 := math.sqrt(m[0, 1]*m[0, 1] + m[0, 2]*m[0, 2])
T2 := math.atan2(S2, m[0, 0])
@@ -615,7 +669,8 @@ euler_angles_xzx_from_matrix3_f32 :: proc(m: Matrix3f32) -> (t1, t2, t3: f32) {
return
}
euler_angles_xyx_from_matrix3_f32 :: proc(m: Matrix3f32) -> (t1, t2, t3: f32) {
@(require_results)
euler_angles_xyx_from_matrix3_f32 :: proc "contextless" (m: Matrix3f32) -> (t1, t2, t3: f32) {
T1 := math.atan2(m[1, 0], -m[2, 0])
S2 := math.sqrt(m[0, 1]*m[0, 1] + m[0, 2]*m[0, 2])
T2 := math.atan2(S2, m[0, 0])
@@ -628,7 +683,8 @@ euler_angles_xyx_from_matrix3_f32 :: proc(m: Matrix3f32) -> (t1, t2, t3: f32) {
return
}
euler_angles_yxy_from_matrix3_f32 :: proc(m: Matrix3f32) -> (t1, t2, t3: f32) {
@(require_results)
euler_angles_yxy_from_matrix3_f32 :: proc "contextless" (m: Matrix3f32) -> (t1, t2, t3: f32) {
T1 := math.atan2(m[0, 1], m[2, 1])
S2 := math.sqrt(m[1, 0]*m[1, 0] + m[1, 2]*m[1, 2])
T2 := math.atan2(S2, m[1, 1])
@@ -641,7 +697,8 @@ euler_angles_yxy_from_matrix3_f32 :: proc(m: Matrix3f32) -> (t1, t2, t3: f32) {
return
}
euler_angles_yzy_from_matrix3_f32 :: proc(m: Matrix3f32) -> (t1, t2, t3: f32) {
@(require_results)
euler_angles_yzy_from_matrix3_f32 :: proc "contextless" (m: Matrix3f32) -> (t1, t2, t3: f32) {
T1 := math.atan2(m[2, 1], -m[0, 1])
S2 := math.sqrt(m[1, 0]*m[1, 0] + m[1, 2]*m[1, 2])
T2 := math.atan2(S2, m[1, 1])
@@ -653,7 +710,8 @@ euler_angles_yzy_from_matrix3_f32 :: proc(m: Matrix3f32) -> (t1, t2, t3: f32) {
t3 = T3
return
}
euler_angles_zyz_from_matrix3_f32 :: proc(m: Matrix3f32) -> (t1, t2, t3: f32) {
@(require_results)
euler_angles_zyz_from_matrix3_f32 :: proc "contextless" (m: Matrix3f32) -> (t1, t2, t3: f32) {
T1 := math.atan2(m[1, 2], m[0, 2])
S2 := math.sqrt(m[2, 0]*m[2, 0] + m[2, 1]*m[2, 1])
T2 := math.atan2(S2, m[2, 2])
@@ -666,7 +724,8 @@ euler_angles_zyz_from_matrix3_f32 :: proc(m: Matrix3f32) -> (t1, t2, t3: f32) {
return
}
euler_angles_zxz_from_matrix3_f32 :: proc(m: Matrix3f32) -> (t1, t2, t3: f32) {
@(require_results)
euler_angles_zxz_from_matrix3_f32 :: proc "contextless" (m: Matrix3f32) -> (t1, t2, t3: f32) {
T1 := math.atan2(m[0, 2], -m[1, 2])
S2 := math.sqrt(m[2, 0]*m[2, 0] + m[2, 1]*m[2, 1])
T2 := math.atan2(S2, m[2, 2])
@@ -679,7 +738,8 @@ euler_angles_zxz_from_matrix3_f32 :: proc(m: Matrix3f32) -> (t1, t2, t3: f32) {
return
}
euler_angles_xzy_from_matrix3_f32 :: proc(m: Matrix3f32) -> (t1, t2, t3: f32) {
@(require_results)
euler_angles_xzy_from_matrix3_f32 :: proc "contextless" (m: Matrix3f32) -> (t1, t2, t3: f32) {
T1 := math.atan2(m[2, 1], m[1, 1])
C2 := math.sqrt(m[0, 0]*m[0, 0] + m[0, 2]*m[0, 2])
T2 := math.atan2(-m[0, 1], C2)
@@ -692,7 +752,8 @@ euler_angles_xzy_from_matrix3_f32 :: proc(m: Matrix3f32) -> (t1, t2, t3: f32) {
return
}
euler_angles_yzx_from_matrix3_f32 :: proc(m: Matrix3f32) -> (t1, t2, t3: f32) {
@(require_results)
euler_angles_yzx_from_matrix3_f32 :: proc "contextless" (m: Matrix3f32) -> (t1, t2, t3: f32) {
T1 := math.atan2(-m[2, 0], m[0, 0])
C2 := math.sqrt(m[1, 1]*m[1, 1] + m[1, 2]*m[1, 2])
T2 := math.atan2(m[1, 0], C2)
@@ -705,7 +766,8 @@ euler_angles_yzx_from_matrix3_f32 :: proc(m: Matrix3f32) -> (t1, t2, t3: f32) {
return
}
euler_angles_zyx_from_matrix3_f32 :: proc(m: Matrix3f32) -> (t1, t2, t3: f32) {
@(require_results)
euler_angles_zyx_from_matrix3_f32 :: proc "contextless" (m: Matrix3f32) -> (t1, t2, t3: f32) {
T1 := math.atan2(m[1, 0], m[0, 0])
C2 := math.sqrt(m[2, 1]*m[2, 1] + m[2, 2]*m[2, 2])
T2 := math.atan2(-m[2, 0], C2)
@@ -718,7 +780,8 @@ euler_angles_zyx_from_matrix3_f32 :: proc(m: Matrix3f32) -> (t1, t2, t3: f32) {
return
}
euler_angles_zxy_from_matrix3_f32 :: proc(m: Matrix3f32) -> (t1, t2, t3: f32) {
@(require_results)
euler_angles_zxy_from_matrix3_f32 :: proc "contextless" (m: Matrix3f32) -> (t1, t2, t3: f32) {
T1 := math.atan2(-m[0, 1], m[1, 1])
C2 := math.sqrt(m[2, 0]*m[2, 0] + m[2, 2]*m[2, 2])
T2 := math.atan2(m[2, 1], C2)
@@ -735,7 +798,8 @@ euler_angles_zxy_from_matrix3_f32 :: proc(m: Matrix3f32) -> (t1, t2, t3: f32) {
// Matrix4
matrix4_from_euler_angle_x_f32 :: proc(angle_x: f32) -> (m: Matrix4f32) {
@(require_results)
matrix4_from_euler_angle_x_f32 :: proc "contextless" (angle_x: f32) -> (m: Matrix4f32) {
cos_x, sin_x := math.cos(angle_x), math.sin(angle_x)
m[0, 0] = 1
m[1, 1] = +cos_x
@@ -745,7 +809,8 @@ matrix4_from_euler_angle_x_f32 :: proc(angle_x: f32) -> (m: Matrix4f32) {
m[3, 3] = 1
return
}
matrix4_from_euler_angle_y_f32 :: proc(angle_y: f32) -> (m: Matrix4f32) {
@(require_results)
matrix4_from_euler_angle_y_f32 :: proc "contextless" (angle_y: f32) -> (m: Matrix4f32) {
cos_y, sin_y := math.cos(angle_y), math.sin(angle_y)
m[0, 0] = +cos_y
m[0, 2] = -sin_y
@@ -755,7 +820,8 @@ matrix4_from_euler_angle_y_f32 :: proc(angle_y: f32) -> (m: Matrix4f32) {
m[3, 3] = 1
return
}
matrix4_from_euler_angle_z_f32 :: proc(angle_z: f32) -> (m: Matrix4f32) {
@(require_results)
matrix4_from_euler_angle_z_f32 :: proc "contextless" (angle_z: f32) -> (m: Matrix4f32) {
cos_z, sin_z := math.cos(angle_z), math.sin(angle_z)
m[0, 0] = +cos_z
m[0, 1] = +sin_z
@@ -767,7 +833,8 @@ matrix4_from_euler_angle_z_f32 :: proc(angle_z: f32) -> (m: Matrix4f32) {
}
matrix4_from_derived_euler_angle_x_f32 :: proc(angle_x: f32, angular_velocity_x: f32) -> (m: Matrix4f32) {
@(require_results)
matrix4_from_derived_euler_angle_x_f32 :: proc "contextless" (angle_x: f32, angular_velocity_x: f32) -> (m: Matrix4f32) {
cos_x := math.cos(angle_x) * angular_velocity_x
sin_x := math.sin(angle_x) * angular_velocity_x
m[0, 0] = 1
@@ -778,7 +845,8 @@ matrix4_from_derived_euler_angle_x_f32 :: proc(angle_x: f32, angular_velocity_x:
m[3, 3] = 1
return
}
matrix4_from_derived_euler_angle_y_f32 :: proc(angle_y: f32, angular_velocity_y: f32) -> (m: Matrix4f32) {
@(require_results)
matrix4_from_derived_euler_angle_y_f32 :: proc "contextless" (angle_y: f32, angular_velocity_y: f32) -> (m: Matrix4f32) {
cos_y := math.cos(angle_y) * angular_velocity_y
sin_y := math.sin(angle_y) * angular_velocity_y
m[0, 0] = +cos_y
@@ -789,7 +857,8 @@ matrix4_from_derived_euler_angle_y_f32 :: proc(angle_y: f32, angular_velocity_y:
m[3, 3] = 1
return
}
matrix4_from_derived_euler_angle_z_f32 :: proc(angle_z: f32, angular_velocity_z: f32) -> (m: Matrix4f32) {
@(require_results)
matrix4_from_derived_euler_angle_z_f32 :: proc "contextless" (angle_z: f32, angular_velocity_z: f32) -> (m: Matrix4f32) {
cos_z := math.cos(angle_z) * angular_velocity_z
sin_z := math.sin(angle_z) * angular_velocity_z
m[0, 0] = +cos_z
@@ -802,7 +871,8 @@ matrix4_from_derived_euler_angle_z_f32 :: proc(angle_z: f32, angular_velocity_z:
}
matrix4_from_euler_angles_xy_f32 :: proc(angle_x, angle_y: f32) -> (m: Matrix4f32) {
@(require_results)
matrix4_from_euler_angles_xy_f32 :: proc "contextless" (angle_x, angle_y: f32) -> (m: Matrix4f32) {
cos_x, sin_x := math.cos(angle_x), math.sin(angle_x)
cos_y, sin_y := math.cos(angle_y), math.sin(angle_y)
m[0, 0] = cos_y
@@ -818,7 +888,8 @@ matrix4_from_euler_angles_xy_f32 :: proc(angle_x, angle_y: f32) -> (m: Matrix4f3
}
matrix4_from_euler_angles_yx_f32 :: proc(angle_y, angle_x: f32) -> (m: Matrix4f32) {
@(require_results)
matrix4_from_euler_angles_yx_f32 :: proc "contextless" (angle_y, angle_x: f32) -> (m: Matrix4f32) {
cos_x, sin_x := math.cos(angle_x), math.sin(angle_x)
cos_y, sin_y := math.cos(angle_y), math.sin(angle_y)
m[0, 0] = cos_y
@@ -833,21 +904,26 @@ matrix4_from_euler_angles_yx_f32 :: proc(angle_y, angle_x: f32) -> (m: Matrix4f3
return
}
matrix4_from_euler_angles_xz_f32 :: proc(angle_x, angle_z: f32) -> (m: Matrix4f32) {
@(require_results)
matrix4_from_euler_angles_xz_f32 :: proc "contextless" (angle_x, angle_z: f32) -> (m: Matrix4f32) {
return mul(matrix4_from_euler_angle_x(angle_x), matrix4_from_euler_angle_z(angle_z))
}
matrix4_from_euler_angles_zx_f32 :: proc(angle_z, angle_x: f32) -> (m: Matrix4f32) {
@(require_results)
matrix4_from_euler_angles_zx_f32 :: proc "contextless" (angle_z, angle_x: f32) -> (m: Matrix4f32) {
return mul(matrix4_from_euler_angle_z(angle_z), matrix4_from_euler_angle_x(angle_x))
}
matrix4_from_euler_angles_yz_f32 :: proc(angle_y, angle_z: f32) -> (m: Matrix4f32) {
@(require_results)
matrix4_from_euler_angles_yz_f32 :: proc "contextless" (angle_y, angle_z: f32) -> (m: Matrix4f32) {
return mul(matrix4_from_euler_angle_y(angle_y), matrix4_from_euler_angle_z(angle_z))
}
matrix4_from_euler_angles_zy_f32 :: proc(angle_z, angle_y: f32) -> (m: Matrix4f32) {
@(require_results)
matrix4_from_euler_angles_zy_f32 :: proc "contextless" (angle_z, angle_y: f32) -> (m: Matrix4f32) {
return mul(matrix4_from_euler_angle_z(angle_z), matrix4_from_euler_angle_y(angle_y))
}
matrix4_from_euler_angles_xyz_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix4f32) {
@(require_results)
matrix4_from_euler_angles_xyz_f32 :: proc "contextless" (t1, t2, t3: f32) -> (m: Matrix4f32) {
c1 := math.cos(-t1)
c2 := math.cos(-t2)
c3 := math.cos(-t3)
@@ -874,7 +950,8 @@ matrix4_from_euler_angles_xyz_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix4f32) {
return
}
matrix4_from_euler_angles_yxz_f32 :: proc(yaw, pitch, roll: f32) -> (m: Matrix4f32) {
@(require_results)
matrix4_from_euler_angles_yxz_f32 :: proc "contextless" (yaw, pitch, roll: f32) -> (m: Matrix4f32) {
ch := math.cos(yaw)
sh := math.sin(yaw)
cp := math.cos(pitch)
@@ -901,7 +978,8 @@ matrix4_from_euler_angles_yxz_f32 :: proc(yaw, pitch, roll: f32) -> (m: Matrix4f
return
}
matrix4_from_euler_angles_xzx_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix4f32) {
@(require_results)
matrix4_from_euler_angles_xzx_f32 :: proc "contextless" (t1, t2, t3: f32) -> (m: Matrix4f32) {
c1 := math.cos(t1)
s1 := math.sin(t1)
c2 := math.cos(t2)
@@ -928,7 +1006,8 @@ matrix4_from_euler_angles_xzx_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix4f32) {
return
}
matrix4_from_euler_angles_xyx_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix4f32) {
@(require_results)
matrix4_from_euler_angles_xyx_f32 :: proc "contextless" (t1, t2, t3: f32) -> (m: Matrix4f32) {
c1 := math.cos(t1)
s1 := math.sin(t1)
c2 := math.cos(t2)
@@ -955,7 +1034,8 @@ matrix4_from_euler_angles_xyx_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix4f32) {
return
}
matrix4_from_euler_angles_yxy_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix4f32) {
@(require_results)
matrix4_from_euler_angles_yxy_f32 :: proc "contextless" (t1, t2, t3: f32) -> (m: Matrix4f32) {
c1 := math.cos(t1)
s1 := math.sin(t1)
c2 := math.cos(t2)
@@ -982,7 +1062,8 @@ matrix4_from_euler_angles_yxy_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix4f32) {
return
}
matrix4_from_euler_angles_yzy_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix4f32) {
@(require_results)
matrix4_from_euler_angles_yzy_f32 :: proc "contextless" (t1, t2, t3: f32) -> (m: Matrix4f32) {
c1 := math.cos(t1)
s1 := math.sin(t1)
c2 := math.cos(t2)
@@ -1009,7 +1090,8 @@ matrix4_from_euler_angles_yzy_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix4f32) {
return
}
matrix4_from_euler_angles_zyz_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix4f32) {
@(require_results)
matrix4_from_euler_angles_zyz_f32 :: proc "contextless" (t1, t2, t3: f32) -> (m: Matrix4f32) {
c1 := math.cos(t1)
s1 := math.sin(t1)
c2 := math.cos(t2)
@@ -1036,7 +1118,8 @@ matrix4_from_euler_angles_zyz_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix4f32) {
return
}
matrix4_from_euler_angles_zxz_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix4f32) {
@(require_results)
matrix4_from_euler_angles_zxz_f32 :: proc "contextless" (t1, t2, t3: f32) -> (m: Matrix4f32) {
c1 := math.cos(t1)
s1 := math.sin(t1)
c2 := math.cos(t2)
@@ -1064,7 +1147,8 @@ matrix4_from_euler_angles_zxz_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix4f32) {
}
matrix4_from_euler_angles_xzy_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix4f32) {
@(require_results)
matrix4_from_euler_angles_xzy_f32 :: proc "contextless" (t1, t2, t3: f32) -> (m: Matrix4f32) {
c1 := math.cos(t1)
s1 := math.sin(t1)
c2 := math.cos(t2)
@@ -1091,7 +1175,8 @@ matrix4_from_euler_angles_xzy_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix4f32) {
return
}
matrix4_from_euler_angles_yzx_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix4f32) {
@(require_results)
matrix4_from_euler_angles_yzx_f32 :: proc "contextless" (t1, t2, t3: f32) -> (m: Matrix4f32) {
c1 := math.cos(t1)
s1 := math.sin(t1)
c2 := math.cos(t2)
@@ -1118,7 +1203,8 @@ matrix4_from_euler_angles_yzx_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix4f32) {
return
}
matrix4_from_euler_angles_zyx_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix4f32) {
@(require_results)
matrix4_from_euler_angles_zyx_f32 :: proc "contextless" (t1, t2, t3: f32) -> (m: Matrix4f32) {
c1 := math.cos(t1)
s1 := math.sin(t1)
c2 := math.cos(t2)
@@ -1145,7 +1231,8 @@ matrix4_from_euler_angles_zyx_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix4f32) {
return
}
matrix4_from_euler_angles_zxy_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix4f32) {
@(require_results)
matrix4_from_euler_angles_zxy_f32 :: proc "contextless" (t1, t2, t3: f32) -> (m: Matrix4f32) {
c1 := math.cos(t1)
s1 := math.sin(t1)
c2 := math.cos(t2)
@@ -1173,7 +1260,8 @@ matrix4_from_euler_angles_zxy_f32 :: proc(t1, t2, t3: f32) -> (m: Matrix4f32) {
}
matrix4_from_yaw_pitch_roll_f32 :: proc(yaw, pitch, roll: f32) -> (m: Matrix4f32) {
@(require_results)
matrix4_from_yaw_pitch_roll_f32 :: proc "contextless" (yaw, pitch, roll: f32) -> (m: Matrix4f32) {
ch := math.cos(yaw)
sh := math.sin(yaw)
cp := math.cos(pitch)
@@ -1200,7 +1288,8 @@ matrix4_from_yaw_pitch_roll_f32 :: proc(yaw, pitch, roll: f32) -> (m: Matrix4f32
return m
}
euler_angles_xyz_from_matrix4_f32 :: proc(m: Matrix4f32) -> (t1, t2, t3: f32) {
@(require_results)
euler_angles_xyz_from_matrix4_f32 :: proc "contextless" (m: Matrix4f32) -> (t1, t2, t3: f32) {
T1 := math.atan2(m[1, 2], m[2, 2])
C2 := math.sqrt(m[0, 0]*m[0, 0] + m[0, 1]*m[0, 1])
T2 := math.atan2(-m[0, 2], C2)
@@ -1213,7 +1302,8 @@ euler_angles_xyz_from_matrix4_f32 :: proc(m: Matrix4f32) -> (t1, t2, t3: f32) {
return
}
euler_angles_yxz_from_matrix4_f32 :: proc(m: Matrix4f32) -> (t1, t2, t3: f32) {
@(require_results)
euler_angles_yxz_from_matrix4_f32 :: proc "contextless" (m: Matrix4f32) -> (t1, t2, t3: f32) {
T1 := math.atan2(m[0, 2], m[2, 2])
C2 := math.sqrt(m[1, 0]*m[1, 0] + m[1, 1]*m[1, 1])
T2 := math.atan2(-m[1, 2], C2)
@@ -1226,7 +1316,8 @@ euler_angles_yxz_from_matrix4_f32 :: proc(m: Matrix4f32) -> (t1, t2, t3: f32) {
return
}
euler_angles_xzx_from_matrix4_f32 :: proc(m: Matrix4f32) -> (t1, t2, t3: f32) {
@(require_results)
euler_angles_xzx_from_matrix4_f32 :: proc "contextless" (m: Matrix4f32) -> (t1, t2, t3: f32) {
T1 := math.atan2(m[2, 0], m[1, 0])
S2 := math.sqrt(m[0, 1]*m[0, 1] + m[0, 2]*m[0, 2])
T2 := math.atan2(S2, m[0, 0])
@@ -1239,7 +1330,8 @@ euler_angles_xzx_from_matrix4_f32 :: proc(m: Matrix4f32) -> (t1, t2, t3: f32) {
return
}
euler_angles_xyx_from_matrix4_f32 :: proc(m: Matrix4f32) -> (t1, t2, t3: f32) {
@(require_results)
euler_angles_xyx_from_matrix4_f32 :: proc "contextless" (m: Matrix4f32) -> (t1, t2, t3: f32) {
T1 := math.atan2(m[1, 0], -m[2, 0])
S2 := math.sqrt(m[0, 1]*m[0, 1] + m[0, 2]*m[0, 2])
T2 := math.atan2(S2, m[0, 0])
@@ -1252,7 +1344,8 @@ euler_angles_xyx_from_matrix4_f32 :: proc(m: Matrix4f32) -> (t1, t2, t3: f32) {
return
}
euler_angles_yxy_from_matrix4_f32 :: proc(m: Matrix4f32) -> (t1, t2, t3: f32) {
@(require_results)
euler_angles_yxy_from_matrix4_f32 :: proc "contextless" (m: Matrix4f32) -> (t1, t2, t3: f32) {
T1 := math.atan2(m[0, 1], m[2, 1])
S2 := math.sqrt(m[1, 0]*m[1, 0] + m[1, 2]*m[1, 2])
T2 := math.atan2(S2, m[1, 1])
@@ -1265,7 +1358,8 @@ euler_angles_yxy_from_matrix4_f32 :: proc(m: Matrix4f32) -> (t1, t2, t3: f32) {
return
}
euler_angles_yzy_from_matrix4_f32 :: proc(m: Matrix4f32) -> (t1, t2, t3: f32) {
@(require_results)
euler_angles_yzy_from_matrix4_f32 :: proc "contextless" (m: Matrix4f32) -> (t1, t2, t3: f32) {
T1 := math.atan2(m[2, 1], -m[0, 1])
S2 := math.sqrt(m[1, 0]*m[1, 0] + m[1, 2]*m[1, 2])
T2 := math.atan2(S2, m[1, 1])
@@ -1277,7 +1371,8 @@ euler_angles_yzy_from_matrix4_f32 :: proc(m: Matrix4f32) -> (t1, t2, t3: f32) {
t3 = T3
return
}
euler_angles_zyz_from_matrix4_f32 :: proc(m: Matrix4f32) -> (t1, t2, t3: f32) {
@(require_results)
euler_angles_zyz_from_matrix4_f32 :: proc "contextless" (m: Matrix4f32) -> (t1, t2, t3: f32) {
T1 := math.atan2(m[1, 2], m[0, 2])
S2 := math.sqrt(m[2, 0]*m[2, 0] + m[2, 1]*m[2, 1])
T2 := math.atan2(S2, m[2, 2])
@@ -1290,7 +1385,8 @@ euler_angles_zyz_from_matrix4_f32 :: proc(m: Matrix4f32) -> (t1, t2, t3: f32) {
return
}
euler_angles_zxz_from_matrix4_f32 :: proc(m: Matrix4f32) -> (t1, t2, t3: f32) {
@(require_results)
euler_angles_zxz_from_matrix4_f32 :: proc "contextless" (m: Matrix4f32) -> (t1, t2, t3: f32) {
T1 := math.atan2(m[0, 2], -m[1, 2])
S2 := math.sqrt(m[2, 0]*m[2, 0] + m[2, 1]*m[2, 1])
T2 := math.atan2(S2, m[2, 2])
@@ -1303,7 +1399,8 @@ euler_angles_zxz_from_matrix4_f32 :: proc(m: Matrix4f32) -> (t1, t2, t3: f32) {
return
}
euler_angles_xzy_from_matrix4_f32 :: proc(m: Matrix4f32) -> (t1, t2, t3: f32) {
@(require_results)
euler_angles_xzy_from_matrix4_f32 :: proc "contextless" (m: Matrix4f32) -> (t1, t2, t3: f32) {
T1 := math.atan2(m[2, 1], m[1, 1])
C2 := math.sqrt(m[0, 0]*m[0, 0] + m[0, 2]*m[0, 2])
T2 := math.atan2(-m[0, 1], C2)
@@ -1316,7 +1413,8 @@ euler_angles_xzy_from_matrix4_f32 :: proc(m: Matrix4f32) -> (t1, t2, t3: f32) {
return
}
euler_angles_yzx_from_matrix4_f32 :: proc(m: Matrix4f32) -> (t1, t2, t3: f32) {
@(require_results)
euler_angles_yzx_from_matrix4_f32 :: proc "contextless" (m: Matrix4f32) -> (t1, t2, t3: f32) {
T1 := math.atan2(-m[2, 0], m[0, 0])
C2 := math.sqrt(m[1, 1]*m[1, 1] + m[1, 2]*m[1, 2])
T2 := math.atan2(m[1, 0], C2)
@@ -1329,7 +1427,8 @@ euler_angles_yzx_from_matrix4_f32 :: proc(m: Matrix4f32) -> (t1, t2, t3: f32) {
return
}
euler_angles_zyx_from_matrix4_f32 :: proc(m: Matrix4f32) -> (t1, t2, t3: f32) {
@(require_results)
euler_angles_zyx_from_matrix4_f32 :: proc "contextless" (m: Matrix4f32) -> (t1, t2, t3: f32) {
T1 := math.atan2(m[1, 0], m[0, 0])
C2 := math.sqrt(m[2, 1]*m[2, 1] + m[2, 2]*m[2, 2])
T2 := math.atan2(-m[2, 0], C2)
@@ -1342,7 +1441,8 @@ euler_angles_zyx_from_matrix4_f32 :: proc(m: Matrix4f32) -> (t1, t2, t3: f32) {
return
}
euler_angles_zxy_from_matrix4_f32 :: proc(m: Matrix4f32) -> (t1, t2, t3: f32) {
@(require_results)
euler_angles_zxy_from_matrix4_f32 :: proc "contextless" (m: Matrix4f32) -> (t1, t2, t3: f32) {
T1 := math.atan2(-m[0, 1], m[1, 1])
C2 := math.sqrt(m[2, 0]*m[2, 0] + m[2, 2]*m[2, 2])
T2 := math.atan2(m[2, 1], C2)
+200 -100
View File
@@ -2,7 +2,8 @@ package linalg
import "core:math"
euler_angles_from_matrix3_f64 :: proc(m: Matrix3f64, order: Euler_Angle_Order) -> (t1, t2, t3: f64) {
@(require_results)
euler_angles_from_matrix3_f64 :: proc "contextless" (m: Matrix3f64, order: Euler_Angle_Order) -> (t1, t2, t3: f64) {
switch order {
case .XYZ: t1, t2, t3 = euler_angles_xyz_from_matrix3(m)
case .XZY: t1, t2, t3 = euler_angles_xzy_from_matrix3(m)
@@ -19,7 +20,8 @@ euler_angles_from_matrix3_f64 :: proc(m: Matrix3f64, order: Euler_Angle_Order) -
}
return
}
euler_angles_from_matrix4_f64 :: proc(m: Matrix4f64, order: Euler_Angle_Order) -> (t1, t2, t3: f64) {
@(require_results)
euler_angles_from_matrix4_f64 :: proc "contextless" (m: Matrix4f64, order: Euler_Angle_Order) -> (t1, t2, t3: f64) {
switch order {
case .XYZ: t1, t2, t3 = euler_angles_xyz_from_matrix4(m)
case .XZY: t1, t2, t3 = euler_angles_xzy_from_matrix4(m)
@@ -36,7 +38,8 @@ euler_angles_from_matrix4_f64 :: proc(m: Matrix4f64, order: Euler_Angle_Order) -
}
return
}
euler_angles_from_quaternion_f64 :: proc(m: Quaternionf64, order: Euler_Angle_Order) -> (t1, t2, t3: f64) {
@(require_results)
euler_angles_from_quaternion_f64 :: proc "contextless" (m: Quaternionf64, order: Euler_Angle_Order) -> (t1, t2, t3: f64) {
switch order {
case .XYZ: t1, t2, t3 = euler_angles_xyz_from_quaternion(m)
case .XZY: t1, t2, t3 = euler_angles_xzy_from_quaternion(m)
@@ -54,7 +57,8 @@ euler_angles_from_quaternion_f64 :: proc(m: Quaternionf64, order: Euler_Angle_Or
return
}
matrix3_from_euler_angles_f64 :: proc(t1, t2, t3: f64, order: Euler_Angle_Order) -> (m: Matrix3f64) {
@(require_results)
matrix3_from_euler_angles_f64 :: proc "contextless" (t1, t2, t3: f64, order: Euler_Angle_Order) -> (m: Matrix3f64) {
switch order {
case .XYZ: return matrix3_from_euler_angles_xyz(t1, t2, t3) // m1, m2, m3 = X(t1), Y(t2), Z(t3);
case .XZY: return matrix3_from_euler_angles_xzy(t1, t2, t3) // m1, m2, m3 = X(t1), Z(t2), Y(t3);
@@ -71,7 +75,8 @@ matrix3_from_euler_angles_f64 :: proc(t1, t2, t3: f64, order: Euler_Angle_Order)
}
return
}
matrix4_from_euler_angles_f64 :: proc(t1, t2, t3: f64, order: Euler_Angle_Order) -> (m: Matrix4f64) {
@(require_results)
matrix4_from_euler_angles_f64 :: proc "contextless" (t1, t2, t3: f64, order: Euler_Angle_Order) -> (m: Matrix4f64) {
switch order {
case .XYZ: return matrix4_from_euler_angles_xyz(t1, t2, t3) // m1, m2, m3 = X(t1), Y(t2), Z(t3);
case .XZY: return matrix4_from_euler_angles_xzy(t1, t2, t3) // m1, m2, m3 = X(t1), Z(t2), Y(t3);
@@ -89,7 +94,8 @@ matrix4_from_euler_angles_f64 :: proc(t1, t2, t3: f64, order: Euler_Angle_Order)
return
}
quaternion_from_euler_angles_f64 :: proc(t1, t2, t3: f64, order: Euler_Angle_Order) -> Quaternionf64 {
@(require_results)
quaternion_from_euler_angles_f64 :: proc "contextless" (t1, t2, t3: f64, order: Euler_Angle_Order) -> Quaternionf64 {
X :: quaternion_from_euler_angle_x
Y :: quaternion_from_euler_angle_y
Z :: quaternion_from_euler_angle_z
@@ -117,17 +123,21 @@ quaternion_from_euler_angles_f64 :: proc(t1, t2, t3: f64, order: Euler_Angle_Ord
// Quaternionf64s
quaternion_from_euler_angle_x_f64 :: proc(angle_x: f64) -> (q: Quaternionf64) {
@(require_results)
quaternion_from_euler_angle_x_f64 :: proc "contextless" (angle_x: f64) -> (q: Quaternionf64) {
return quaternion_angle_axis_f64(angle_x, {1, 0, 0})
}
quaternion_from_euler_angle_y_f64 :: proc(angle_y: f64) -> (q: Quaternionf64) {
@(require_results)
quaternion_from_euler_angle_y_f64 :: proc "contextless" (angle_y: f64) -> (q: Quaternionf64) {
return quaternion_angle_axis_f64(angle_y, {0, 1, 0})
}
quaternion_from_euler_angle_z_f64 :: proc(angle_z: f64) -> (q: Quaternionf64) {
@(require_results)
quaternion_from_euler_angle_z_f64 :: proc "contextless" (angle_z: f64) -> (q: Quaternionf64) {
return quaternion_angle_axis_f64(angle_z, {0, 0, 1})
}
quaternion_from_pitch_yaw_roll_f64 :: proc(pitch, yaw, roll: f64) -> Quaternionf64 {
@(require_results)
quaternion_from_pitch_yaw_roll_f64 :: proc "contextless" (pitch, yaw, roll: f64) -> Quaternionf64 {
a, b, c := pitch, yaw, roll
ca, sa := math.cos(a*0.5), math.sin(a*0.5)
@@ -142,11 +152,13 @@ quaternion_from_pitch_yaw_roll_f64 :: proc(pitch, yaw, roll: f64) -> Quaternionf
return q
}
roll_from_quaternion_f64 :: proc(q: Quaternionf64) -> f64 {
@(require_results)
roll_from_quaternion_f64 :: proc "contextless" (q: Quaternionf64) -> f64 {
return math.atan2(2 * q.x*q.y + q.w*q.z, q.w*q.w + q.x*q.x - q.y*q.y - q.z*q.z)
}
pitch_from_quaternion_f64 :: proc(q: Quaternionf64) -> f64 {
@(require_results)
pitch_from_quaternion_f64 :: proc "contextless" (q: Quaternionf64) -> f64 {
y := 2 * (q.y*q.z + q.w*q.w)
x := q.w*q.w - q.x*q.x - q.y*q.y + q.z*q.z
@@ -157,52 +169,66 @@ pitch_from_quaternion_f64 :: proc(q: Quaternionf64) -> f64 {
return math.atan2(y, x)
}
yaw_from_quaternion_f64 :: proc(q: Quaternionf64) -> f64 {
@(require_results)
yaw_from_quaternion_f64 :: proc "contextless" (q: Quaternionf64) -> f64 {
return math.asin(clamp(-2 * (q.x*q.z - q.w*q.y), -1, 1))
}
pitch_yaw_roll_from_quaternion_f64 :: proc(q: Quaternionf64) -> (pitch, yaw, roll: f64) {
@(require_results)
pitch_yaw_roll_from_quaternion_f64 :: proc "contextless" (q: Quaternionf64) -> (pitch, yaw, roll: f64) {
pitch = pitch_from_quaternion(q)
yaw = yaw_from_quaternion(q)
roll = roll_from_quaternion(q)
return
}
euler_angles_xyz_from_quaternion_f64 :: proc(q: Quaternionf64) -> (t1, t2, t3: f64) {
@(require_results)
euler_angles_xyz_from_quaternion_f64 :: proc "contextless" (q: Quaternionf64) -> (t1, t2, t3: f64) {
return euler_angles_xyz_from_matrix4(matrix4_from_quaternion(q))
}
euler_angles_yxz_from_quaternion_f64 :: proc(q: Quaternionf64) -> (t1, t2, t3: f64) {
@(require_results)
euler_angles_yxz_from_quaternion_f64 :: proc "contextless" (q: Quaternionf64) -> (t1, t2, t3: f64) {
return euler_angles_yxz_from_matrix4(matrix4_from_quaternion(q))
}
euler_angles_xzx_from_quaternion_f64 :: proc(q: Quaternionf64) -> (t1, t2, t3: f64) {
@(require_results)
euler_angles_xzx_from_quaternion_f64 :: proc "contextless" (q: Quaternionf64) -> (t1, t2, t3: f64) {
return euler_angles_xzx_from_matrix4(matrix4_from_quaternion(q))
}
euler_angles_xyx_from_quaternion_f64 :: proc(q: Quaternionf64) -> (t1, t2, t3: f64) {
@(require_results)
euler_angles_xyx_from_quaternion_f64 :: proc "contextless" (q: Quaternionf64) -> (t1, t2, t3: f64) {
return euler_angles_xyx_from_matrix4(matrix4_from_quaternion(q))
}
euler_angles_yxy_from_quaternion_f64 :: proc(q: Quaternionf64) -> (t1, t2, t3: f64) {
@(require_results)
euler_angles_yxy_from_quaternion_f64 :: proc "contextless" (q: Quaternionf64) -> (t1, t2, t3: f64) {
return euler_angles_yxy_from_matrix4(matrix4_from_quaternion(q))
}
euler_angles_yzy_from_quaternion_f64 :: proc(q: Quaternionf64) -> (t1, t2, t3: f64) {
@(require_results)
euler_angles_yzy_from_quaternion_f64 :: proc "contextless" (q: Quaternionf64) -> (t1, t2, t3: f64) {
return euler_angles_yzy_from_matrix4(matrix4_from_quaternion(q))
}
euler_angles_zyz_from_quaternion_f64 :: proc(q: Quaternionf64) -> (t1, t2, t3: f64) {
@(require_results)
euler_angles_zyz_from_quaternion_f64 :: proc "contextless" (q: Quaternionf64) -> (t1, t2, t3: f64) {
return euler_angles_zyz_from_matrix4(matrix4_from_quaternion(q))
}
euler_angles_zxz_from_quaternion_f64 :: proc(q: Quaternionf64) -> (t1, t2, t3: f64) {
@(require_results)
euler_angles_zxz_from_quaternion_f64 :: proc "contextless" (q: Quaternionf64) -> (t1, t2, t3: f64) {
return euler_angles_zxz_from_matrix4(matrix4_from_quaternion(q))
}
euler_angles_xzy_from_quaternion_f64 :: proc(q: Quaternionf64) -> (t1, t2, t3: f64) {
@(require_results)
euler_angles_xzy_from_quaternion_f64 :: proc "contextless" (q: Quaternionf64) -> (t1, t2, t3: f64) {
return euler_angles_xzy_from_matrix4(matrix4_from_quaternion(q))
}
euler_angles_yzx_from_quaternion_f64 :: proc(q: Quaternionf64) -> (t1, t2, t3: f64) {
@(require_results)
euler_angles_yzx_from_quaternion_f64 :: proc "contextless" (q: Quaternionf64) -> (t1, t2, t3: f64) {
return euler_angles_yzx_from_matrix4(matrix4_from_quaternion(q))
}
euler_angles_zyx_from_quaternion_f64 :: proc(q: Quaternionf64) -> (t1, t2, t3: f64) {
@(require_results)
euler_angles_zyx_from_quaternion_f64 :: proc "contextless" (q: Quaternionf64) -> (t1, t2, t3: f64) {
return euler_angles_zyx_from_matrix4(matrix4_from_quaternion(q))
}
euler_angles_zxy_from_quaternion_f64 :: proc(q: Quaternionf64) -> (t1, t2, t3: f64) {
@(require_results)
euler_angles_zxy_from_quaternion_f64 :: proc "contextless" (q: Quaternionf64) -> (t1, t2, t3: f64) {
return euler_angles_zxy_from_matrix4(matrix4_from_quaternion(q))
}
@@ -210,7 +236,8 @@ euler_angles_zxy_from_quaternion_f64 :: proc(q: Quaternionf64) -> (t1, t2, t3: f
// Matrix3
matrix3_from_euler_angle_x_f64 :: proc(angle_x: f64) -> (m: Matrix3f64) {
@(require_results)
matrix3_from_euler_angle_x_f64 :: proc "contextless" (angle_x: f64) -> (m: Matrix3f64) {
cos_x, sin_x := math.cos(angle_x), math.sin(angle_x)
m[0, 0] = 1
m[1, 1] = +cos_x
@@ -219,7 +246,8 @@ matrix3_from_euler_angle_x_f64 :: proc(angle_x: f64) -> (m: Matrix3f64) {
m[2, 2] = +cos_x
return
}
matrix3_from_euler_angle_y_f64 :: proc(angle_y: f64) -> (m: Matrix3f64) {
@(require_results)
matrix3_from_euler_angle_y_f64 :: proc "contextless" (angle_y: f64) -> (m: Matrix3f64) {
cos_y, sin_y := math.cos(angle_y), math.sin(angle_y)
m[0, 0] = +cos_y
m[0, 2] = -sin_y
@@ -228,7 +256,8 @@ matrix3_from_euler_angle_y_f64 :: proc(angle_y: f64) -> (m: Matrix3f64) {
m[2, 2] = +cos_y
return
}
matrix3_from_euler_angle_z_f64 :: proc(angle_z: f64) -> (m: Matrix3f64) {
@(require_results)
matrix3_from_euler_angle_z_f64 :: proc "contextless" (angle_z: f64) -> (m: Matrix3f64) {
cos_z, sin_z := math.cos(angle_z), math.sin(angle_z)
m[0, 0] = +cos_z
m[0, 1] = +sin_z
@@ -239,7 +268,8 @@ matrix3_from_euler_angle_z_f64 :: proc(angle_z: f64) -> (m: Matrix3f64) {
}
matrix3_from_derived_euler_angle_x_f64 :: proc(angle_x: f64, angular_velocity_x: f64) -> (m: Matrix3f64) {
@(require_results)
matrix3_from_derived_euler_angle_x_f64 :: proc "contextless" (angle_x: f64, angular_velocity_x: f64) -> (m: Matrix3f64) {
cos_x := math.cos(angle_x) * angular_velocity_x
sin_x := math.sin(angle_x) * angular_velocity_x
m[0, 0] = 1
@@ -249,7 +279,8 @@ matrix3_from_derived_euler_angle_x_f64 :: proc(angle_x: f64, angular_velocity_x:
m[2, 2] = +cos_x
return
}
matrix3_from_derived_euler_angle_y_f64 :: proc(angle_y: f64, angular_velocity_y: f64) -> (m: Matrix3f64) {
@(require_results)
matrix3_from_derived_euler_angle_y_f64 :: proc "contextless" (angle_y: f64, angular_velocity_y: f64) -> (m: Matrix3f64) {
cos_y := math.cos(angle_y) * angular_velocity_y
sin_y := math.sin(angle_y) * angular_velocity_y
m[0, 0] = +cos_y
@@ -259,7 +290,8 @@ matrix3_from_derived_euler_angle_y_f64 :: proc(angle_y: f64, angular_velocity_y:
m[2, 2] = +cos_y
return
}
matrix3_from_derived_euler_angle_z_f64 :: proc(angle_z: f64, angular_velocity_z: f64) -> (m: Matrix3f64) {
@(require_results)
matrix3_from_derived_euler_angle_z_f64 :: proc "contextless" (angle_z: f64, angular_velocity_z: f64) -> (m: Matrix3f64) {
cos_z := math.cos(angle_z) * angular_velocity_z
sin_z := math.sin(angle_z) * angular_velocity_z
m[0, 0] = +cos_z
@@ -271,7 +303,8 @@ matrix3_from_derived_euler_angle_z_f64 :: proc(angle_z: f64, angular_velocity_z:
}
matrix3_from_euler_angles_xy_f64 :: proc(angle_x, angle_y: f64) -> (m: Matrix3f64) {
@(require_results)
matrix3_from_euler_angles_xy_f64 :: proc "contextless" (angle_x, angle_y: f64) -> (m: Matrix3f64) {
cos_x, sin_x := math.cos(angle_x), math.sin(angle_x)
cos_y, sin_y := math.cos(angle_y), math.sin(angle_y)
m[0, 0] = cos_y
@@ -286,7 +319,8 @@ matrix3_from_euler_angles_xy_f64 :: proc(angle_x, angle_y: f64) -> (m: Matrix3f6
}
matrix3_from_euler_angles_yx_f64 :: proc(angle_y, angle_x: f64) -> (m: Matrix3f64) {
@(require_results)
matrix3_from_euler_angles_yx_f64 :: proc "contextless" (angle_y, angle_x: f64) -> (m: Matrix3f64) {
cos_x, sin_x := math.cos(angle_x), math.sin(angle_x)
cos_y, sin_y := math.cos(angle_y), math.sin(angle_y)
m[0, 0] = cos_y
@@ -300,21 +334,26 @@ matrix3_from_euler_angles_yx_f64 :: proc(angle_y, angle_x: f64) -> (m: Matrix3f6
return
}
matrix3_from_euler_angles_xz_f64 :: proc(angle_x, angle_z: f64) -> (m: Matrix3f64) {
@(require_results)
matrix3_from_euler_angles_xz_f64 :: proc "contextless" (angle_x, angle_z: f64) -> (m: Matrix3f64) {
return mul(matrix3_from_euler_angle_x(angle_x), matrix3_from_euler_angle_z(angle_z))
}
matrix3_from_euler_angles_zx_f64 :: proc(angle_z, angle_x: f64) -> (m: Matrix3f64) {
@(require_results)
matrix3_from_euler_angles_zx_f64 :: proc "contextless" (angle_z, angle_x: f64) -> (m: Matrix3f64) {
return mul(matrix3_from_euler_angle_z(angle_z), matrix3_from_euler_angle_x(angle_x))
}
matrix3_from_euler_angles_yz_f64 :: proc(angle_y, angle_z: f64) -> (m: Matrix3f64) {
@(require_results)
matrix3_from_euler_angles_yz_f64 :: proc "contextless" (angle_y, angle_z: f64) -> (m: Matrix3f64) {
return mul(matrix3_from_euler_angle_y(angle_y), matrix3_from_euler_angle_z(angle_z))
}
matrix3_from_euler_angles_zy_f64 :: proc(angle_z, angle_y: f64) -> (m: Matrix3f64) {
@(require_results)
matrix3_from_euler_angles_zy_f64 :: proc "contextless" (angle_z, angle_y: f64) -> (m: Matrix3f64) {
return mul(matrix3_from_euler_angle_z(angle_z), matrix3_from_euler_angle_y(angle_y))
}
matrix3_from_euler_angles_xyz_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix3f64) {
@(require_results)
matrix3_from_euler_angles_xyz_f64 :: proc "contextless" (t1, t2, t3: f64) -> (m: Matrix3f64) {
c1 := math.cos(-t1)
c2 := math.cos(-t2)
c3 := math.cos(-t3)
@@ -334,7 +373,8 @@ matrix3_from_euler_angles_xyz_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix3f64) {
return
}
matrix3_from_euler_angles_yxz_f64 :: proc(yaw, pitch, roll: f64) -> (m: Matrix3f64) {
@(require_results)
matrix3_from_euler_angles_yxz_f64 :: proc "contextless" (yaw, pitch, roll: f64) -> (m: Matrix3f64) {
ch := math.cos(yaw)
sh := math.sin(yaw)
cp := math.cos(pitch)
@@ -354,7 +394,8 @@ matrix3_from_euler_angles_yxz_f64 :: proc(yaw, pitch, roll: f64) -> (m: Matrix3f
return
}
matrix3_from_euler_angles_xzx_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix3f64) {
@(require_results)
matrix3_from_euler_angles_xzx_f64 :: proc "contextless" (t1, t2, t3: f64) -> (m: Matrix3f64) {
c1 := math.cos(t1)
s1 := math.sin(t1)
c2 := math.cos(t2)
@@ -374,7 +415,8 @@ matrix3_from_euler_angles_xzx_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix3f64) {
return
}
matrix3_from_euler_angles_xyx_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix3f64) {
@(require_results)
matrix3_from_euler_angles_xyx_f64 :: proc "contextless" (t1, t2, t3: f64) -> (m: Matrix3f64) {
c1 := math.cos(t1)
s1 := math.sin(t1)
c2 := math.cos(t2)
@@ -394,7 +436,8 @@ matrix3_from_euler_angles_xyx_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix3f64) {
return
}
matrix3_from_euler_angles_yxy_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix3f64) {
@(require_results)
matrix3_from_euler_angles_yxy_f64 :: proc "contextless" (t1, t2, t3: f64) -> (m: Matrix3f64) {
c1 := math.cos(t1)
s1 := math.sin(t1)
c2 := math.cos(t2)
@@ -414,7 +457,8 @@ matrix3_from_euler_angles_yxy_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix3f64) {
return
}
matrix3_from_euler_angles_yzy_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix3f64) {
@(require_results)
matrix3_from_euler_angles_yzy_f64 :: proc "contextless" (t1, t2, t3: f64) -> (m: Matrix3f64) {
c1 := math.cos(t1)
s1 := math.sin(t1)
c2 := math.cos(t2)
@@ -434,7 +478,8 @@ matrix3_from_euler_angles_yzy_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix3f64) {
return
}
matrix3_from_euler_angles_zyz_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix3f64) {
@(require_results)
matrix3_from_euler_angles_zyz_f64 :: proc "contextless" (t1, t2, t3: f64) -> (m: Matrix3f64) {
c1 := math.cos(t1)
s1 := math.sin(t1)
c2 := math.cos(t2)
@@ -454,7 +499,8 @@ matrix3_from_euler_angles_zyz_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix3f64) {
return
}
matrix3_from_euler_angles_zxz_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix3f64) {
@(require_results)
matrix3_from_euler_angles_zxz_f64 :: proc "contextless" (t1, t2, t3: f64) -> (m: Matrix3f64) {
c1 := math.cos(t1)
s1 := math.sin(t1)
c2 := math.cos(t2)
@@ -475,7 +521,8 @@ matrix3_from_euler_angles_zxz_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix3f64) {
}
matrix3_from_euler_angles_xzy_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix3f64) {
@(require_results)
matrix3_from_euler_angles_xzy_f64 :: proc "contextless" (t1, t2, t3: f64) -> (m: Matrix3f64) {
c1 := math.cos(t1)
s1 := math.sin(t1)
c2 := math.cos(t2)
@@ -495,7 +542,8 @@ matrix3_from_euler_angles_xzy_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix3f64) {
return
}
matrix3_from_euler_angles_yzx_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix3f64) {
@(require_results)
matrix3_from_euler_angles_yzx_f64 :: proc "contextless" (t1, t2, t3: f64) -> (m: Matrix3f64) {
c1 := math.cos(t1)
s1 := math.sin(t1)
c2 := math.cos(t2)
@@ -515,7 +563,8 @@ matrix3_from_euler_angles_yzx_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix3f64) {
return
}
matrix3_from_euler_angles_zyx_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix3f64) {
@(require_results)
matrix3_from_euler_angles_zyx_f64 :: proc "contextless" (t1, t2, t3: f64) -> (m: Matrix3f64) {
c1 := math.cos(t1)
s1 := math.sin(t1)
c2 := math.cos(t2)
@@ -535,7 +584,8 @@ matrix3_from_euler_angles_zyx_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix3f64) {
return
}
matrix3_from_euler_angles_zxy_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix3f64) {
@(require_results)
matrix3_from_euler_angles_zxy_f64 :: proc "contextless" (t1, t2, t3: f64) -> (m: Matrix3f64) {
c1 := math.cos(t1)
s1 := math.sin(t1)
c2 := math.cos(t2)
@@ -556,7 +606,8 @@ matrix3_from_euler_angles_zxy_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix3f64) {
}
matrix3_from_yaw_pitch_roll_f64 :: proc(yaw, pitch, roll: f64) -> (m: Matrix3f64) {
@(require_results)
matrix3_from_yaw_pitch_roll_f64 :: proc "contextless" (yaw, pitch, roll: f64) -> (m: Matrix3f64) {
ch := math.cos(yaw)
sh := math.sin(yaw)
cp := math.cos(pitch)
@@ -576,7 +627,8 @@ matrix3_from_yaw_pitch_roll_f64 :: proc(yaw, pitch, roll: f64) -> (m: Matrix3f64
return m
}
euler_angles_xyz_from_matrix3_f64 :: proc(m: Matrix3f64) -> (t1, t2, t3: f64) {
@(require_results)
euler_angles_xyz_from_matrix3_f64 :: proc "contextless" (m: Matrix3f64) -> (t1, t2, t3: f64) {
T1 := math.atan2(m[1, 2], m[2, 2])
C2 := math.sqrt(m[0, 0]*m[0, 0] + m[0, 1]*m[0, 1])
T2 := math.atan2(-m[0, 2], C2)
@@ -589,7 +641,8 @@ euler_angles_xyz_from_matrix3_f64 :: proc(m: Matrix3f64) -> (t1, t2, t3: f64) {
return
}
euler_angles_yxz_from_matrix3_f64 :: proc(m: Matrix3f64) -> (t1, t2, t3: f64) {
@(require_results)
euler_angles_yxz_from_matrix3_f64 :: proc "contextless" (m: Matrix3f64) -> (t1, t2, t3: f64) {
T1 := math.atan2(m[0, 2], m[2, 2])
C2 := math.sqrt(m[1, 0]*m[1, 0] + m[1, 1]*m[1, 1])
T2 := math.atan2(-m[1, 2], C2)
@@ -602,7 +655,8 @@ euler_angles_yxz_from_matrix3_f64 :: proc(m: Matrix3f64) -> (t1, t2, t3: f64) {
return
}
euler_angles_xzx_from_matrix3_f64 :: proc(m: Matrix3f64) -> (t1, t2, t3: f64) {
@(require_results)
euler_angles_xzx_from_matrix3_f64 :: proc "contextless" (m: Matrix3f64) -> (t1, t2, t3: f64) {
T1 := math.atan2(m[2, 0], m[1, 0])
S2 := math.sqrt(m[0, 1]*m[0, 1] + m[0, 2]*m[0, 2])
T2 := math.atan2(S2, m[0, 0])
@@ -615,7 +669,8 @@ euler_angles_xzx_from_matrix3_f64 :: proc(m: Matrix3f64) -> (t1, t2, t3: f64) {
return
}
euler_angles_xyx_from_matrix3_f64 :: proc(m: Matrix3f64) -> (t1, t2, t3: f64) {
@(require_results)
euler_angles_xyx_from_matrix3_f64 :: proc "contextless" (m: Matrix3f64) -> (t1, t2, t3: f64) {
T1 := math.atan2(m[1, 0], -m[2, 0])
S2 := math.sqrt(m[0, 1]*m[0, 1] + m[0, 2]*m[0, 2])
T2 := math.atan2(S2, m[0, 0])
@@ -628,7 +683,8 @@ euler_angles_xyx_from_matrix3_f64 :: proc(m: Matrix3f64) -> (t1, t2, t3: f64) {
return
}
euler_angles_yxy_from_matrix3_f64 :: proc(m: Matrix3f64) -> (t1, t2, t3: f64) {
@(require_results)
euler_angles_yxy_from_matrix3_f64 :: proc "contextless" (m: Matrix3f64) -> (t1, t2, t3: f64) {
T1 := math.atan2(m[0, 1], m[2, 1])
S2 := math.sqrt(m[1, 0]*m[1, 0] + m[1, 2]*m[1, 2])
T2 := math.atan2(S2, m[1, 1])
@@ -641,7 +697,8 @@ euler_angles_yxy_from_matrix3_f64 :: proc(m: Matrix3f64) -> (t1, t2, t3: f64) {
return
}
euler_angles_yzy_from_matrix3_f64 :: proc(m: Matrix3f64) -> (t1, t2, t3: f64) {
@(require_results)
euler_angles_yzy_from_matrix3_f64 :: proc "contextless" (m: Matrix3f64) -> (t1, t2, t3: f64) {
T1 := math.atan2(m[2, 1], -m[0, 1])
S2 := math.sqrt(m[1, 0]*m[1, 0] + m[1, 2]*m[1, 2])
T2 := math.atan2(S2, m[1, 1])
@@ -653,7 +710,8 @@ euler_angles_yzy_from_matrix3_f64 :: proc(m: Matrix3f64) -> (t1, t2, t3: f64) {
t3 = T3
return
}
euler_angles_zyz_from_matrix3_f64 :: proc(m: Matrix3f64) -> (t1, t2, t3: f64) {
@(require_results)
euler_angles_zyz_from_matrix3_f64 :: proc "contextless" (m: Matrix3f64) -> (t1, t2, t3: f64) {
T1 := math.atan2(m[1, 2], m[0, 2])
S2 := math.sqrt(m[2, 0]*m[2, 0] + m[2, 1]*m[2, 1])
T2 := math.atan2(S2, m[2, 2])
@@ -666,7 +724,8 @@ euler_angles_zyz_from_matrix3_f64 :: proc(m: Matrix3f64) -> (t1, t2, t3: f64) {
return
}
euler_angles_zxz_from_matrix3_f64 :: proc(m: Matrix3f64) -> (t1, t2, t3: f64) {
@(require_results)
euler_angles_zxz_from_matrix3_f64 :: proc "contextless" (m: Matrix3f64) -> (t1, t2, t3: f64) {
T1 := math.atan2(m[0, 2], -m[1, 2])
S2 := math.sqrt(m[2, 0]*m[2, 0] + m[2, 1]*m[2, 1])
T2 := math.atan2(S2, m[2, 2])
@@ -679,7 +738,8 @@ euler_angles_zxz_from_matrix3_f64 :: proc(m: Matrix3f64) -> (t1, t2, t3: f64) {
return
}
euler_angles_xzy_from_matrix3_f64 :: proc(m: Matrix3f64) -> (t1, t2, t3: f64) {
@(require_results)
euler_angles_xzy_from_matrix3_f64 :: proc "contextless" (m: Matrix3f64) -> (t1, t2, t3: f64) {
T1 := math.atan2(m[2, 1], m[1, 1])
C2 := math.sqrt(m[0, 0]*m[0, 0] + m[0, 2]*m[0, 2])
T2 := math.atan2(-m[0, 1], C2)
@@ -692,7 +752,8 @@ euler_angles_xzy_from_matrix3_f64 :: proc(m: Matrix3f64) -> (t1, t2, t3: f64) {
return
}
euler_angles_yzx_from_matrix3_f64 :: proc(m: Matrix3f64) -> (t1, t2, t3: f64) {
@(require_results)
euler_angles_yzx_from_matrix3_f64 :: proc "contextless" (m: Matrix3f64) -> (t1, t2, t3: f64) {
T1 := math.atan2(-m[2, 0], m[0, 0])
C2 := math.sqrt(m[1, 1]*m[1, 1] + m[1, 2]*m[1, 2])
T2 := math.atan2(m[1, 0], C2)
@@ -705,7 +766,8 @@ euler_angles_yzx_from_matrix3_f64 :: proc(m: Matrix3f64) -> (t1, t2, t3: f64) {
return
}
euler_angles_zyx_from_matrix3_f64 :: proc(m: Matrix3f64) -> (t1, t2, t3: f64) {
@(require_results)
euler_angles_zyx_from_matrix3_f64 :: proc "contextless" (m: Matrix3f64) -> (t1, t2, t3: f64) {
T1 := math.atan2(m[1, 0], m[0, 0])
C2 := math.sqrt(m[2, 1]*m[2, 1] + m[2, 2]*m[2, 2])
T2 := math.atan2(-m[2, 0], C2)
@@ -718,7 +780,8 @@ euler_angles_zyx_from_matrix3_f64 :: proc(m: Matrix3f64) -> (t1, t2, t3: f64) {
return
}
euler_angles_zxy_from_matrix3_f64 :: proc(m: Matrix3f64) -> (t1, t2, t3: f64) {
@(require_results)
euler_angles_zxy_from_matrix3_f64 :: proc "contextless" (m: Matrix3f64) -> (t1, t2, t3: f64) {
T1 := math.atan2(-m[0, 1], m[1, 1])
C2 := math.sqrt(m[2, 0]*m[2, 0] + m[2, 2]*m[2, 2])
T2 := math.atan2(m[2, 1], C2)
@@ -735,7 +798,8 @@ euler_angles_zxy_from_matrix3_f64 :: proc(m: Matrix3f64) -> (t1, t2, t3: f64) {
// Matrix4
matrix4_from_euler_angle_x_f64 :: proc(angle_x: f64) -> (m: Matrix4f64) {
@(require_results)
matrix4_from_euler_angle_x_f64 :: proc "contextless" (angle_x: f64) -> (m: Matrix4f64) {
cos_x, sin_x := math.cos(angle_x), math.sin(angle_x)
m[0, 0] = 1
m[1, 1] = +cos_x
@@ -745,7 +809,8 @@ matrix4_from_euler_angle_x_f64 :: proc(angle_x: f64) -> (m: Matrix4f64) {
m[3, 3] = 1
return
}
matrix4_from_euler_angle_y_f64 :: proc(angle_y: f64) -> (m: Matrix4f64) {
@(require_results)
matrix4_from_euler_angle_y_f64 :: proc "contextless" (angle_y: f64) -> (m: Matrix4f64) {
cos_y, sin_y := math.cos(angle_y), math.sin(angle_y)
m[0, 0] = +cos_y
m[0, 2] = -sin_y
@@ -755,7 +820,8 @@ matrix4_from_euler_angle_y_f64 :: proc(angle_y: f64) -> (m: Matrix4f64) {
m[3, 3] = 1
return
}
matrix4_from_euler_angle_z_f64 :: proc(angle_z: f64) -> (m: Matrix4f64) {
@(require_results)
matrix4_from_euler_angle_z_f64 :: proc "contextless" (angle_z: f64) -> (m: Matrix4f64) {
cos_z, sin_z := math.cos(angle_z), math.sin(angle_z)
m[0, 0] = +cos_z
m[0, 1] = +sin_z
@@ -767,7 +833,8 @@ matrix4_from_euler_angle_z_f64 :: proc(angle_z: f64) -> (m: Matrix4f64) {
}
matrix4_from_derived_euler_angle_x_f64 :: proc(angle_x: f64, angular_velocity_x: f64) -> (m: Matrix4f64) {
@(require_results)
matrix4_from_derived_euler_angle_x_f64 :: proc "contextless" (angle_x: f64, angular_velocity_x: f64) -> (m: Matrix4f64) {
cos_x := math.cos(angle_x) * angular_velocity_x
sin_x := math.sin(angle_x) * angular_velocity_x
m[0, 0] = 1
@@ -778,7 +845,8 @@ matrix4_from_derived_euler_angle_x_f64 :: proc(angle_x: f64, angular_velocity_x:
m[3, 3] = 1
return
}
matrix4_from_derived_euler_angle_y_f64 :: proc(angle_y: f64, angular_velocity_y: f64) -> (m: Matrix4f64) {
@(require_results)
matrix4_from_derived_euler_angle_y_f64 :: proc "contextless" (angle_y: f64, angular_velocity_y: f64) -> (m: Matrix4f64) {
cos_y := math.cos(angle_y) * angular_velocity_y
sin_y := math.sin(angle_y) * angular_velocity_y
m[0, 0] = +cos_y
@@ -789,7 +857,8 @@ matrix4_from_derived_euler_angle_y_f64 :: proc(angle_y: f64, angular_velocity_y:
m[3, 3] = 1
return
}
matrix4_from_derived_euler_angle_z_f64 :: proc(angle_z: f64, angular_velocity_z: f64) -> (m: Matrix4f64) {
@(require_results)
matrix4_from_derived_euler_angle_z_f64 :: proc "contextless" (angle_z: f64, angular_velocity_z: f64) -> (m: Matrix4f64) {
cos_z := math.cos(angle_z) * angular_velocity_z
sin_z := math.sin(angle_z) * angular_velocity_z
m[0, 0] = +cos_z
@@ -802,7 +871,8 @@ matrix4_from_derived_euler_angle_z_f64 :: proc(angle_z: f64, angular_velocity_z:
}
matrix4_from_euler_angles_xy_f64 :: proc(angle_x, angle_y: f64) -> (m: Matrix4f64) {
@(require_results)
matrix4_from_euler_angles_xy_f64 :: proc "contextless" (angle_x, angle_y: f64) -> (m: Matrix4f64) {
cos_x, sin_x := math.cos(angle_x), math.sin(angle_x)
cos_y, sin_y := math.cos(angle_y), math.sin(angle_y)
m[0, 0] = cos_y
@@ -818,7 +888,8 @@ matrix4_from_euler_angles_xy_f64 :: proc(angle_x, angle_y: f64) -> (m: Matrix4f6
}
matrix4_from_euler_angles_yx_f64 :: proc(angle_y, angle_x: f64) -> (m: Matrix4f64) {
@(require_results)
matrix4_from_euler_angles_yx_f64 :: proc "contextless" (angle_y, angle_x: f64) -> (m: Matrix4f64) {
cos_x, sin_x := math.cos(angle_x), math.sin(angle_x)
cos_y, sin_y := math.cos(angle_y), math.sin(angle_y)
m[0, 0] = cos_y
@@ -833,21 +904,26 @@ matrix4_from_euler_angles_yx_f64 :: proc(angle_y, angle_x: f64) -> (m: Matrix4f6
return
}
matrix4_from_euler_angles_xz_f64 :: proc(angle_x, angle_z: f64) -> (m: Matrix4f64) {
@(require_results)
matrix4_from_euler_angles_xz_f64 :: proc "contextless" (angle_x, angle_z: f64) -> (m: Matrix4f64) {
return mul(matrix4_from_euler_angle_x(angle_x), matrix4_from_euler_angle_z(angle_z))
}
matrix4_from_euler_angles_zx_f64 :: proc(angle_z, angle_x: f64) -> (m: Matrix4f64) {
@(require_results)
matrix4_from_euler_angles_zx_f64 :: proc "contextless" (angle_z, angle_x: f64) -> (m: Matrix4f64) {
return mul(matrix4_from_euler_angle_z(angle_z), matrix4_from_euler_angle_x(angle_x))
}
matrix4_from_euler_angles_yz_f64 :: proc(angle_y, angle_z: f64) -> (m: Matrix4f64) {
@(require_results)
matrix4_from_euler_angles_yz_f64 :: proc "contextless" (angle_y, angle_z: f64) -> (m: Matrix4f64) {
return mul(matrix4_from_euler_angle_y(angle_y), matrix4_from_euler_angle_z(angle_z))
}
matrix4_from_euler_angles_zy_f64 :: proc(angle_z, angle_y: f64) -> (m: Matrix4f64) {
@(require_results)
matrix4_from_euler_angles_zy_f64 :: proc "contextless" (angle_z, angle_y: f64) -> (m: Matrix4f64) {
return mul(matrix4_from_euler_angle_z(angle_z), matrix4_from_euler_angle_y(angle_y))
}
matrix4_from_euler_angles_xyz_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix4f64) {
@(require_results)
matrix4_from_euler_angles_xyz_f64 :: proc "contextless" (t1, t2, t3: f64) -> (m: Matrix4f64) {
c1 := math.cos(-t1)
c2 := math.cos(-t2)
c3 := math.cos(-t3)
@@ -874,7 +950,8 @@ matrix4_from_euler_angles_xyz_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix4f64) {
return
}
matrix4_from_euler_angles_yxz_f64 :: proc(yaw, pitch, roll: f64) -> (m: Matrix4f64) {
@(require_results)
matrix4_from_euler_angles_yxz_f64 :: proc "contextless" (yaw, pitch, roll: f64) -> (m: Matrix4f64) {
ch := math.cos(yaw)
sh := math.sin(yaw)
cp := math.cos(pitch)
@@ -901,7 +978,8 @@ matrix4_from_euler_angles_yxz_f64 :: proc(yaw, pitch, roll: f64) -> (m: Matrix4f
return
}
matrix4_from_euler_angles_xzx_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix4f64) {
@(require_results)
matrix4_from_euler_angles_xzx_f64 :: proc "contextless" (t1, t2, t3: f64) -> (m: Matrix4f64) {
c1 := math.cos(t1)
s1 := math.sin(t1)
c2 := math.cos(t2)
@@ -928,7 +1006,8 @@ matrix4_from_euler_angles_xzx_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix4f64) {
return
}
matrix4_from_euler_angles_xyx_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix4f64) {
@(require_results)
matrix4_from_euler_angles_xyx_f64 :: proc "contextless" (t1, t2, t3: f64) -> (m: Matrix4f64) {
c1 := math.cos(t1)
s1 := math.sin(t1)
c2 := math.cos(t2)
@@ -955,7 +1034,8 @@ matrix4_from_euler_angles_xyx_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix4f64) {
return
}
matrix4_from_euler_angles_yxy_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix4f64) {
@(require_results)
matrix4_from_euler_angles_yxy_f64 :: proc "contextless" (t1, t2, t3: f64) -> (m: Matrix4f64) {
c1 := math.cos(t1)
s1 := math.sin(t1)
c2 := math.cos(t2)
@@ -982,7 +1062,8 @@ matrix4_from_euler_angles_yxy_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix4f64) {
return
}
matrix4_from_euler_angles_yzy_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix4f64) {
@(require_results)
matrix4_from_euler_angles_yzy_f64 :: proc "contextless" (t1, t2, t3: f64) -> (m: Matrix4f64) {
c1 := math.cos(t1)
s1 := math.sin(t1)
c2 := math.cos(t2)
@@ -1009,7 +1090,8 @@ matrix4_from_euler_angles_yzy_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix4f64) {
return
}
matrix4_from_euler_angles_zyz_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix4f64) {
@(require_results)
matrix4_from_euler_angles_zyz_f64 :: proc "contextless" (t1, t2, t3: f64) -> (m: Matrix4f64) {
c1 := math.cos(t1)
s1 := math.sin(t1)
c2 := math.cos(t2)
@@ -1036,7 +1118,8 @@ matrix4_from_euler_angles_zyz_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix4f64) {
return
}
matrix4_from_euler_angles_zxz_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix4f64) {
@(require_results)
matrix4_from_euler_angles_zxz_f64 :: proc "contextless" (t1, t2, t3: f64) -> (m: Matrix4f64) {
c1 := math.cos(t1)
s1 := math.sin(t1)
c2 := math.cos(t2)
@@ -1064,7 +1147,8 @@ matrix4_from_euler_angles_zxz_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix4f64) {
}
matrix4_from_euler_angles_xzy_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix4f64) {
@(require_results)
matrix4_from_euler_angles_xzy_f64 :: proc "contextless" (t1, t2, t3: f64) -> (m: Matrix4f64) {
c1 := math.cos(t1)
s1 := math.sin(t1)
c2 := math.cos(t2)
@@ -1091,7 +1175,8 @@ matrix4_from_euler_angles_xzy_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix4f64) {
return
}
matrix4_from_euler_angles_yzx_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix4f64) {
@(require_results)
matrix4_from_euler_angles_yzx_f64 :: proc "contextless" (t1, t2, t3: f64) -> (m: Matrix4f64) {
c1 := math.cos(t1)
s1 := math.sin(t1)
c2 := math.cos(t2)
@@ -1118,7 +1203,8 @@ matrix4_from_euler_angles_yzx_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix4f64) {
return
}
matrix4_from_euler_angles_zyx_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix4f64) {
@(require_results)
matrix4_from_euler_angles_zyx_f64 :: proc "contextless" (t1, t2, t3: f64) -> (m: Matrix4f64) {
c1 := math.cos(t1)
s1 := math.sin(t1)
c2 := math.cos(t2)
@@ -1145,7 +1231,8 @@ matrix4_from_euler_angles_zyx_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix4f64) {
return
}
matrix4_from_euler_angles_zxy_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix4f64) {
@(require_results)
matrix4_from_euler_angles_zxy_f64 :: proc "contextless" (t1, t2, t3: f64) -> (m: Matrix4f64) {
c1 := math.cos(t1)
s1 := math.sin(t1)
c2 := math.cos(t2)
@@ -1173,7 +1260,8 @@ matrix4_from_euler_angles_zxy_f64 :: proc(t1, t2, t3: f64) -> (m: Matrix4f64) {
}
matrix4_from_yaw_pitch_roll_f64 :: proc(yaw, pitch, roll: f64) -> (m: Matrix4f64) {
@(require_results)
matrix4_from_yaw_pitch_roll_f64 :: proc "contextless" (yaw, pitch, roll: f64) -> (m: Matrix4f64) {
ch := math.cos(yaw)
sh := math.sin(yaw)
cp := math.cos(pitch)
@@ -1200,7 +1288,8 @@ matrix4_from_yaw_pitch_roll_f64 :: proc(yaw, pitch, roll: f64) -> (m: Matrix4f64
return m
}
euler_angles_xyz_from_matrix4_f64 :: proc(m: Matrix4f64) -> (t1, t2, t3: f64) {
@(require_results)
euler_angles_xyz_from_matrix4_f64 :: proc "contextless" (m: Matrix4f64) -> (t1, t2, t3: f64) {
T1 := math.atan2(m[1, 2], m[2, 2])
C2 := math.sqrt(m[0, 0]*m[0, 0] + m[0, 1]*m[0, 1])
T2 := math.atan2(-m[0, 2], C2)
@@ -1213,7 +1302,8 @@ euler_angles_xyz_from_matrix4_f64 :: proc(m: Matrix4f64) -> (t1, t2, t3: f64) {
return
}
euler_angles_yxz_from_matrix4_f64 :: proc(m: Matrix4f64) -> (t1, t2, t3: f64) {
@(require_results)
euler_angles_yxz_from_matrix4_f64 :: proc "contextless" (m: Matrix4f64) -> (t1, t2, t3: f64) {
T1 := math.atan2(m[0, 2], m[2, 2])
C2 := math.sqrt(m[1, 0]*m[1, 0] + m[1, 1]*m[1, 1])
T2 := math.atan2(-m[1, 2], C2)
@@ -1226,7 +1316,8 @@ euler_angles_yxz_from_matrix4_f64 :: proc(m: Matrix4f64) -> (t1, t2, t3: f64) {
return
}
euler_angles_xzx_from_matrix4_f64 :: proc(m: Matrix4f64) -> (t1, t2, t3: f64) {
@(require_results)
euler_angles_xzx_from_matrix4_f64 :: proc "contextless" (m: Matrix4f64) -> (t1, t2, t3: f64) {
T1 := math.atan2(m[2, 0], m[1, 0])
S2 := math.sqrt(m[0, 1]*m[0, 1] + m[0, 2]*m[0, 2])
T2 := math.atan2(S2, m[0, 0])
@@ -1239,7 +1330,8 @@ euler_angles_xzx_from_matrix4_f64 :: proc(m: Matrix4f64) -> (t1, t2, t3: f64) {
return
}
euler_angles_xyx_from_matrix4_f64 :: proc(m: Matrix4f64) -> (t1, t2, t3: f64) {
@(require_results)
euler_angles_xyx_from_matrix4_f64 :: proc "contextless" (m: Matrix4f64) -> (t1, t2, t3: f64) {
T1 := math.atan2(m[1, 0], -m[2, 0])
S2 := math.sqrt(m[0, 1]*m[0, 1] + m[0, 2]*m[0, 2])
T2 := math.atan2(S2, m[0, 0])
@@ -1252,7 +1344,8 @@ euler_angles_xyx_from_matrix4_f64 :: proc(m: Matrix4f64) -> (t1, t2, t3: f64) {
return
}
euler_angles_yxy_from_matrix4_f64 :: proc(m: Matrix4f64) -> (t1, t2, t3: f64) {
@(require_results)
euler_angles_yxy_from_matrix4_f64 :: proc "contextless" (m: Matrix4f64) -> (t1, t2, t3: f64) {
T1 := math.atan2(m[0, 1], m[2, 1])
S2 := math.sqrt(m[1, 0]*m[1, 0] + m[1, 2]*m[1, 2])
T2 := math.atan2(S2, m[1, 1])
@@ -1265,7 +1358,8 @@ euler_angles_yxy_from_matrix4_f64 :: proc(m: Matrix4f64) -> (t1, t2, t3: f64) {
return
}
euler_angles_yzy_from_matrix4_f64 :: proc(m: Matrix4f64) -> (t1, t2, t3: f64) {
@(require_results)
euler_angles_yzy_from_matrix4_f64 :: proc "contextless" (m: Matrix4f64) -> (t1, t2, t3: f64) {
T1 := math.atan2(m[2, 1], -m[0, 1])
S2 := math.sqrt(m[1, 0]*m[1, 0] + m[1, 2]*m[1, 2])
T2 := math.atan2(S2, m[1, 1])
@@ -1277,7 +1371,8 @@ euler_angles_yzy_from_matrix4_f64 :: proc(m: Matrix4f64) -> (t1, t2, t3: f64) {
t3 = T3
return
}
euler_angles_zyz_from_matrix4_f64 :: proc(m: Matrix4f64) -> (t1, t2, t3: f64) {
@(require_results)
euler_angles_zyz_from_matrix4_f64 :: proc "contextless" (m: Matrix4f64) -> (t1, t2, t3: f64) {
T1 := math.atan2(m[1, 2], m[0, 2])
S2 := math.sqrt(m[2, 0]*m[2, 0] + m[2, 1]*m[2, 1])
T2 := math.atan2(S2, m[2, 2])
@@ -1290,7 +1385,8 @@ euler_angles_zyz_from_matrix4_f64 :: proc(m: Matrix4f64) -> (t1, t2, t3: f64) {
return
}
euler_angles_zxz_from_matrix4_f64 :: proc(m: Matrix4f64) -> (t1, t2, t3: f64) {
@(require_results)
euler_angles_zxz_from_matrix4_f64 :: proc "contextless" (m: Matrix4f64) -> (t1, t2, t3: f64) {
T1 := math.atan2(m[0, 2], -m[1, 2])
S2 := math.sqrt(m[2, 0]*m[2, 0] + m[2, 1]*m[2, 1])
T2 := math.atan2(S2, m[2, 2])
@@ -1303,7 +1399,8 @@ euler_angles_zxz_from_matrix4_f64 :: proc(m: Matrix4f64) -> (t1, t2, t3: f64) {
return
}
euler_angles_xzy_from_matrix4_f64 :: proc(m: Matrix4f64) -> (t1, t2, t3: f64) {
@(require_results)
euler_angles_xzy_from_matrix4_f64 :: proc "contextless" (m: Matrix4f64) -> (t1, t2, t3: f64) {
T1 := math.atan2(m[2, 1], m[1, 1])
C2 := math.sqrt(m[0, 0]*m[0, 0] + m[0, 2]*m[0, 2])
T2 := math.atan2(-m[0, 1], C2)
@@ -1316,7 +1413,8 @@ euler_angles_xzy_from_matrix4_f64 :: proc(m: Matrix4f64) -> (t1, t2, t3: f64) {
return
}
euler_angles_yzx_from_matrix4_f64 :: proc(m: Matrix4f64) -> (t1, t2, t3: f64) {
@(require_results)
euler_angles_yzx_from_matrix4_f64 :: proc "contextless" (m: Matrix4f64) -> (t1, t2, t3: f64) {
T1 := math.atan2(-m[2, 0], m[0, 0])
C2 := math.sqrt(m[1, 1]*m[1, 1] + m[1, 2]*m[1, 2])
T2 := math.atan2(m[1, 0], C2)
@@ -1329,7 +1427,8 @@ euler_angles_yzx_from_matrix4_f64 :: proc(m: Matrix4f64) -> (t1, t2, t3: f64) {
return
}
euler_angles_zyx_from_matrix4_f64 :: proc(m: Matrix4f64) -> (t1, t2, t3: f64) {
@(require_results)
euler_angles_zyx_from_matrix4_f64 :: proc "contextless" (m: Matrix4f64) -> (t1, t2, t3: f64) {
T1 := math.atan2(m[1, 0], m[0, 0])
C2 := math.sqrt(m[2, 1]*m[2, 1] + m[2, 2]*m[2, 2])
T2 := math.atan2(-m[2, 0], C2)
@@ -1342,7 +1441,8 @@ euler_angles_zyx_from_matrix4_f64 :: proc(m: Matrix4f64) -> (t1, t2, t3: f64) {
return
}
euler_angles_zxy_from_matrix4_f64 :: proc(m: Matrix4f64) -> (t1, t2, t3: f64) {
@(require_results)
euler_angles_zxy_from_matrix4_f64 :: proc "contextless" (m: Matrix4f64) -> (t1, t2, t3: f64) {
T1 := math.atan2(-m[0, 1], m[1, 1])
C2 := math.sqrt(m[2, 0]*m[2, 0] + m[2, 2]*m[2, 2])
T2 := math.atan2(m[2, 1], C2)
+64 -32
View File
@@ -37,110 +37,142 @@ Vector4_Components :: enum u8 {
a = 3,
}
scalar_f32_swizzle1 :: proc(f: f32, c0: Scalar_Components) -> f32 {
@(require_results)
scalar_f32_swizzle1 :: proc "contextless" (f: f32, c0: Scalar_Components) -> f32 {
return f
}
scalar_f32_swizzle2 :: proc(f: f32, c0, c1: Scalar_Components) -> Vector2f32 {
@(require_results)
scalar_f32_swizzle2 :: proc "contextless" (f: f32, c0, c1: Scalar_Components) -> Vector2f32 {
return {f, f}
}
scalar_f32_swizzle3 :: proc(f: f32, c0, c1, c2: Scalar_Components) -> Vector3f32 {
@(require_results)
scalar_f32_swizzle3 :: proc "contextless" (f: f32, c0, c1, c2: Scalar_Components) -> Vector3f32 {
return {f, f, f}
}
scalar_f32_swizzle4 :: proc(f: f32, c0, c1, c2, c3: Scalar_Components) -> Vector4f32 {
@(require_results)
scalar_f32_swizzle4 :: proc "contextless" (f: f32, c0, c1, c2, c3: Scalar_Components) -> Vector4f32 {
return {f, f, f, f}
}
vector2f32_swizzle1 :: proc(v: Vector2f32, c0: Vector2_Components) -> f32 {
@(require_results)
vector2f32_swizzle1 :: proc "contextless" (v: Vector2f32, c0: Vector2_Components) -> f32 {
return v[c0]
}
vector2f32_swizzle2 :: proc(v: Vector2f32, c0, c1: Vector2_Components) -> Vector2f32 {
@(require_results)
vector2f32_swizzle2 :: proc "contextless" (v: Vector2f32, c0, c1: Vector2_Components) -> Vector2f32 {
return {v[c0], v[c1]}
}
vector2f32_swizzle3 :: proc(v: Vector2f32, c0, c1, c2: Vector2_Components) -> Vector3f32 {
@(require_results)
vector2f32_swizzle3 :: proc "contextless" (v: Vector2f32, c0, c1, c2: Vector2_Components) -> Vector3f32 {
return {v[c0], v[c1], v[c2]}
}
vector2f32_swizzle4 :: proc(v: Vector2f32, c0, c1, c2, c3: Vector2_Components) -> Vector4f32 {
@(require_results)
vector2f32_swizzle4 :: proc "contextless" (v: Vector2f32, c0, c1, c2, c3: Vector2_Components) -> Vector4f32 {
return {v[c0], v[c1], v[c2], v[c3]}
}
vector3f32_swizzle1 :: proc(v: Vector3f32, c0: Vector3_Components) -> f32 {
@(require_results)
vector3f32_swizzle1 :: proc "contextless" (v: Vector3f32, c0: Vector3_Components) -> f32 {
return v[c0]
}
vector3f32_swizzle2 :: proc(v: Vector3f32, c0, c1: Vector3_Components) -> Vector2f32 {
@(require_results)
vector3f32_swizzle2 :: proc "contextless" (v: Vector3f32, c0, c1: Vector3_Components) -> Vector2f32 {
return {v[c0], v[c1]}
}
vector3f32_swizzle3 :: proc(v: Vector3f32, c0, c1, c2: Vector3_Components) -> Vector3f32 {
@(require_results)
vector3f32_swizzle3 :: proc "contextless" (v: Vector3f32, c0, c1, c2: Vector3_Components) -> Vector3f32 {
return {v[c0], v[c1], v[c2]}
}
vector3f32_swizzle4 :: proc(v: Vector3f32, c0, c1, c2, c3: Vector3_Components) -> Vector4f32 {
@(require_results)
vector3f32_swizzle4 :: proc "contextless" (v: Vector3f32, c0, c1, c2, c3: Vector3_Components) -> Vector4f32 {
return {v[c0], v[c1], v[c2], v[c3]}
}
vector4f32_swizzle1 :: proc(v: Vector4f32, c0: Vector4_Components) -> f32 {
@(require_results)
vector4f32_swizzle1 :: proc "contextless" (v: Vector4f32, c0: Vector4_Components) -> f32 {
return v[c0]
}
vector4f32_swizzle2 :: proc(v: Vector4f32, c0, c1: Vector4_Components) -> Vector2f32 {
@(require_results)
vector4f32_swizzle2 :: proc "contextless" (v: Vector4f32, c0, c1: Vector4_Components) -> Vector2f32 {
return {v[c0], v[c1]}
}
vector4f32_swizzle3 :: proc(v: Vector4f32, c0, c1, c2: Vector4_Components) -> Vector3f32 {
@(require_results)
vector4f32_swizzle3 :: proc "contextless" (v: Vector4f32, c0, c1, c2: Vector4_Components) -> Vector3f32 {
return {v[c0], v[c1], v[c2]}
}
vector4f32_swizzle4 :: proc(v: Vector4f32, c0, c1, c2, c3: Vector4_Components) -> Vector4f32 {
@(require_results)
vector4f32_swizzle4 :: proc "contextless" (v: Vector4f32, c0, c1, c2, c3: Vector4_Components) -> Vector4f32 {
return {v[c0], v[c1], v[c2], v[c3]}
}
scalar_f64_swizzle1 :: proc(f: f64, c0: Scalar_Components) -> f64 {
@(require_results)
scalar_f64_swizzle1 :: proc "contextless" (f: f64, c0: Scalar_Components) -> f64 {
return f
}
scalar_f64_swizzle2 :: proc(f: f64, c0, c1: Scalar_Components) -> Vector2f64 {
@(require_results)
scalar_f64_swizzle2 :: proc "contextless" (f: f64, c0, c1: Scalar_Components) -> Vector2f64 {
return {f, f}
}
scalar_f64_swizzle3 :: proc(f: f64, c0, c1, c2: Scalar_Components) -> Vector3f64 {
@(require_results)
scalar_f64_swizzle3 :: proc "contextless" (f: f64, c0, c1, c2: Scalar_Components) -> Vector3f64 {
return {f, f, f}
}
scalar_f64_swizzle4 :: proc(f: f64, c0, c1, c2, c3: Scalar_Components) -> Vector4f64 {
@(require_results)
scalar_f64_swizzle4 :: proc "contextless" (f: f64, c0, c1, c2, c3: Scalar_Components) -> Vector4f64 {
return {f, f, f, f}
}
vector2f64_swizzle1 :: proc(v: Vector2f64, c0: Vector2_Components) -> f64 {
@(require_results)
vector2f64_swizzle1 :: proc "contextless" (v: Vector2f64, c0: Vector2_Components) -> f64 {
return v[c0]
}
vector2f64_swizzle2 :: proc(v: Vector2f64, c0, c1: Vector2_Components) -> Vector2f64 {
@(require_results)
vector2f64_swizzle2 :: proc "contextless" (v: Vector2f64, c0, c1: Vector2_Components) -> Vector2f64 {
return {v[c0], v[c1]}
}
vector2f64_swizzle3 :: proc(v: Vector2f64, c0, c1, c2: Vector2_Components) -> Vector3f64 {
@(require_results)
vector2f64_swizzle3 :: proc "contextless" (v: Vector2f64, c0, c1, c2: Vector2_Components) -> Vector3f64 {
return {v[c0], v[c1], v[c2]}
}
vector2f64_swizzle4 :: proc(v: Vector2f64, c0, c1, c2, c3: Vector2_Components) -> Vector4f64 {
@(require_results)
vector2f64_swizzle4 :: proc "contextless" (v: Vector2f64, c0, c1, c2, c3: Vector2_Components) -> Vector4f64 {
return {v[c0], v[c1], v[c2], v[c3]}
}
vector3f64_swizzle1 :: proc(v: Vector3f64, c0: Vector3_Components) -> f64 {
@(require_results)
vector3f64_swizzle1 :: proc "contextless" (v: Vector3f64, c0: Vector3_Components) -> f64 {
return v[c0]
}
vector3f64_swizzle2 :: proc(v: Vector3f64, c0, c1: Vector3_Components) -> Vector2f64 {
@(require_results)
vector3f64_swizzle2 :: proc "contextless" (v: Vector3f64, c0, c1: Vector3_Components) -> Vector2f64 {
return {v[c0], v[c1]}
}
vector3f64_swizzle3 :: proc(v: Vector3f64, c0, c1, c2: Vector3_Components) -> Vector3f64 {
@(require_results)
vector3f64_swizzle3 :: proc "contextless" (v: Vector3f64, c0, c1, c2: Vector3_Components) -> Vector3f64 {
return {v[c0], v[c1], v[c2]}
}
vector3f64_swizzle4 :: proc(v: Vector3f64, c0, c1, c2, c3: Vector3_Components) -> Vector4f64 {
@(require_results)
vector3f64_swizzle4 :: proc "contextless" (v: Vector3f64, c0, c1, c2, c3: Vector3_Components) -> Vector4f64 {
return {v[c0], v[c1], v[c2], v[c3]}
}
vector4f64_swizzle1 :: proc(v: Vector4f64, c0: Vector4_Components) -> f64 {
@(require_results)
vector4f64_swizzle1 :: proc "contextless" (v: Vector4f64, c0: Vector4_Components) -> f64 {
return v[c0]
}
vector4f64_swizzle2 :: proc(v: Vector4f64, c0, c1: Vector4_Components) -> Vector2f64 {
@(require_results)
vector4f64_swizzle2 :: proc "contextless" (v: Vector4f64, c0, c1: Vector4_Components) -> Vector2f64 {
return {v[c0], v[c1]}
}
vector4f64_swizzle3 :: proc(v: Vector4f64, c0, c1, c2: Vector4_Components) -> Vector3f64 {
@(require_results)
vector4f64_swizzle3 :: proc "contextless" (v: Vector4f64, c0, c1, c2: Vector4_Components) -> Vector3f64 {
return {v[c0], v[c1], v[c2]}
}
vector4f64_swizzle4 :: proc(v: Vector4f64, c0, c1, c2, c3: Vector4_Components) -> Vector4f64 {
@(require_results)
vector4f64_swizzle4 :: proc "contextless" (v: Vector4f64, c0, c1, c2, c3: Vector4_Components) -> Vector4f64 {
return {v[c0], v[c1], v[c2], v[c3]}
}
+477 -261
View File
File diff suppressed because it is too large Load Diff
+109 -39
View File
@@ -3,56 +3,126 @@ package math
import "core:intrinsics"
@(default_calling_convention="none")
@(default_calling_convention="none", private="file")
foreign _ {
@(link_name="llvm.sin.f16")
sin_f16 :: proc(θ: f16) -> f16 ---
@(link_name="llvm.sin.f32")
sin_f32 :: proc(θ: f32) -> f32 ---
@(link_name="llvm.sin.f64")
sin_f64 :: proc(θ: f64) -> f64 ---
@(link_name="llvm.sin.f16", require_results)
_sin_f16 :: proc(θ: f16) -> f16 ---
@(link_name="llvm.sin.f32", require_results)
_sin_f32 :: proc(θ: f32) -> f32 ---
@(link_name="llvm.sin.f64", require_results)
_sin_f64 :: proc(θ: f64) -> f64 ---
@(link_name="llvm.cos.f16")
cos_f16 :: proc(θ: f16) -> f16 ---
@(link_name="llvm.cos.f32")
cos_f32 :: proc(θ: f32) -> f32 ---
@(link_name="llvm.cos.f64")
cos_f64 :: proc(θ: f64) -> f64 ---
@(link_name="llvm.cos.f16", require_results)
_cos_f16 :: proc(θ: f16) -> f16 ---
@(link_name="llvm.cos.f32", require_results)
_cos_f32 :: proc(θ: f32) -> f32 ---
@(link_name="llvm.cos.f64", require_results)
_cos_f64 :: proc(θ: f64) -> f64 ---
@(link_name="llvm.pow.f16")
pow_f16 :: proc(x, power: f16) -> f16 ---
@(link_name="llvm.pow.f32")
pow_f32 :: proc(x, power: f32) -> f32 ---
@(link_name="llvm.pow.f64")
pow_f64 :: proc(x, power: f64) -> f64 ---
@(link_name="llvm.pow.f16", require_results)
_pow_f16 :: proc(x, power: f16) -> f16 ---
@(link_name="llvm.pow.f32", require_results)
_pow_f32 :: proc(x, power: f32) -> f32 ---
@(link_name="llvm.pow.f64", require_results)
_pow_f64 :: proc(x, power: f64) -> f64 ---
@(link_name="llvm.fmuladd.f16")
fmuladd_f16 :: proc(a, b, c: f16) -> f16 ---
@(link_name="llvm.fmuladd.f32")
fmuladd_f32 :: proc(a, b, c: f32) -> f32 ---
@(link_name="llvm.fmuladd.f64")
fmuladd_f64 :: proc(a, b, c: f64) -> f64 ---
@(link_name="llvm.fmuladd.f16", require_results)
_fmuladd_f16 :: proc(a, b, c: f16) -> f16 ---
@(link_name="llvm.fmuladd.f32", require_results)
_fmuladd_f32 :: proc(a, b, c: f32) -> f32 ---
@(link_name="llvm.fmuladd.f64", require_results)
_fmuladd_f64 :: proc(a, b, c: f64) -> f64 ---
@(link_name="llvm.exp.f16")
exp_f16 :: proc(x: f16) -> f16 ---
@(link_name="llvm.exp.f32")
exp_f32 :: proc(x: f32) -> f32 ---
@(link_name="llvm.exp.f64")
exp_f64 :: proc(x: f64) -> f64 ---
@(link_name="llvm.exp.f16", require_results)
_exp_f16 :: proc(x: f16) -> f16 ---
@(link_name="llvm.exp.f32", require_results)
_exp_f32 :: proc(x: f32) -> f32 ---
@(link_name="llvm.exp.f64", require_results)
_exp_f64 :: proc(x: f64) -> f64 ---
}
@(require_results)
sin_f16 :: proc "contextless" (θ: f16) -> f16 {
return _sin_f16(θ)
}
@(require_results)
sin_f32 :: proc "contextless" (θ: f32) -> f32 {
return _sin_f32(θ)
}
@(require_results)
sin_f64 :: proc "contextless" (θ: f64) -> f64 {
return _sin_f64(θ)
}
@(require_results)
cos_f16 :: proc "contextless" (θ: f16) -> f16 {
return _cos_f16(θ)
}
@(require_results)
cos_f32 :: proc "contextless" (θ: f32) -> f32 {
return _cos_f32(θ)
}
@(require_results)
cos_f64 :: proc "contextless" (θ: f64) -> f64 {
return _cos_f64(θ)
}
@(require_results)
pow_f16 :: proc "contextless" (x, power: f16) -> f16 {
return _pow_f16(x, power)
}
@(require_results)
pow_f32 :: proc "contextless" (x, power: f32) -> f32 {
return _pow_f32(x, power)
}
@(require_results)
pow_f64 :: proc "contextless" (x, power: f64) -> f64 {
return _pow_f64(x, power)
}
@(require_results)
fmuladd_f16 :: proc "contextless" (a, b, c: f16) -> f16 {
return _fmuladd_f16(a, b, c)
}
@(require_results)
fmuladd_f32 :: proc "contextless" (a, b, c: f32) -> f32 {
return _fmuladd_f32(a, b, c)
}
@(require_results)
fmuladd_f64 :: proc "contextless" (a, b, c: f64) -> f64 {
return _fmuladd_f64(a, b, c)
}
@(require_results)
exp_f16 :: proc "contextless" (x: f16) -> f16 {
return _exp_f16(x)
}
@(require_results)
exp_f32 :: proc "contextless" (x: f32) -> f32 {
return _exp_f32(x)
}
@(require_results)
exp_f64 :: proc "contextless" (x: f64) -> f64 {
return _exp_f64(x)
}
@(require_results)
sqrt_f16 :: proc "contextless" (x: f16) -> f16 {
return intrinsics.sqrt(x)
}
@(require_results)
sqrt_f32 :: proc "contextless" (x: f32) -> f32 {
return intrinsics.sqrt(x)
}
@(require_results)
sqrt_f64 :: proc "contextless" (x: f64) -> f64 {
return intrinsics.sqrt(x)
}
@(require_results)
ln_f64 :: proc "contextless" (x: f64) -> f64 {
// The original C code, the long comment, and the constants
// below are from FreeBSD's /usr/src/lib/msun/src/e_log.c
@@ -154,14 +224,14 @@ ln_f64 :: proc "contextless" (x: f64) -> f64 {
return k*LN2_HI - ((hfsq - (s*(hfsq+R) + k*LN2_LO)) - f)
}
ln_f16 :: proc "contextless" (x: f16) -> f16 { return #force_inline f16(ln_f64(f64(x))) }
ln_f32 :: proc "contextless" (x: f32) -> f32 { return #force_inline f32(ln_f64(f64(x))) }
ln_f16le :: proc "contextless" (x: f16le) -> f16le { return #force_inline f16le(ln_f64(f64(x))) }
ln_f16be :: proc "contextless" (x: f16be) -> f16be { return #force_inline f16be(ln_f64(f64(x))) }
ln_f32le :: proc "contextless" (x: f32le) -> f32le { return #force_inline f32le(ln_f64(f64(x))) }
ln_f32be :: proc "contextless" (x: f32be) -> f32be { return #force_inline f32be(ln_f64(f64(x))) }
ln_f64le :: proc "contextless" (x: f64le) -> f64le { return #force_inline f64le(ln_f64(f64(x))) }
ln_f64be :: proc "contextless" (x: f64be) -> f64be { return #force_inline f64be(ln_f64(f64(x))) }
@(require_results) ln_f16 :: proc "contextless" (x: f16) -> f16 { return #force_inline f16(ln_f64(f64(x))) }
@(require_results) ln_f32 :: proc "contextless" (x: f32) -> f32 { return #force_inline f32(ln_f64(f64(x))) }
@(require_results) ln_f16le :: proc "contextless" (x: f16le) -> f16le { return #force_inline f16le(ln_f64(f64(x))) }
@(require_results) ln_f16be :: proc "contextless" (x: f16be) -> f16be { return #force_inline f16be(ln_f64(f64(x))) }
@(require_results) ln_f32le :: proc "contextless" (x: f32le) -> f32le { return #force_inline f32le(ln_f64(f64(x))) }
@(require_results) ln_f32be :: proc "contextless" (x: f32be) -> f32be { return #force_inline f32be(ln_f64(f64(x))) }
@(require_results) ln_f64le :: proc "contextless" (x: f64le) -> f64le { return #force_inline f64le(ln_f64(f64(x))) }
@(require_results) ln_f64be :: proc "contextless" (x: f64be) -> f64be { return #force_inline f64be(ln_f64(f64(x))) }
ln :: proc{
ln_f16, ln_f16le, ln_f16be,
ln_f32, ln_f32le, ln_f32be,
+27 -26
View File
@@ -7,46 +7,47 @@ foreign import "odin_env"
@(default_calling_convention="c")
foreign odin_env {
@(link_name="sin")
@(link_name="sin", require_results)
sin_f64 :: proc(θ: f64) -> f64 ---
@(link_name="cos")
@(link_name="cos", require_results)
cos_f64 :: proc(θ: f64) -> f64 ---
@(link_name="pow")
@(link_name="pow", require_results)
pow_f64 :: proc(x, power: f64) -> f64 ---
@(link_name="fmuladd")
@(link_name="fmuladd", require_results)
fmuladd_f64 :: proc(a, b, c: f64) -> f64 ---
@(link_name="ln")
@(link_name="ln", require_results)
ln_f64 :: proc(x: f64) -> f64 ---
@(link_name="exp")
@(link_name="exp", require_results)
exp_f64 :: proc(x: f64) -> f64 ---
}
@(require_results)
sqrt_f64 :: proc "contextless" (x: f64) -> f64 {
return intrinsics.sqrt(x)
}
sqrt_f16 :: proc "c" (x: f16) -> f16 { return f16(sqrt_f64(f64(x))) }
sin_f16 :: proc "c" (θ: f16) -> f16 { return f16(sin_f64(f64(θ))) }
cos_f16 :: proc "c" (θ: f16) -> f16 { return f16(cos_f64(f64(θ))) }
pow_f16 :: proc "c" (x, power: f16) -> f16 { return f16(pow_f64(f64(x), f64(power))) }
fmuladd_f16 :: proc "c" (a, b, c: f16) -> f16 { return f16(fmuladd_f64(f64(a), f64(a), f64(c))) }
ln_f16 :: proc "c" (x: f16) -> f16 { return f16(ln_f64(f64(x))) }
exp_f16 :: proc "c" (x: f16) -> f16 { return f16(exp_f64(f64(x))) }
@(require_results) sqrt_f16 :: proc "c" (x: f16) -> f16 { return f16(sqrt_f64(f64(x))) }
@(require_results) sin_f16 :: proc "c" (θ: f16) -> f16 { return f16(sin_f64(f64(θ))) }
@(require_results) cos_f16 :: proc "c" (θ: f16) -> f16 { return f16(cos_f64(f64(θ))) }
@(require_results) pow_f16 :: proc "c" (x, power: f16) -> f16 { return f16(pow_f64(f64(x), f64(power))) }
@(require_results) fmuladd_f16 :: proc "c" (a, b, c: f16) -> f16 { return f16(fmuladd_f64(f64(a), f64(a), f64(c))) }
@(require_results) ln_f16 :: proc "c" (x: f16) -> f16 { return f16(ln_f64(f64(x))) }
@(require_results) exp_f16 :: proc "c" (x: f16) -> f16 { return f16(exp_f64(f64(x))) }
sqrt_f32 :: proc "c" (x: f32) -> f32 { return f32(sqrt_f64(f64(x))) }
sin_f32 :: proc "c" (θ: f32) -> f32 { return f32(sin_f64(f64(θ))) }
cos_f32 :: proc "c" (θ: f32) -> f32 { return f32(cos_f64(f64(θ))) }
pow_f32 :: proc "c" (x, power: f32) -> f32 { return f32(pow_f64(f64(x), f64(power))) }
fmuladd_f32 :: proc "c" (a, b, c: f32) -> f32 { return f32(fmuladd_f64(f64(a), f64(a), f64(c))) }
ln_f32 :: proc "c" (x: f32) -> f32 { return f32(ln_f64(f64(x))) }
exp_f32 :: proc "c" (x: f32) -> f32 { return f32(exp_f64(f64(x))) }
@(require_results) sqrt_f32 :: proc "c" (x: f32) -> f32 { return f32(sqrt_f64(f64(x))) }
@(require_results) sin_f32 :: proc "c" (θ: f32) -> f32 { return f32(sin_f64(f64(θ))) }
@(require_results) cos_f32 :: proc "c" (θ: f32) -> f32 { return f32(cos_f64(f64(θ))) }
@(require_results) pow_f32 :: proc "c" (x, power: f32) -> f32 { return f32(pow_f64(f64(x), f64(power))) }
@(require_results) fmuladd_f32 :: proc "c" (a, b, c: f32) -> f32 { return f32(fmuladd_f64(f64(a), f64(a), f64(c))) }
@(require_results) ln_f32 :: proc "c" (x: f32) -> f32 { return f32(ln_f64(f64(x))) }
@(require_results) exp_f32 :: proc "c" (x: f32) -> f32 { return f32(exp_f64(f64(x))) }
ln_f16le :: proc "contextless" (x: f16le) -> f16le { return #force_inline f16le(ln_f64(f64(x))) }
ln_f16be :: proc "contextless" (x: f16be) -> f16be { return #force_inline f16be(ln_f64(f64(x))) }
ln_f32le :: proc "contextless" (x: f32le) -> f32le { return #force_inline f32le(ln_f64(f64(x))) }
ln_f32be :: proc "contextless" (x: f32be) -> f32be { return #force_inline f32be(ln_f64(f64(x))) }
ln_f64le :: proc "contextless" (x: f64le) -> f64le { return #force_inline f64le(ln_f64(f64(x))) }
ln_f64be :: proc "contextless" (x: f64be) -> f64be { return #force_inline f64be(ln_f64(f64(x))) }
@(require_results) ln_f16le :: proc "contextless" (x: f16le) -> f16le { return #force_inline f16le(ln_f64(f64(x))) }
@(require_results) ln_f16be :: proc "contextless" (x: f16be) -> f16be { return #force_inline f16be(ln_f64(f64(x))) }
@(require_results) ln_f32le :: proc "contextless" (x: f32le) -> f32le { return #force_inline f32le(ln_f64(f64(x))) }
@(require_results) ln_f32be :: proc "contextless" (x: f32be) -> f32be { return #force_inline f32be(ln_f64(f64(x))) }
@(require_results) ln_f64le :: proc "contextless" (x: f64le) -> f64le { return #force_inline f64le(ln_f64(f64(x))) }
@(require_results) ln_f64be :: proc "contextless" (x: f64be) -> f64be { return #force_inline f64be(ln_f64(f64(x))) }
ln :: proc{
ln_f16, ln_f16le, ln_f16be,
ln_f32, ln_f32le, ln_f32be,
+14 -12
View File
@@ -117,13 +117,14 @@ erf :: proc{
erf_f64,
}
erf_f16 :: proc "contextless" (x: f16) -> f16 { return f16(erf_f64(f64(x))) }
erf_f16le :: proc "contextless" (x: f16le) -> f16le { return f16le(erf_f64(f64(x))) }
erf_f16be :: proc "contextless" (x: f16be) -> f16be { return f16be(erf_f64(f64(x))) }
erf_f32 :: proc "contextless" (x: f32) -> f32 { return f32(erf_f64(f64(x))) }
erf_f32le :: proc "contextless" (x: f32le) -> f32le { return f32le(erf_f64(f64(x))) }
erf_f32be :: proc "contextless" (x: f32be) -> f32be { return f32be(erf_f64(f64(x))) }
@(require_results) erf_f16 :: proc "contextless" (x: f16) -> f16 { return f16(erf_f64(f64(x))) }
@(require_results) erf_f16le :: proc "contextless" (x: f16le) -> f16le { return f16le(erf_f64(f64(x))) }
@(require_results) erf_f16be :: proc "contextless" (x: f16be) -> f16be { return f16be(erf_f64(f64(x))) }
@(require_results) erf_f32 :: proc "contextless" (x: f32) -> f32 { return f32(erf_f64(f64(x))) }
@(require_results) erf_f32le :: proc "contextless" (x: f32le) -> f32le { return f32le(erf_f64(f64(x))) }
@(require_results) erf_f32be :: proc "contextless" (x: f32be) -> f32be { return f32be(erf_f64(f64(x))) }
@(require_results)
erf_f64 :: proc "contextless" (x: f64) -> f64 {
erx :: 0h3FEB0AC160000000
// Coefficients for approximation to erf in [0, 0.84375]
@@ -268,13 +269,14 @@ erfc :: proc{
erfc_f64,
}
erfc_f16 :: proc "contextless" (x: f16) -> f16 { return f16(erfc_f64(f64(x))) }
erfc_f16le :: proc "contextless" (x: f16le) -> f16le { return f16le(erfc_f64(f64(x))) }
erfc_f16be :: proc "contextless" (x: f16be) -> f16be { return f16be(erfc_f64(f64(x))) }
erfc_f32 :: proc "contextless" (x: f32) -> f32 { return f32(erfc_f64(f64(x))) }
erfc_f32le :: proc "contextless" (x: f32le) -> f32le { return f32le(erfc_f64(f64(x))) }
erfc_f32be :: proc "contextless" (x: f32be) -> f32be { return f32be(erfc_f64(f64(x))) }
@(require_results) erfc_f16 :: proc "contextless" (x: f16) -> f16 { return f16(erfc_f64(f64(x))) }
@(require_results) erfc_f16le :: proc "contextless" (x: f16le) -> f16le { return f16le(erfc_f64(f64(x))) }
@(require_results) erfc_f16be :: proc "contextless" (x: f16be) -> f16be { return f16be(erfc_f64(f64(x))) }
@(require_results) erfc_f32 :: proc "contextless" (x: f32) -> f32 { return f32(erfc_f64(f64(x))) }
@(require_results) erfc_f32le :: proc "contextless" (x: f32le) -> f32le { return f32le(erfc_f64(f64(x))) }
@(require_results) erfc_f32be :: proc "contextless" (x: f32be) -> f32be { return f32be(erfc_f64(f64(x))) }
@(require_results)
erfc_f64 :: proc "contextless" (x: f64) -> f64 {
erx :: 0h3FEB0AC160000000
// Coefficients for approximation to erf in [0, 0.84375]
+10 -9
View File
@@ -65,7 +65,7 @@ package math
// The polynomial is valid for 33 <= x <= 172; larger values are only used
// in reciprocal and produce denormalized floats. The lower precision there
// masks any imprecision in the polynomial.
@(private="file")
@(private="file", require_results)
stirling :: proc "contextless" (x: f64) -> (f64, f64) {
@(static) gamS := [?]f64{
+7.87311395793093628397e-04,
@@ -93,6 +93,7 @@ stirling :: proc "contextless" (x: f64) -> (f64, f64) {
return y1, SQRT_TWO_PI * w * y2
}
@(require_results)
gamma_f64 :: proc "contextless" (x: f64) -> f64 {
is_neg_int :: proc "contextless" (x: f64) -> bool {
if x < 0 {
@@ -210,14 +211,14 @@ gamma_f64 :: proc "contextless" (x: f64) -> f64 {
}
gamma_f16 :: proc "contextless" (x: f16) -> f16 { return f16(gamma_f64(f64(x))) }
gamma_f16le :: proc "contextless" (x: f16le) -> f16le { return f16le(gamma_f64(f64(x))) }
gamma_f16be :: proc "contextless" (x: f16be) -> f16be { return f16be(gamma_f64(f64(x))) }
gamma_f32 :: proc "contextless" (x: f32) -> f32 { return f32(gamma_f64(f64(x))) }
gamma_f32le :: proc "contextless" (x: f32le) -> f32le { return f32le(gamma_f64(f64(x))) }
gamma_f32be :: proc "contextless" (x: f32be) -> f32be { return f32be(gamma_f64(f64(x))) }
gamma_f64le :: proc "contextless" (x: f64le) -> f64le { return f64le(gamma_f64(f64(x))) }
gamma_f64be :: proc "contextless" (x: f64be) -> f64be { return f64be(gamma_f64(f64(x))) }
@(require_results) gamma_f16 :: proc "contextless" (x: f16) -> f16 { return f16(gamma_f64(f64(x))) }
@(require_results) gamma_f16le :: proc "contextless" (x: f16le) -> f16le { return f16le(gamma_f64(f64(x))) }
@(require_results) gamma_f16be :: proc "contextless" (x: f16be) -> f16be { return f16be(gamma_f64(f64(x))) }
@(require_results) gamma_f32 :: proc "contextless" (x: f32) -> f32 { return f32(gamma_f64(f64(x))) }
@(require_results) gamma_f32le :: proc "contextless" (x: f32le) -> f32le { return f32le(gamma_f64(f64(x))) }
@(require_results) gamma_f32be :: proc "contextless" (x: f32be) -> f32be { return f32be(gamma_f64(f64(x))) }
@(require_results) gamma_f64le :: proc "contextless" (x: f64le) -> f64le { return f64le(gamma_f64(f64(x))) }
@(require_results) gamma_f64be :: proc "contextless" (x: f64be) -> f64be { return f64be(gamma_f64(f64(x))) }
gamma :: proc{
gamma_f16, gamma_f16le, gamma_f16be,
+10 -8
View File
@@ -80,7 +80,9 @@ package math
//
@(require_results)
lgamma_f64 :: proc "contextless" (x: f64) -> (lgamma: f64, sign: int) {
@(require_results)
sin_pi :: proc "contextless" (x: f64) -> f64 {
if x < 0.25 {
return -sin(PI * x)
@@ -345,14 +347,14 @@ lgamma_f64 :: proc "contextless" (x: f64) -> (lgamma: f64, sign: int) {
}
lgamma_f16 :: proc "contextless" (x: f16) -> (lgamma: f16, sign: int) { r, s := lgamma_f64(f64(x)); return f16(r), s }
lgamma_f32 :: proc "contextless" (x: f32) -> (lgamma: f32, sign: int) { r, s := lgamma_f64(f64(x)); return f32(r), s }
lgamma_f16le :: proc "contextless" (x: f16le) -> (lgamma: f16le, sign: int) { r, s := lgamma_f64(f64(x)); return f16le(r), s }
lgamma_f16be :: proc "contextless" (x: f16be) -> (lgamma: f16be, sign: int) { r, s := lgamma_f64(f64(x)); return f16be(r), s }
lgamma_f32le :: proc "contextless" (x: f32le) -> (lgamma: f32le, sign: int) { r, s := lgamma_f64(f64(x)); return f32le(r), s }
lgamma_f32be :: proc "contextless" (x: f32be) -> (lgamma: f32be, sign: int) { r, s := lgamma_f64(f64(x)); return f32be(r), s }
lgamma_f64le :: proc "contextless" (x: f64le) -> (lgamma: f64le, sign: int) { r, s := lgamma_f64(f64(x)); return f64le(r), s }
lgamma_f64be :: proc "contextless" (x: f64be) -> (lgamma: f64be, sign: int) { r, s := lgamma_f64(f64(x)); return f64be(r), s }
@(require_results) lgamma_f16 :: proc "contextless" (x: f16) -> (lgamma: f16, sign: int) { r, s := lgamma_f64(f64(x)); return f16(r), s }
@(require_results) lgamma_f32 :: proc "contextless" (x: f32) -> (lgamma: f32, sign: int) { r, s := lgamma_f64(f64(x)); return f32(r), s }
@(require_results) lgamma_f16le :: proc "contextless" (x: f16le) -> (lgamma: f16le, sign: int) { r, s := lgamma_f64(f64(x)); return f16le(r), s }
@(require_results) lgamma_f16be :: proc "contextless" (x: f16be) -> (lgamma: f16be, sign: int) { r, s := lgamma_f64(f64(x)); return f16be(r), s }
@(require_results) lgamma_f32le :: proc "contextless" (x: f32le) -> (lgamma: f32le, sign: int) { r, s := lgamma_f64(f64(x)); return f32le(r), s }
@(require_results) lgamma_f32be :: proc "contextless" (x: f32be) -> (lgamma: f32be, sign: int) { r, s := lgamma_f64(f64(x)); return f32be(r), s }
@(require_results) lgamma_f64le :: proc "contextless" (x: f64le) -> (lgamma: f64le, sign: int) { r, s := lgamma_f64(f64(x)); return f64le(r), s }
@(require_results) lgamma_f64be :: proc "contextless" (x: f64be) -> (lgamma: f64be, sign: int) { r, s := lgamma_f64(f64(x)); return f64be(r), s }
lgamma :: proc{
lgamma_f16, lgamma_f16le, lgamma_f16be,
+9 -8
View File
@@ -90,15 +90,16 @@ log1p :: proc {
log1p_f64le,
log1p_f64be,
}
log1p_f16 :: proc "contextless" (x: f16) -> f16 { return f16(log1p_f64(f64(x))) }
log1p_f32 :: proc "contextless" (x: f32) -> f32 { return f32(log1p_f64(f64(x))) }
log1p_f16le :: proc "contextless" (x: f16le) -> f16le { return f16le(log1p_f64(f64(x))) }
log1p_f16be :: proc "contextless" (x: f16be) -> f16be { return f16be(log1p_f64(f64(x))) }
log1p_f32le :: proc "contextless" (x: f32le) -> f32le { return f32le(log1p_f64(f64(x))) }
log1p_f32be :: proc "contextless" (x: f32be) -> f32be { return f32be(log1p_f64(f64(x))) }
log1p_f64le :: proc "contextless" (x: f64le) -> f64le { return f64le(log1p_f64(f64(x))) }
log1p_f64be :: proc "contextless" (x: f64be) -> f64be { return f64be(log1p_f64(f64(x))) }
@(require_results) log1p_f16 :: proc "contextless" (x: f16) -> f16 { return f16(log1p_f64(f64(x))) }
@(require_results) log1p_f32 :: proc "contextless" (x: f32) -> f32 { return f32(log1p_f64(f64(x))) }
@(require_results) log1p_f16le :: proc "contextless" (x: f16le) -> f16le { return f16le(log1p_f64(f64(x))) }
@(require_results) log1p_f16be :: proc "contextless" (x: f16be) -> f16be { return f16be(log1p_f64(f64(x))) }
@(require_results) log1p_f32le :: proc "contextless" (x: f32le) -> f32le { return f32le(log1p_f64(f64(x))) }
@(require_results) log1p_f32be :: proc "contextless" (x: f32be) -> f32be { return f32be(log1p_f64(f64(x))) }
@(require_results) log1p_f64le :: proc "contextless" (x: f64le) -> f64le { return f64le(log1p_f64(f64(x))) }
@(require_results) log1p_f64be :: proc "contextless" (x: f64be) -> f64be { return f64be(log1p_f64(f64(x))) }
@(require_results)
log1p_f64 :: proc "contextless" (x: f64) -> f64 {
SQRT2_M1 :: 0h3fda827999fcef34 // sqrt(2)-1
SQRT2_HALF_M1 :: 0hbfd2bec333018866 // sqrt(2)/2-1
+308
View File
@@ -0,0 +1,308 @@
package math
import "core:math/bits"
// The original C code, the long comment, and the constants
// below were from http://netlib.sandia.gov/cephes/cmath/sin.c,
// available from http://www.netlib.org/cephes/cmath.tgz.
// The go code is a simplified version of the original C.
//
// sin.c
//
// Circular sine
//
// SYNOPSIS:
//
// double x, y, sin();
// y = sin( x );
//
// DESCRIPTION:
//
// Range reduction is into intervals of pi/4. The reduction error is nearly
// eliminated by contriving an extended precision modular arithmetic.
//
// Two polynomial approximating functions are employed.
// Between 0 and pi/4 the sine is approximated by
// x + x**3 P(x**2).
// Between pi/4 and pi/2 the cosine is represented as
// 1 - x**2 Q(x**2).
//
// ACCURACY:
//
// Relative error:
// arithmetic domain # trials peak rms
// DEC 0, 10 150000 3.0e-17 7.8e-18
// IEEE -1.07e9,+1.07e9 130000 2.1e-16 5.4e-17
//
// Partial loss of accuracy begins to occur at x = 2**30 = 1.074e9. The loss
// is not gradual, but jumps suddenly to about 1 part in 10e7. Results may
// be meaningless for x > 2**49 = 5.6e14.
//
// cos.c
//
// Circular cosine
//
// SYNOPSIS:
//
// double x, y, cos();
// y = cos( x );
//
// DESCRIPTION:
//
// Range reduction is into intervals of pi/4. The reduction error is nearly
// eliminated by contriving an extended precision modular arithmetic.
//
// Two polynomial approximating functions are employed.
// Between 0 and pi/4 the cosine is approximated by
// 1 - x**2 Q(x**2).
// Between pi/4 and pi/2 the sine is represented as
// x + x**3 P(x**2).
//
// ACCURACY:
//
// Relative error:
// arithmetic domain # trials peak rms
// IEEE -1.07e9,+1.07e9 130000 2.1e-16 5.4e-17
// DEC 0,+1.07e9 17000 3.0e-17 7.2e-18
//
// Cephes Math Library Release 2.8: June, 2000
// Copyright 1984, 1987, 1989, 1992, 2000 by Stephen L. Moshier
//
// The readme file at http://netlib.sandia.gov/cephes/ says:
// Some software in this archive may be from the book _Methods and
// Programs for Mathematical Functions_ (Prentice-Hall or Simon & Schuster
// International, 1989) or from the Cephes Mathematical Library, a
// commercial product. In either event, it is copyrighted by the author.
// What you see here may be used freely but it comes with no support or
// guarantee.
//
// The two known misprints in the book are repaired here in the
// source listings for the gamma function and the incomplete beta
// integral.
//
// Stephen L. Moshier
// moshier@na-net.ornl.gov
sincos :: proc{
sincos_f16, sincos_f16le, sincos_f16be,
sincos_f32, sincos_f32le, sincos_f32be,
sincos_f64, sincos_f64le, sincos_f64be,
}
sincos_f16 :: proc "contextless" (x: f16) -> (sin, cos: f16) #no_bounds_check {
s, c := sincos_f64(f64(x))
return f16(s), f16(c)
}
sincos_f16le :: proc "contextless" (x: f16le) -> (sin, cos: f16le) #no_bounds_check {
s, c := sincos_f64(f64(x))
return f16le(s), f16le(c)
}
sincos_f16be :: proc "contextless" (x: f16be) -> (sin, cos: f16be) #no_bounds_check {
s, c := sincos_f64(f64(x))
return f16be(s), f16be(c)
}
sincos_f32 :: proc "contextless" (x: f32) -> (sin, cos: f32) #no_bounds_check {
s, c := sincos_f64(f64(x))
return f32(s), f32(c)
}
sincos_f32le :: proc "contextless" (x: f32le) -> (sin, cos: f32le) #no_bounds_check {
s, c := sincos_f64(f64(x))
return f32le(s), f32le(c)
}
sincos_f32be :: proc "contextless" (x: f32be) -> (sin, cos: f32be) #no_bounds_check {
s, c := sincos_f64(f64(x))
return f32be(s), f32be(c)
}
sincos_f64le :: proc "contextless" (x: f64le) -> (sin, cos: f64le) #no_bounds_check {
s, c := sincos_f64(f64(x))
return f64le(s), f64le(c)
}
sincos_f64be :: proc "contextless" (x: f64be) -> (sin, cos: f64be) #no_bounds_check {
s, c := sincos_f64(f64(x))
return f64be(s), f64be(c)
}
sincos_f64 :: proc "contextless" (x: f64) -> (sin, cos: f64) #no_bounds_check {
x := x
PI4A :: 0h3fe921fb40000000 // 7.85398125648498535156e-1 PI/4 split into three parts
PI4B :: 0h3e64442d00000000 // 3.77489470793079817668e-8
PI4C :: 0h3ce8469898cc5170 // 2.69515142907905952645e-15
// special cases
switch {
case x == 0:
return x, 1 // return ±0.0, 1.0
case is_nan(x) || is_inf(x, 0):
return nan_f64(), nan_f64()
}
// make argument positive
sin_sign, cos_sign := false, false
if x < 0 {
x = -x
sin_sign = true
}
j: u64
y, z: f64
if x >= REDUCE_THRESHOLD {
j, z = _trig_reduce_f64(x)
} else {
j = u64(x * (4 / PI)) // integer part of x/(PI/4), as integer for tests on the phase angle
y = f64(j) // integer part of x/(PI/4), as float
if j&1 == 1 { // map zeros to origin
j += 1
y += 1
}
j &= 7 // octant modulo TAU radians (360 degrees)
z = ((x - y*PI4A) - y*PI4B) - y*PI4C // Extended precision modular arithmetic
}
if j > 3 { // reflect in x axis
j -= 4
sin_sign, cos_sign = !sin_sign, !cos_sign
}
if j > 1 {
cos_sign = !cos_sign
}
zz := z * z
cos = 1.0 - 0.5*zz + zz*zz*((((((_cos[0]*zz)+_cos[1])*zz+_cos[2])*zz+_cos[3])*zz+_cos[4])*zz+_cos[5])
sin = z + z*zz*((((((_sin[0]*zz)+_sin[1])*zz+_sin[2])*zz+_sin[3])*zz+_sin[4])*zz+_sin[5])
if j == 1 || j == 2 {
sin, cos = cos, sin
}
if cos_sign {
cos = -cos
}
if sin_sign {
sin = -sin
}
return
}
// sin coefficients
@(private="file")
_sin := [?]f64{
0h3de5d8fd1fd19ccd, // 1.58962301576546568060e-10
0hbe5ae5e5a9291f5d, // -2.50507477628578072866e-8
0h3ec71de3567d48a1, // 2.75573136213857245213e-6
0hbf2a01a019bfdf03, // -1.98412698295895385996e-4
0h3f8111111110f7d0, // 8.33333333332211858878e-3
0hbfc5555555555548, // -1.66666666666666307295e-1
}
// cos coefficients
@(private="file")
_cos := [?]f64{
0hbda8fa49a0861a9b, // -1.13585365213876817300e-11,
0h3e21ee9d7b4e3f05, // 2.08757008419747316778e-9,
0hbe927e4f7eac4bc6, // -2.75573141792967388112e-7,
0h3efa01a019c844f5, // 2.48015872888517045348e-5,
0hbf56c16c16c14f91, // -1.38888888888730564116e-3,
0h3fa555555555554b, // 4.16666666666665929218e-2,
}
// REDUCE_THRESHOLD is the maximum value of x where the reduction using Pi/4
// in 3 f64 parts still gives accurate results. This threshold
// is set by y*C being representable as a f64 without error
// where y is given by y = floor(x * (4 / Pi)) and C is the leading partial
// terms of 4/Pi. Since the leading terms (PI4A and PI4B in sin.go) have 30
// and 32 trailing zero bits, y should have less than 30 significant bits.
//
// y < 1<<30 -> floor(x*4/Pi) < 1<<30 -> x < (1<<30 - 1) * Pi/4
//
// So, conservatively we can take x < 1<<29.
// Above this threshold Payne-Hanek range reduction must be used.
@(private="file")
REDUCE_THRESHOLD :: 1 << 29
// _trig_reduce_f64 implements Payne-Hanek range reduction by Pi/4
// for x > 0. It returns the integer part mod 8 (j) and
// the fractional part (z) of x / (Pi/4).
// The implementation is based on:
// "ARGUMENT REDUCTION FOR HUGE ARGUMENTS: Good to the Last Bit"
// K. C. Ng et al, March 24, 1992
// The simulated multi-precision calculation of x*B uses 64-bit integer arithmetic.
_trig_reduce_f64 :: proc "contextless" (x: f64) -> (j: u64, z: f64) #no_bounds_check {
// bd_pi4 is the binary digits of 4/pi as a u64 array,
// that is, 4/pi = Sum bd_pi4[i]*2^(-64*i)
// 19 64-bit digits and the leading one bit give 1217 bits
// of precision to handle the largest possible f64 exponent.
@static bd_pi4 := [?]u64{
0x0000000000000001,
0x45f306dc9c882a53,
0xf84eafa3ea69bb81,
0xb6c52b3278872083,
0xfca2c757bd778ac3,
0x6e48dc74849ba5c0,
0x0c925dd413a32439,
0xfc3bd63962534e7d,
0xd1046bea5d768909,
0xd338e04d68befc82,
0x7323ac7306a673e9,
0x3908bf177bf25076,
0x3ff12fffbc0b301f,
0xde5e2316b414da3e,
0xda6cfd9e4f96136e,
0x9e8c7ecd3cbfd45a,
0xea4f758fd7cbe2f6,
0x7a0e73ef14a525d4,
0xd7f6bf623f1aba10,
0xac06608df8f6d757,
}
PI4 :: PI / 4
if x < PI4 {
return 0, x
}
MASK :: 0x7FF
SHIFT :: 64 - 11 - 1
BIAS :: 1023
// Extract out the integer and exponent such that,
// x = ix * 2 ** exp.
ix := transmute(u64)x
exp := int(ix>>SHIFT&MASK) - BIAS - SHIFT
ix &~= MASK << SHIFT
ix |= 1 << SHIFT
// Use the exponent to extract the 3 appropriate u64 digits from bd_pi4,
// B ~ (z0, z1, z2), such that the product leading digit has the exponent -61.
// Note, exp >= -53 since x >= PI4 and exp < 971 for maximum f64.
digit, bitshift := uint(exp+61)/64, uint(exp+61)%64
z0 := (bd_pi4[digit] << bitshift) | (bd_pi4[digit+1] >> (64 - bitshift))
z1 := (bd_pi4[digit+1] << bitshift) | (bd_pi4[digit+2] >> (64 - bitshift))
z2 := (bd_pi4[digit+2] << bitshift) | (bd_pi4[digit+3] >> (64 - bitshift))
// Multiply mantissa by the digits and extract the upper two digits (hi, lo).
z2hi, _ := bits.mul(z2, ix)
z1hi, z1lo := bits.mul(z1, ix)
z0lo := z0 * ix
lo, c := bits.add(z1lo, z2hi, 0)
hi, _ := bits.add(z0lo, z1hi, c)
// The top 3 bits are j.
j = hi >> 61
// Extract the fraction and find its magnitude.
hi = hi<<3 | lo>>61
lz := uint(bits.leading_zeros(hi))
e := u64(BIAS - (lz + 1))
// Clear implicit mantissa bit and shift into place.
hi = (hi << (lz + 1)) | (lo >> (64 - (lz + 1)))
hi >>= 64 - SHIFT
// Include the exponent and convert to a float.
hi |= e << SHIFT
z = transmute(f64)hi
// Map zeros to origin.
if j&1 == 1 {
j += 1
j &= 7
z -= 1
}
// Multiply the fractional part by pi/4.
return j, z * PI4
}
+9
View File
@@ -20,6 +20,7 @@ Vec4 :: [4]f64
/*
2D Simplex noise, standard lattice orientation.
*/
@(require_results)
noise_2d :: proc(seed: i64, coord: Vec2) -> (value: f32) {
// Get points for A2* lattice
skew := SKEW_2D * (coord.x + coord.y)
@@ -35,6 +36,7 @@ noise_2d :: proc(seed: i64, coord: Vec2) -> (value: f32) {
unless your map is centered around an equator. It's a subtle
difference, but the option is here to make it an easy choice.
*/
@(require_results)
noise_2d_improve_x :: proc(seed: i64, coord: Vec2) -> (value: f32) {
// Skew transform and rotation baked into one.
xx := coord.x * ROOT_2_OVER_2
@@ -51,6 +53,7 @@ noise_2d_improve_x :: proc(seed: i64, coord: Vec2) -> (value: f32) {
If Z is vertical in world coordinates, call `noise_3d_improve_xz(x, y, Z)`.
For a time varied animation, call `noise_3d_improve_xz(x, y, T)`.
*/
@(require_results)
noise_3d_improve_xy :: proc(seed: i64, coord: Vec3) -> (value: f32) {
/*
Re-orient the cubic lattices without skewing, so Z points up the main lattice diagonal,
@@ -75,6 +78,7 @@ noise_3d_improve_xy :: proc(seed: i64, coord: Vec3) -> (value: f32) {
If Z is vertical in world coordinates, call `noise_3d_improve_xz(x, Z, y)` or use `noise_3d_improve_xy`.
For a time varied animation, call `noise_3d_improve_xz(x, T, y)` or use `noise_3d_improve_xy`.
*/
@(require_results)
noise_3d_improve_xz :: proc(seed: i64, coord: Vec3) -> (value: f32) {
/*
Re-orient the cubic lattices without skewing, so Y points up the main lattice diagonal,
@@ -96,6 +100,7 @@ noise_3d_improve_xz :: proc(seed: i64, coord: Vec3) -> (value: f32) {
Use `noise_3d_improve_xy` or `noise_3d_improve_xz` instead, wherever appropriate.
They have less diagonal bias. This function's best use is as a fallback.
*/
@(require_results)
noise_3d_fallback :: proc(seed: i64, coord: Vec3) -> (value: f32) {
/*
Re-orient the cubic lattices via rotation, to produce a familiar look.
@@ -114,6 +119,7 @@ noise_3d_fallback :: proc(seed: i64, coord: Vec3) -> (value: f32) {
Recommended for time-varied animations which texture a 3D object (W=time)
in a space where Z is vertical.
*/
@(require_results)
noise_4d_improve_xyz_improve_xy :: proc(seed: i64, coord: Vec4) -> (value: f32) {
xy := coord.x + coord.y
s2 := xy * -0.21132486540518699998
@@ -133,6 +139,7 @@ noise_4d_improve_xyz_improve_xy :: proc(seed: i64, coord: Vec4) -> (value: f32)
Recommended for time-varied animations which texture a 3D object (W=time)
in a space where Y is vertical.
*/
@(require_results)
noise_4d_improve_xyz_improve_xz :: proc(seed: i64, coord: Vec4) -> (value: f32) {
xz := coord.x + coord.z
s2 := xz * -0.21132486540518699998
@@ -152,6 +159,7 @@ noise_4d_improve_xyz_improve_xz :: proc(seed: i64, coord: Vec4) -> (value: f32)
Recommended for time-varied animations which texture a 3D object (W=time)
where there isn't a clear distinction between horizontal and vertical
*/
@(require_results)
noise_4d_improve_xyz :: proc(seed: i64, coord: Vec4) -> (value: f32) {
xyz := coord.x + coord.y + coord.z
ww := coord.w * 0.2236067977499788
@@ -164,6 +172,7 @@ noise_4d_improve_xyz :: proc(seed: i64, coord: Vec4) -> (value: f32) {
/*
4D OpenSimplex2 noise, fallback lattice orientation.
*/
@(require_results)
noise_4d_fallback :: proc(seed: i64, coord: Vec4) -> (value: f32) {
// Get points for A4 lattice
skew := f64(SKEW_4D) * (coord.x + coord.y + coord.z + coord.w)
+26
View File
@@ -7,6 +7,7 @@ float32_uniform :: float32_range
// Triangular Distribution
// See: http://wikipedia.org/wiki/Triangular_distribution
@(require_results)
float64_triangular :: proc(lo, hi: f64, mode: Maybe(f64), r: ^Rand = nil) -> f64 {
if hi-lo == 0 {
return lo
@@ -24,6 +25,7 @@ float64_triangular :: proc(lo, hi: f64, mode: Maybe(f64), r: ^Rand = nil) -> f64
}
// Triangular Distribution
// See: http://wikipedia.org/wiki/Triangular_distribution
@(require_results)
float32_triangular :: proc(lo, hi: f32, mode: Maybe(f32), r: ^Rand = nil) -> f32 {
if hi-lo == 0 {
return lo
@@ -41,20 +43,24 @@ float32_triangular :: proc(lo, hi: f32, mode: Maybe(f32), r: ^Rand = nil) -> f32
// Normal/Gaussian Distribution
@(require_results)
float64_normal :: proc(mean, stddev: f64, r: ^Rand = nil) -> f64 {
return norm_float64(r) * stddev + mean
}
// Normal/Gaussian Distribution
@(require_results)
float32_normal :: proc(mean, stddev: f32, r: ^Rand = nil) -> f32 {
return f32(float64_normal(f64(mean), f64(stddev), r))
}
// Log Normal Distribution
@(require_results)
float64_log_normal :: proc(mean, stddev: f64, r: ^Rand = nil) -> f64 {
return math.exp(float64_normal(mean, stddev, r))
}
// Log Normal Distribution
@(require_results)
float32_log_normal :: proc(mean, stddev: f32, r: ^Rand = nil) -> f32 {
return f32(float64_log_normal(f64(mean), f64(stddev), r))
}
@@ -65,6 +71,7 @@ float32_log_normal :: proc(mean, stddev: f32, r: ^Rand = nil) -> f32 {
// Return values range from
// 0 to positive infinity if lambda > 0
// negative infinity to 0 if lambda <= 0
@(require_results)
float64_exponential :: proc(lambda: f64, r: ^Rand = nil) -> f64 {
return - math.ln(1 - float64(r)) / lambda
}
@@ -73,6 +80,7 @@ float64_exponential :: proc(lambda: f64, r: ^Rand = nil) -> f64 {
// Return values range from
// 0 to positive infinity if lambda > 0
// negative infinity to 0 if lambda <= 0
@(require_results)
float32_exponential :: proc(lambda: f32, r: ^Rand = nil) -> f32 {
return f32(float64_exponential(f64(lambda), r))
}
@@ -87,6 +95,7 @@ float32_exponential :: proc(lambda: f32, r: ^Rand = nil) -> f32 {
// math.gamma(alpha) * math.pow(beta, alpha)
//
// mean is alpha*beta, variance is math.pow(alpha*beta, 2)
@(require_results)
float64_gamma :: proc(alpha, beta: f64, r: ^Rand = nil) -> f64 {
if alpha <= 0 || beta <= 0 {
panic(#procedure + ": alpha and beta must be > 0.0")
@@ -152,6 +161,7 @@ float64_gamma :: proc(alpha, beta: f64, r: ^Rand = nil) -> f64 {
// math.gamma(alpha) * math.pow(beta, alpha)
//
// mean is alpha*beta, variance is math.pow(alpha*beta, 2)
@(require_results)
float32_gamma :: proc(alpha, beta: f32, r: ^Rand = nil) -> f32 {
return f32(float64_gamma(f64(alpha), f64(beta), r))
}
@@ -162,6 +172,7 @@ float32_gamma :: proc(alpha, beta: f32, r: ^Rand = nil) -> f32 {
// Required: alpha > 0 and beta > 0
//
// Return values range between 0 and 1
@(require_results)
float64_beta :: proc(alpha, beta: f64, r: ^Rand = nil) -> f64 {
if alpha <= 0 || beta <= 0 {
panic(#procedure + ": alpha and beta must be > 0.0")
@@ -178,6 +189,7 @@ float64_beta :: proc(alpha, beta: f64, r: ^Rand = nil) -> f64 {
// Required: alpha > 0 and beta > 0
//
// Return values range between 0 and 1
@(require_results)
float32_beta :: proc(alpha, beta: f32, r: ^Rand = nil) -> f32 {
return f32(float64_beta(f64(alpha), f64(beta), r))
}
@@ -185,22 +197,26 @@ float32_beta :: proc(alpha, beta: f32, r: ^Rand = nil) -> f32 {
// Pareto distribution, `alpha` is the shape parameter.
// https://wikipedia.org/wiki/Pareto_distribution
@(require_results)
float64_pareto :: proc(alpha: f64, r: ^Rand = nil) -> f64 {
return math.pow(1 - float64(r), -1.0 / alpha)
}
// Pareto distribution, `alpha` is the shape parameter.
// https://wikipedia.org/wiki/Pareto_distribution
@(require_results)
float32_pareto :: proc(alpha, beta: f32, r: ^Rand = nil) -> f32 {
return f32(float64_pareto(f64(alpha), r))
}
// Weibull distribution, `alpha` is the scale parameter, `beta` is the shape parameter.
@(require_results)
float64_weibull :: proc(alpha, beta: f64, r: ^Rand = nil) -> f64 {
u := 1 - float64(r)
return alpha * math.pow(-math.ln(u), 1.0/beta)
}
// Weibull distribution, `alpha` is the scale parameter, `beta` is the shape parameter.
@(require_results)
float32_weibull :: proc(alpha, beta: f32, r: ^Rand = nil) -> f32 {
return f32(float64_weibull(f64(alpha), f64(beta), r))
}
@@ -210,6 +226,7 @@ float32_weibull :: proc(alpha, beta: f32, r: ^Rand = nil) -> f32 {
// `mean_angle` is the in mean angle between 0 and 2pi radians
// `kappa` is the concentration parameter which must be >= 0
// When `kappa` is zero, the Distribution is a uniform Distribution over the range 0 to 2pi
@(require_results)
float64_von_mises :: proc(mean_angle, kappa: f64, r: ^Rand = nil) -> f64 {
// Fisher, N.I., "Statistical Analysis of Circular Data", Cambridge University Press, 1993.
@@ -245,6 +262,7 @@ float64_von_mises :: proc(mean_angle, kappa: f64, r: ^Rand = nil) -> f64 {
// `mean_angle` is the in mean angle between 0 and 2pi radians
// `kappa` is the concentration parameter which must be >= 0
// When `kappa` is zero, the Distribution is a uniform Distribution over the range 0 to 2pi
@(require_results)
float32_von_mises :: proc(mean_angle, kappa: f32, r: ^Rand = nil) -> f32 {
return f32(float64_von_mises(f64(mean_angle), f64(kappa), r))
}
@@ -252,6 +270,7 @@ float32_von_mises :: proc(mean_angle, kappa: f32, r: ^Rand = nil) -> f32 {
// Cauchy-Lorentz Distribution
// `x_0` is the location, `gamma` is the scale where `gamma` > 0
@(require_results)
float64_cauchy_lorentz :: proc(x_0, gamma: f64, r: ^Rand = nil) -> f64 {
assert(gamma > 0)
@@ -261,6 +280,7 @@ float64_cauchy_lorentz :: proc(x_0, gamma: f64, r: ^Rand = nil) -> f64 {
}
// Cauchy-Lorentz Distribution
// `x_0` is the location, `gamma` is the scale where `gamma` > 0
@(require_results)
float32_cauchy_lorentz :: proc(x_0, gamma: f32, r: ^Rand = nil) -> f32 {
return f32(float64_cauchy_lorentz(f64(x_0), f64(gamma), r))
}
@@ -268,12 +288,14 @@ float32_cauchy_lorentz :: proc(x_0, gamma: f32, r: ^Rand = nil) -> f32 {
// Log Cauchy-Lorentz Distribution
// `x_0` is the location, `gamma` is the scale where `gamma` > 0
@(require_results)
float64_log_cauchy_lorentz :: proc(x_0, gamma: f64, r: ^Rand = nil) -> f64 {
assert(gamma > 0)
return math.exp(math.tan(math.PI * (float64(r) - 0.5))*gamma + x_0)
}
// Log Cauchy-Lorentz Distribution
// `x_0` is the location, `gamma` is the scale where `gamma` > 0
@(require_results)
float32_log_cauchy_lorentz :: proc(x_0, gamma: f32, r: ^Rand = nil) -> f32 {
return f32(float64_log_cauchy_lorentz(f64(x_0), f64(gamma), r))
}
@@ -281,6 +303,7 @@ float32_log_cauchy_lorentz :: proc(x_0, gamma: f32, r: ^Rand = nil) -> f32 {
// Laplace Distribution
// `b` is the scale where `b` > 0
@(require_results)
float64_laplace :: proc(mean, b: f64, r: ^Rand = nil) -> f64 {
assert(b > 0)
p := float64(r)-0.5
@@ -288,6 +311,7 @@ float64_laplace :: proc(mean, b: f64, r: ^Rand = nil) -> f64 {
}
// Laplace Distribution
// `b` is the scale where `b` > 0
@(require_results)
float32_laplace :: proc(mean, b: f32, r: ^Rand = nil) -> f32 {
return f32(float64_laplace(f64(mean), f64(b), r))
}
@@ -296,6 +320,7 @@ float32_laplace :: proc(mean, b: f32, r: ^Rand = nil) -> f32 {
// Gompertz Distribution
// `eta` is the shape, `b` is the scale
// Both `eta` and `b` must be > 0
@(require_results)
float64_gompertz :: proc(eta, b: f64, r: ^Rand = nil) -> f64 {
if eta <= 0 || b <= 0 {
panic(#procedure + ": eta and b must be > 0.0")
@@ -307,6 +332,7 @@ float64_gompertz :: proc(eta, b: f64, r: ^Rand = nil) -> f64 {
// Gompertz Distribution
// `eta` is the shape, `b` is the scale
// Both `eta` and `b` must be > 0
@(require_results)
float32_gompertz :: proc(eta, b: f32, r: ^Rand = nil) -> f32 {
return f32(float64_gompertz(f64(eta), f64(b), r))
}
+1
View File
@@ -15,6 +15,7 @@ import "core:math"
// https://www.jstatsoft.org/index.php/jss/article/view/v005i08/ziggurat.pdf [pdf]
// https://www.jstatsoft.org/article/view/v005i08 [web page]
//
@(require_results)
exp_float64 :: proc(r: ^Rand = nil) -> f64 {
re :: 7.69711747013104972

Some files were not shown because too many files have changed in this diff Show More