1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

tools: make v test-cleancode test everything by default (#10050)

This commit is contained in:
Delyan Angelov 2021-05-08 13:32:29 +03:00 committed by GitHub
parent cba2cb6b9c
commit 8a380f4699
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
132 changed files with 3230 additions and 3440 deletions

View File

@ -50,7 +50,7 @@ jobs:
run: | run: |
sudo apt update sudo apt update
sudo apt-get install --quiet -y libssl-dev sqlite3 libsqlite3-dev valgrind sudo apt-get install --quiet -y libssl-dev sqlite3 libsqlite3-dev valgrind
sudo apt-get install --quiet -y libfreetype6-dev libxi-dev libxcursor-dev libasound2-dev libgl-dev sudo apt-get install --quiet -y libfreetype6-dev libxi-dev libxcursor-dev libgl-dev
## The following is needed for examples/wkhtmltopdf.v ## The following is needed for examples/wkhtmltopdf.v
wget https://github.com/wkhtmltopdf/packaging/releases/download/0.12.6-1/wkhtmltox_0.12.6-1.focal_amd64.deb wget https://github.com/wkhtmltopdf/packaging/releases/download/0.12.6-1/wkhtmltox_0.12.6-1.focal_amd64.deb
sudo apt-get install xfonts-75dpi xfonts-base sudo apt-get install xfonts-75dpi xfonts-base
@ -112,7 +112,7 @@ jobs:
run: | run: |
sudo apt update sudo apt update
sudo apt-get install --quiet -y libssl-dev sqlite3 libsqlite3-dev valgrind sudo apt-get install --quiet -y libssl-dev sqlite3 libsqlite3-dev valgrind
sudo apt-get install --quiet -y libfreetype6-dev libxi-dev libxcursor-dev libasound2-dev libgl-dev sudo apt-get install --quiet -y libfreetype6-dev libxi-dev libxcursor-dev libgl-dev
sudo apt-get install --quiet -y libgc-dev sudo apt-get install --quiet -y libgc-dev
## The following is needed for examples/wkhtmltopdf.v ## The following is needed for examples/wkhtmltopdf.v
wget https://github.com/wkhtmltopdf/packaging/releases/download/0.12.6-1/wkhtmltox_0.12.6-1.focal_amd64.deb wget https://github.com/wkhtmltopdf/packaging/releases/download/0.12.6-1/wkhtmltox_0.12.6-1.focal_amd64.deb
@ -168,7 +168,7 @@ jobs:
run: | run: |
sudo apt update sudo apt update
sudo apt-get install --quiet -y libssl-dev sqlite3 libsqlite3-dev valgrind sudo apt-get install --quiet -y libssl-dev sqlite3 libsqlite3-dev valgrind
sudo apt-get install --quiet -y libfreetype6-dev libxi-dev libxcursor-dev libasound2-dev libgl-dev sudo apt-get install --quiet -y libfreetype6-dev libxi-dev libxcursor-dev libgl-dev
sudo apt-get install --quiet -y xfonts-75dpi xfonts-base sudo apt-get install --quiet -y xfonts-75dpi xfonts-base
- name: Build v - name: Build v
run: make run: make
@ -213,7 +213,7 @@ jobs:
- name: Install C++ dependencies - name: Install C++ dependencies
run: | run: |
sudo apt-get install --quiet -y postgresql libpq-dev libssl-dev sqlite3 libsqlite3-dev sudo apt-get install --quiet -y postgresql libpq-dev libssl-dev sqlite3 libsqlite3-dev
sudo apt-get install --quiet -y libfreetype6-dev libxi-dev libxcursor-dev libasound2-dev libgl-dev sudo apt-get install --quiet -y libfreetype6-dev libxi-dev libxcursor-dev libgl-dev
sudo apt-get install --quiet -y valgrind g++-9 sudo apt-get install --quiet -y valgrind g++-9
- name: Build V - name: Build V
run: make -j4 run: make -j4
@ -341,7 +341,7 @@ jobs:
run: | run: |
sudo apt update sudo apt update
sudo apt-get install --quiet -y postgresql libpq-dev libssl-dev sqlite3 libsqlite3-dev valgrind sudo apt-get install --quiet -y postgresql libpq-dev libssl-dev sqlite3 libsqlite3-dev valgrind
sudo apt-get install --quiet -y libfreetype6-dev libxi-dev libxcursor-dev libasound2-dev libgl-dev sudo apt-get install --quiet -y libfreetype6-dev libxi-dev libxcursor-dev libgl-dev
- name: Build V - name: Build V
run: make -j4 && ./v -cc gcc -cg -cstrict -o v cmd/v run: make -j4 && ./v -cc gcc -cg -cstrict -o v cmd/v
- name: Valgrind v.c - name: Valgrind v.c
@ -436,7 +436,7 @@ jobs:
run: | run: |
sudo apt update sudo apt update
sudo apt-get install --quiet -y postgresql libpq-dev libssl-dev sqlite3 libsqlite3-dev valgrind sudo apt-get install --quiet -y postgresql libpq-dev libssl-dev sqlite3 libsqlite3-dev valgrind
sudo apt-get install --quiet -y libfreetype6-dev libxi-dev libxcursor-dev libasound2-dev libgl-dev sudo apt-get install --quiet -y libfreetype6-dev libxi-dev libxcursor-dev libgl-dev
sudo apt-get install clang sudo apt-get install clang
- name: Build V - name: Build V
run: make -j4 && ./v -cc clang -cg -cstrict -o v cmd/v run: make -j4 && ./v -cc clang -cg -cstrict -o v cmd/v

View File

@ -25,7 +25,7 @@ jobs:
run: | run: |
sudo apt update sudo apt update
sudo apt-get install --quiet -y postgresql libpq-dev libssl-dev sqlite3 libsqlite3-dev valgrind sudo apt-get install --quiet -y postgresql libpq-dev libssl-dev sqlite3 libsqlite3-dev valgrind
sudo apt-get install --quiet -y libfreetype6-dev libxi-dev libxcursor-dev libasound2-dev libgl-dev sudo apt-get install --quiet -y libfreetype6-dev libxi-dev libxcursor-dev libgl-dev
sudo apt-get install clang sudo apt-get install clang
- name: Build V - name: Build V
run: make -j4 && ./v -cg -cstrict -o v cmd/v run: make -j4 && ./v -cg -cstrict -o v cmd/v
@ -50,7 +50,7 @@ jobs:
run: | run: |
sudo apt update sudo apt update
sudo apt-get install --quiet -y postgresql libpq-dev libssl-dev sqlite3 libsqlite3-dev valgrind sudo apt-get install --quiet -y postgresql libpq-dev libssl-dev sqlite3 libsqlite3-dev valgrind
sudo apt-get install --quiet -y libfreetype6-dev libxi-dev libxcursor-dev libasound2-dev libgl-dev sudo apt-get install --quiet -y libfreetype6-dev libxi-dev libxcursor-dev libgl-dev
- name: Build V - name: Build V
run: make -j4 && ./v -cg -cstrict -o v cmd/v run: make -j4 && ./v -cg -cstrict -o v cmd/v
- name: Self tests (-fsanitize=undefined) - name: Self tests (-fsanitize=undefined)
@ -74,7 +74,7 @@ jobs:
run: | run: |
sudo apt update sudo apt update
sudo apt-get install --quiet -y postgresql libpq-dev libssl-dev sqlite3 libsqlite3-dev valgrind sudo apt-get install --quiet -y postgresql libpq-dev libssl-dev sqlite3 libsqlite3-dev valgrind
sudo apt-get install --quiet -y libfreetype6-dev libxi-dev libxcursor-dev libasound2-dev libgl-dev sudo apt-get install --quiet -y libfreetype6-dev libxi-dev libxcursor-dev libgl-dev
sudo apt-get install clang sudo apt-get install clang
- name: Build V - name: Build V
run: make -j4 && ./v -cg -cstrict -o v cmd/v run: make -j4 && ./v -cg -cstrict -o v cmd/v
@ -129,7 +129,7 @@ jobs:
run: | run: |
sudo apt update sudo apt update
sudo apt-get install --quiet -y postgresql libpq-dev libssl-dev sqlite3 libsqlite3-dev valgrind sudo apt-get install --quiet -y postgresql libpq-dev libssl-dev sqlite3 libsqlite3-dev valgrind
sudo apt-get install --quiet -y libfreetype6-dev libxi-dev libxcursor-dev libasound2-dev libgl-dev sudo apt-get install --quiet -y libfreetype6-dev libxi-dev libxcursor-dev libgl-dev
sudo apt-get install clang sudo apt-get install clang
- name: Build V - name: Build V
run: make -j4 && ./v -cg -cstrict -o v cmd/v run: make -j4 && ./v -cg -cstrict -o v cmd/v
@ -158,7 +158,7 @@ jobs:
run: | run: |
sudo apt update sudo apt update
sudo apt-get install --quiet -y postgresql libpq-dev libssl-dev sqlite3 libsqlite3-dev valgrind sudo apt-get install --quiet -y postgresql libpq-dev libssl-dev sqlite3 libsqlite3-dev valgrind
sudo apt-get install --quiet -y libfreetype6-dev libxi-dev libxcursor-dev libasound2-dev libgl-dev sudo apt-get install --quiet -y libfreetype6-dev libxi-dev libxcursor-dev libgl-dev
sudo apt-get install clang sudo apt-get install clang
- name: Build V - name: Build V
run: make -j4 && ./v -cc clang -cg -cstrict -o v cmd/v run: make -j4 && ./v -cc clang -cg -cstrict -o v cmd/v

View File

@ -12,6 +12,10 @@ const github_job = os.getenv('GITHUB_JOB')
const show_start = os.getenv('VTEST_SHOW_START') == '1' const show_start = os.getenv('VTEST_SHOW_START') == '1'
const hide_skips = os.getenv('VTEST_HIDE_SKIP') == '1'
const hide_oks = os.getenv('VTEST_HIDE_OK') == '1'
pub struct TestSession { pub struct TestSession {
pub mut: pub mut:
files []string files []string
@ -108,43 +112,50 @@ pub fn (mut ts TestSession) print_messages() {
} }
} }
pub fn new_test_session(_vargs string) TestSession { pub fn new_test_session(_vargs string, will_compile bool) TestSession {
mut skip_files := []string{} mut skip_files := []string{}
$if solaris { if will_compile {
skip_files << 'examples/gg/gg2.v' $if solaris {
skip_files << 'examples/pico/pico.v' skip_files << 'examples/gg/gg2.v'
skip_files << 'examples/sokol/fonts.v' skip_files << 'examples/pico/pico.v'
skip_files << 'examples/sokol/drawing.v' skip_files << 'examples/sokol/fonts.v'
} skip_files << 'examples/sokol/drawing.v'
$if macos { }
skip_files << 'examples/database/mysql.v' $if macos {
skip_files << 'examples/database/orm.v' skip_files << 'examples/database/mysql.v'
skip_files << 'examples/database/pg/customer.v' skip_files << 'examples/database/orm.v'
} skip_files << 'examples/database/pg/customer.v'
$if windows { }
skip_files << 'examples/database/mysql.v' $if windows {
skip_files << 'examples/database/orm.v' skip_files << 'examples/database/mysql.v'
skip_files << 'examples/websocket/ping.v' // requires OpenSSL skip_files << 'examples/database/orm.v'
skip_files << 'examples/websocket/client-server/client.v' // requires OpenSSL skip_files << 'examples/websocket/ping.v' // requires OpenSSL
skip_files << 'examples/websocket/client-server/server.v' // requires OpenSSL skip_files << 'examples/websocket/client-server/client.v' // requires OpenSSL
$if tinyc { skip_files << 'examples/websocket/client-server/server.v' // requires OpenSSL
skip_files << 'examples/database/orm.v' // try fix it $if tinyc {
skip_files << 'examples/database/orm.v' // try fix it
}
}
if testing.github_job != 'sokol-shaders-can-be-compiled' {
// These examples need .h files that are produced from the supplied .glsl files,
// using by the shader compiler tools in https://github.com/floooh/sokol-tools-bin/archive/pre-feb2021-api-changes.tar.gz
skip_files << 'examples/sokol/02_cubes_glsl/cube_glsl.v'
skip_files << 'examples/sokol/03_march_tracing_glsl/rt_glsl.v'
skip_files << 'examples/sokol/04_multi_shader_glsl/rt_glsl.v'
skip_files << 'examples/sokol/05_instancing_glsl/rt_glsl.v'
// Skip obj_viewer code in the CI
skip_files << 'examples/sokol/06_obj_viewer/show_obj.v'
}
if testing.github_job != 'ubuntu-tcc' {
skip_files << 'examples/c_interop_wkhtmltopdf.v' // needs installation of wkhtmltopdf from https://github.com/wkhtmltopdf/packaging/releases
// the ttf_test.v is not interactive, but needs X11 headers to be installed, which is done only on ubuntu-tcc for now
skip_files << 'vlib/x/ttf/ttf_test.v'
}
if testing.github_job != 'audio-examples' {
skip_files << 'examples/sokol/sounds/melody.v'
skip_files << 'examples/sokol/sounds/wav_player.v'
skip_files << 'examples/sokol/sounds/simple_sin_tones.v'
} }
}
if testing.github_job != 'sokol-shaders-can-be-compiled' {
// These examples need .h files that are produced from the supplied .glsl files,
// using by the shader compiler tools in https://github.com/floooh/sokol-tools-bin/archive/pre-feb2021-api-changes.tar.gz
skip_files << 'examples/sokol/02_cubes_glsl/cube_glsl.v'
skip_files << 'examples/sokol/03_march_tracing_glsl/rt_glsl.v'
skip_files << 'examples/sokol/04_multi_shader_glsl/rt_glsl.v'
skip_files << 'examples/sokol/05_instancing_glsl/rt_glsl.v'
// Skip obj_viewer code in the CI
skip_files << 'examples/sokol/06_obj_viewer/show_obj.v'
}
if testing.github_job != 'ubuntu-tcc' {
skip_files << 'examples/c_interop_wkhtmltopdf.v' // needs installation of wkhtmltopdf from https://github.com/wkhtmltopdf/packaging/releases
// the ttf_test.v is not interactive, but needs X11 headers to be installed, which is done only on ubuntu-tcc for now
skip_files << 'vlib/x/ttf/ttf_test.v'
} }
vargs := _vargs.replace('-progress', '').replace('-progress', '') vargs := _vargs.replace('-progress', '').replace('-progress', '')
vexe := pref.vexe_path() vexe := pref.vexe_path()
@ -268,7 +279,9 @@ fn worker_trunner(mut p pool.PoolProcessor, idx int, thread_id int) voidptr {
if relative_file.replace('\\', '/') in ts.skip_files { if relative_file.replace('\\', '/') in ts.skip_files {
ts.benchmark.skip() ts.benchmark.skip()
tls_bench.skip() tls_bench.skip()
ts.append_message(.skip, tls_bench.step_message_skip(relative_file)) if !testing.hide_skips {
ts.append_message(.skip, tls_bench.step_message_skip(relative_file))
}
return pool.no_result return pool.no_result
} }
if show_stats { if show_stats {
@ -304,7 +317,9 @@ fn worker_trunner(mut p pool.PoolProcessor, idx int, thread_id int) voidptr {
} else { } else {
ts.benchmark.ok() ts.benchmark.ok()
tls_bench.ok() tls_bench.ok()
ts.append_message(.ok, tls_bench.step_message_ok(relative_file)) if !testing.hide_oks {
ts.append_message(.ok, tls_bench.step_message_ok(relative_file))
}
} }
} }
if os.exists(generated_binary_fpath) { if os.exists(generated_binary_fpath) {
@ -336,7 +351,7 @@ pub fn prepare_test_session(zargs string, folder string, oskipped []string, main
if vargs.len > 0 { if vargs.len > 0 {
eprintln('v compiler args: "$vargs"') eprintln('v compiler args: "$vargs"')
} }
mut session := new_test_session(vargs) mut session := new_test_session(vargs, true)
files := os.walk_ext(os.join_path(parent_dir, folder), '.v') files := os.walk_ext(os.join_path(parent_dir, folder), '.v')
mut mains := []string{} mut mains := []string{}
mut skipped := oskipped.clone() mut skipped := oskipped.clone()
@ -414,7 +429,9 @@ pub fn building_any_v_binaries_failed() bool {
continue continue
} }
bmark.ok() bmark.ok()
eprintln(bmark.step_message_ok('command: $cmd')) if !testing.hide_oks {
eprintln(bmark.step_message_ok('command: $cmd'))
}
} }
bmark.stop() bmark.stop()
eprintln(term.h_divider('-')) eprintln(term.h_divider('-'))

View File

@ -3,6 +3,7 @@ module main
import os import os
import testing import testing
import v.util import v.util
import arrays
const ( const (
vet_known_failing_exceptions = []string{} vet_known_failing_exceptions = []string{}
@ -31,70 +32,31 @@ const (
'vlib/builtin/int.v' /* TODO byteptr: vfmt converts `pub fn (nn byteptr) str() string {` to `nn &byte` and that conflicts with `nn byte` */, 'vlib/builtin/int.v' /* TODO byteptr: vfmt converts `pub fn (nn byteptr) str() string {` to `nn &byte` and that conflicts with `nn byte` */,
'vlib/builtin/string_charptr_byteptr_helpers.v' /* TODO byteptr: a temporary shim to ease the byteptr=>&byte transition */, 'vlib/builtin/string_charptr_byteptr_helpers.v' /* TODO byteptr: a temporary shim to ease the byteptr=>&byte transition */,
'vlib/v/tests/fn_high_test.v', /* param name removed */ 'vlib/v/tests/fn_high_test.v', /* param name removed */
'vlib/v/tests/fn_test.v', /* bad comment formatting */
'vlib/v/tests/generics_return_generics_struct_test.v', /* generic fn param removed */ 'vlib/v/tests/generics_return_generics_struct_test.v', /* generic fn param removed */
'vlib/v/tests/interop_test.v', /* bad comment formatting */ 'vlib/v/tests/interop_test.v', /* bad comment formatting */
'vlib/v/tests/generics_test.v', /* multi_generic_args<Foo<int>, Foo<int> >(...) becomes .... Foo<int>>(...) which does not parse */ 'vlib/v/tests/generics_test.v', /* multi_generic_args<Foo<int>, Foo<int> >(...) becomes .... Foo<int>>(...) which does not parse */
'vlib/v/tests/string_interpolation_test.v' /* TODO byteptr: &byte.str() behaves differently than byteptr.str() */, 'vlib/v/tests/string_interpolation_test.v' /* TODO byteptr: &byte.str() behaves differently than byteptr.str() */,
'vlib/v/gen/js/tests/js.v', /* local `hello` fn, gets replaced with module `hello` aliased as `hl` */ 'vlib/v/gen/js/tests/js.v', /* local `hello` fn, gets replaced with module `hello` aliased as `hl` */
'examples/c_interop_wkhtmltopdf.v', /* &charptr --> &&char */ 'examples/c_interop_wkhtmltopdf.v' /* &charptr --> &&char */,
'vlib/v/gen/c/cheaders.v' /* infix wrapping error */,
] ]
vfmt_verify_list = [ vfmt_verify_list = [
'cmd/', 'cmd/',
'examples/', 'examples/',
'tutorials/', 'tutorials/',
'vlib/arrays/', 'vlib/',
'vlib/benchmark/',
'vlib/bitfield/',
'vlib/builtin/',
'vlib/cli/',
'vlib/dl/',
'vlib/encoding/utf8/',
'vlib/flag/',
'vlib/gg/',
'vlib/math/bits/bits.v',
'vlib/orm/',
'vlib/runtime/',
'vlib/term/colors.v',
'vlib/term/term.v',
'vlib/v/ast/',
'vlib/v/builder/',
'vlib/v/cflag/',
'vlib/v/checker/',
'vlib/v/depgraph/',
'vlib/v/doc/',
'vlib/v/embed_file/',
'vlib/v/errors/',
'vlib/v/eval/',
'vlib/v/fmt/',
'vlib/v/gen/c/',
'vlib/v/gen/js/',
'vlib/v/gen/native/',
'vlib/v/live/',
'vlib/v/markused/',
'vlib/v/parser/',
'vlib/v/pkgconfig/',
'vlib/v/pref/',
'vlib/v/preludes',
'vlib/v/scanner/',
'vlib/v/tests/',
'vlib/v/token/',
'vlib/v/util/',
'vlib/v/vcache/',
'vlib/v/vet/',
'vlib/v/vmod/',
'vlib/cli/',
'vlib/flag/',
'vlib/math/big/',
'vlib/os/',
'vlib/semver/',
'vlib/strings/',
'vlib/time/',
'vlib/vweb/',
'vlib/x/json2',
'vlib/x/websocket/',
] ]
vfmt_known_failing_exceptions = arrays.merge(verify_known_failing_exceptions, [
'vlib/strconv/' /* prevent conflicts, till the new pure V string interpolation is merged */,
'vlib/net/' /* prevent conflicts, till ipv6 support is merged */,
'vlib/math/math_test.v', /* prevent conflict, till the sign PR is merged */
'vlib/term/ui/input.v' /* comment after a struct embed is removed */,
'vlib/regex/regex_test.v' /* contains meaningfull formatting of the test case data */,
'vlib/readline/readline_test.v' /* vfmt eats `{ Readline }` from `import readline { Readline }` */,
'vlib/glm/glm.v' /* `mut res &f32` => `mut res f32`, which then fails to compile */,
'vlib/fontstash/fontstash_structs.v' /* eats fn arg names for inline callback types in struct field declarations */,
'vlib/crypto/sha512/sha512block_generic.v' /* formatting of large constant arrays wraps to too many lines */,
'vlib/crypto/aes/const.v' /* formatting of large constant arrays wraps to too many lines */,
])
) )
const ( const (
@ -113,7 +75,7 @@ fn tsession(vargs string, tool_source string, tool_cmd string, tool_args string,
os.chdir(vroot) os.chdir(vroot)
title_message := 'running $tool_cmd over most .v files' title_message := 'running $tool_cmd over most .v files'
testing.eheader(title_message) testing.eheader(title_message)
mut test_session := testing.new_test_session('$vargs $tool_args') mut test_session := testing.new_test_session('$vargs $tool_args', false)
test_session.files << flist test_session.files << flist
test_session.skip_files << slist test_session.skip_files << slist
util.prepare_tool_when_needed(tool_source) util.prepare_tool_when_needed(tool_source)
@ -128,10 +90,11 @@ fn tsession(vargs string, tool_source string, tool_cmd string, tool_args string,
fn v_test_vetting(vargs string) { fn v_test_vetting(vargs string) {
expanded_vet_list := util.find_all_v_files(vet_folders) or { return } expanded_vet_list := util.find_all_v_files(vet_folders) or { return }
vet_session := tsession(vargs, 'vvet', 'v vet', 'vet', expanded_vet_list, vet_known_failing_exceptions) vet_session := tsession(vargs, 'vvet', 'v vet', 'vet', expanded_vet_list, vet_known_failing_exceptions)
//
fmt_cmd, fmt_args := if is_fix { 'v fmt -w', 'fmt -w' } else { 'v fmt -verify', 'fmt -verify' } fmt_cmd, fmt_args := if is_fix { 'v fmt -w', 'fmt -w' } else { 'v fmt -verify', 'fmt -verify' }
expanded_vfmt_list := util.find_all_v_files(vfmt_verify_list) or { return } vfmt_list := util.find_all_v_files(vfmt_verify_list) or { return }
verify_session := tsession(vargs, 'vfmt.v', fmt_cmd, fmt_args, expanded_vfmt_list, exceptions := util.find_all_v_files(vfmt_known_failing_exceptions) or { return }
verify_known_failing_exceptions) verify_session := tsession(vargs, 'vfmt.v', fmt_cmd, fmt_args, vfmt_list, exceptions)
// //
if vet_session.benchmark.nfail > 0 || verify_session.benchmark.nfail > 0 { if vet_session.benchmark.nfail > 0 || verify_session.benchmark.nfail > 0 {
eprintln('\n') eprintln('\n')

View File

@ -6,21 +6,7 @@ import v.util
const ( const (
known_failing_exceptions = [ known_failing_exceptions = [
'vlib/crypto/aes/const.v', 'vlib/crypto/aes/const.v' /* const array wrapped in too many lines */,
// multiple narrow columns of []string turned to 1 long single column, otherwise works
'vlib/v/gen/js/tests/life.v',
// error: unexpected `,`, expecting ), on JS.setInterval(fn () { show(game) game = step(game) }, 500)
'vlib/builtin/js/builtin.v',
// JS.console.error(s) => JS.error(s), JS.process.exit(c) => JS.exit(c)
'vlib/builtin/js/jsfns_node.js.v',
'vlib/builtin/js/jsfns.js.v',
'vlib/builtin/js/jsfns_browser.js.v',
// total chaos (duplicated code several times) in array_eq_test.v
'vlib/builtin/array_eq_test.v',
// the fn args are removed, then `cb fn (picohttpparser.Request, mut picohttpparser.Response)` can not be reparsed
'vlib/picoev/picoev.v',
// the preprocessor directives are formated to the V standard, even though they are in a string literal
'vlib/v/gen/c/cheaders.v',
] ]
) )
@ -33,7 +19,7 @@ fn v_test_formatting(vargs string) {
all_v_files := v_files() all_v_files := v_files()
util.prepare_tool_when_needed('vfmt.v') util.prepare_tool_when_needed('vfmt.v')
testing.eheader('Run "v fmt" over all .v files') testing.eheader('Run "v fmt" over all .v files')
mut vfmt_test_session := testing.new_test_session('$vargs fmt -worker') mut vfmt_test_session := testing.new_test_session('$vargs fmt -worker', false)
vfmt_test_session.files << all_v_files vfmt_test_session.files << all_v_files
vfmt_test_session.skip_files << known_failing_exceptions vfmt_test_session.skip_files << known_failing_exceptions
vfmt_test_session.test() vfmt_test_session.test()

View File

@ -105,7 +105,7 @@ fn main() {
title := 'testing vlib' title := 'testing vlib'
all_test_files := os.walk_ext(os.join_path(vroot, 'vlib'), '_test.v') all_test_files := os.walk_ext(os.join_path(vroot, 'vlib'), '_test.v')
testing.eheader(title) testing.eheader(title)
mut tsession := testing.new_test_session(cmd_prefix) mut tsession := testing.new_test_session(cmd_prefix, true)
tsession.files << all_test_files tsession.files << all_test_files
tsession.skip_files << skip_test_files tsession.skip_files << skip_test_files
mut werror := false mut werror := false

View File

@ -22,7 +22,7 @@ fn main() {
backend_pos := args_before.index('-b') backend_pos := args_before.index('-b')
backend := if backend_pos == -1 { '.c' } else { args_before[backend_pos + 1] } // this giant mess because closures are not implemented backend := if backend_pos == -1 { '.c' } else { args_before[backend_pos + 1] } // this giant mess because closures are not implemented
mut ts := testing.new_test_session(args_before.join(' ')) mut ts := testing.new_test_session(args_before.join(' '), true)
for targ in args_after { for targ in args_after {
if os.is_dir(targ) { if os.is_dir(targ) {
// Fetch all tests from the directory // Fetch all tests from the directory

View File

@ -36,17 +36,17 @@ fn C.XChangeProperty(d &C.Display, requestor Window, property Atom, typ Atom, fo
fn C.XSendEvent(d &C.Display, requestor Window, propogate int, mask i64, event &C.XEvent) fn C.XSendEvent(d &C.Display, requestor Window, propogate int, mask i64, event &C.XEvent)
fn C.XInternAtom(d &C.Display, typ byteptr, only_if_exists int) Atom fn C.XInternAtom(d &C.Display, typ &byte, only_if_exists int) Atom
fn C.XCreateSimpleWindow(d &C.Display, root Window, x int, y int, width u32, height u32, border_width u32, border u64, background u64) Window fn C.XCreateSimpleWindow(d &C.Display, root Window, x int, y int, width u32, height u32, border_width u32, border u64, background u64) Window
fn C.XOpenDisplay(name byteptr) &C.Display fn C.XOpenDisplay(name &byte) &C.Display
fn C.XConvertSelection(d &C.Display, selection Atom, target Atom, property Atom, requestor Window, time int) int fn C.XConvertSelection(d &C.Display, selection Atom, target Atom, property Atom, requestor Window, time int) int
fn C.XSync(d &C.Display, discard int) int fn C.XSync(d &C.Display, discard int) int
fn C.XGetWindowProperty(d &C.Display, w Window, property Atom, offset i64, length i64, delete int, req_type Atom, actual_type_return &Atom, actual_format_return &int, nitems &u64, bytes_after_return &u64, prop_return &byteptr) int fn C.XGetWindowProperty(d &C.Display, w Window, property Atom, offset i64, length i64, delete int, req_type Atom, actual_type_return &Atom, actual_format_return &int, nitems &u64, bytes_after_return &u64, prop_return &&byte) int
fn C.XDeleteProperty(d &C.Display, w Window, property Atom) int fn C.XDeleteProperty(d &C.Display, w Window, property Atom) int
@ -149,7 +149,7 @@ struct Property {
actual_type Atom actual_type Atom
actual_format int actual_format int
nitems u64 nitems u64
data byteptr data &byte
} }
// new_clipboard returns a new `Clipboard` instance allocated on the heap. // new_clipboard returns a new `Clipboard` instance allocated on the heap.
@ -359,7 +359,7 @@ fn (mut cb Clipboard) start_listener() {
if cb.is_supported_target(prop.actual_type) { if cb.is_supported_target(prop.actual_type) {
cb.got_text = true cb.got_text = true
unsafe { unsafe {
cb.text = byteptr(prop.data).vstring() // TODO: return byteptr to support other mimetypes cb.text = prop.data.vstring() // TODO: return byteptr to support other mimetypes
} }
} }
cb.mutex.unlock() cb.mutex.unlock()
@ -393,14 +393,14 @@ fn read_property(d &C.Display, w Window, p Atom) Property {
actual_format := 0 actual_format := 0
nitems := u64(0) nitems := u64(0)
bytes_after := u64(0) bytes_after := u64(0)
ret := byteptr(0) ret := &byte(0)
mut read_bytes := 1024 mut read_bytes := 1024
for { for {
if ret != 0 { if ret != 0 {
C.XFree(ret) C.XFree(ret)
} }
C.XGetWindowProperty(d, w, p, 0, read_bytes, 0, 0, &actual_type, C.XGetWindowProperty(d, w, p, 0, read_bytes, 0, 0, &actual_type, &actual_format,
&actual_format, &nitems, &bytes_after, &ret) &nitems, &bytes_after, &ret)
read_bytes *= 2 read_bytes *= 2
if bytes_after == 0 { if bytes_after == 0 {
break break
@ -421,7 +421,7 @@ fn (cb &Clipboard) pick_target(prop Property) Atom {
// next instead as the lowest common denominator // next instead as the lowest common denominator
return cb.get_atom(.xa_string) return cb.get_atom(.xa_string)
} else { } else {
atom_list := &Atom(prop.data) atom_list := &Atom(voidptr(prop.data))
mut to_be_requested := Atom(0) mut to_be_requested := Atom(0)

View File

@ -40,20 +40,20 @@ pub fn new_cipher(key []byte) AesCipher {
// block_size returns the block size of the checksum in bytes. // block_size returns the block size of the checksum in bytes.
pub fn (c &AesCipher) block_size() int { pub fn (c &AesCipher) block_size() int {
return block_size return aes.block_size
} }
// encrypt encrypts the blocks in `src` to `dst`. // encrypt encrypts the blocks in `src` to `dst`.
// Please note: `dst` and `src` are both mutable for performance reasons. // Please note: `dst` and `src` are both mutable for performance reasons.
pub fn (c &AesCipher) encrypt(mut dst []byte, mut src []byte) { pub fn (c &AesCipher) encrypt(mut dst []byte, mut src []byte) {
if src.len < block_size { if src.len < aes.block_size {
panic('crypto.aes: input not full block') panic('crypto.aes: input not full block')
} }
if dst.len < block_size { if dst.len < aes.block_size {
panic('crypto.aes: output not full block') panic('crypto.aes: output not full block')
} }
// if subtle.inexact_overlap(dst[:block_size], src[:block_size]) { // if subtle.inexact_overlap(dst[:block_size], src[:block_size]) {
if subtle.inexact_overlap((*dst)[..block_size], (*src)[..block_size]) { if subtle.inexact_overlap((*dst)[..aes.block_size], (*src)[..aes.block_size]) {
panic('crypto.aes: invalid buffer overlap') panic('crypto.aes: invalid buffer overlap')
} }
// for now use generic version // for now use generic version
@ -63,13 +63,13 @@ pub fn (c &AesCipher) encrypt(mut dst []byte, mut src []byte) {
// decrypt decrypts the blocks in `src` to `dst`. // decrypt decrypts the blocks in `src` to `dst`.
// Please note: `dst` and `src` are both mutable for performance reasons. // Please note: `dst` and `src` are both mutable for performance reasons.
pub fn (c &AesCipher) decrypt(mut dst []byte, mut src []byte) { pub fn (c &AesCipher) decrypt(mut dst []byte, mut src []byte) {
if src.len < block_size { if src.len < aes.block_size {
panic('crypto.aes: input not full block') panic('crypto.aes: input not full block')
} }
if dst.len < block_size { if dst.len < aes.block_size {
panic('crypto.aes: output not full block') panic('crypto.aes: output not full block')
} }
if subtle.inexact_overlap((*dst)[..block_size], (*src)[..block_size]) { if subtle.inexact_overlap((*dst)[..aes.block_size], (*src)[..aes.block_size]) {
panic('crypto.aes: invalid buffer overlap') panic('crypto.aes: invalid buffer overlap')
} }
// for now use generic version // for now use generic version

View File

@ -22,7 +22,6 @@ fn test_crypto_aes() {
mode := aes.new_cbc(block, iv) mode := aes.new_cbc(block, iv)
cipher_clone := ciphertext.clone() cipher_clone := ciphertext.clone()
mode.encrypt_blocks(mut ciphertext, cipher_clone) mode.encrypt_blocks(mut ciphertext, cipher_clone)
assert ciphertext.hex() == assert ciphertext.hex() == 'c210459b514668ddc44674885e4979215265a6c44431a248421254ef357a8c2a308a8bddf5623af9df91737562041cf1'
'c210459b514668ddc44674885e4979215265a6c44431a248421254ef357a8c2a308a8bddf5623af9df91737562041cf1'
println('ok') println('ok')
} }

View File

@ -69,14 +69,10 @@ fn encrypt_block_generic(xk []u32, mut dst []byte, src []byte) {
s3 = t3 s3 = t3
} }
// Last round uses s-box directly and XORs to produce output. // Last round uses s-box directly and XORs to produce output.
s0 = s_box0[t0 >> 24] << 24 | s0 = s_box0[t0 >> 24] << 24 | s_box0[t1 >> 16 & 0xff] << 16 | u32(s_box0[t2 >> 8 & 0xff] << 8) | s_box0[t3 & u32(0xff)]
s_box0[t1 >> 16 & 0xff] << 16 | u32(s_box0[t2 >> 8 & 0xff] << 8) | s_box0[t3 & u32(0xff)] s1 = s_box0[t1 >> 24] << 24 | s_box0[t2 >> 16 & 0xff] << 16 | u32(s_box0[t3 >> 8 & 0xff] << 8) | s_box0[t0 & u32(0xff)]
s1 = s_box0[t1 >> 24] << 24 | s2 = s_box0[t2 >> 24] << 24 | s_box0[t3 >> 16 & 0xff] << 16 | u32(s_box0[t0 >> 8 & 0xff] << 8) | s_box0[t1 & u32(0xff)]
s_box0[t2 >> 16 & 0xff] << 16 | u32(s_box0[t3 >> 8 & 0xff] << 8) | s_box0[t0 & u32(0xff)] s3 = s_box0[t3 >> 24] << 24 | s_box0[t0 >> 16 & 0xff] << 16 | u32(s_box0[t1 >> 8 & 0xff] << 8) | s_box0[t2 & u32(0xff)]
s2 = s_box0[t2 >> 24] << 24 |
s_box0[t3 >> 16 & 0xff] << 16 | u32(s_box0[t0 >> 8 & 0xff] << 8) | s_box0[t1 & u32(0xff)]
s3 = s_box0[t3 >> 24] << 24 |
s_box0[t0 >> 16 & 0xff] << 16 | u32(s_box0[t1 >> 8 & 0xff] << 8) | s_box0[t2 & u32(0xff)]
s0 ^= xk[k + 0] s0 ^= xk[k + 0]
s1 ^= xk[k + 1] s1 ^= xk[k + 1]
s2 ^= xk[k + 2] s2 ^= xk[k + 2]
@ -120,14 +116,10 @@ fn decrypt_block_generic(xk []u32, mut dst []byte, src []byte) {
s3 = t3 s3 = t3
} }
// Last round uses s-box directly and XORs to produce output. // Last round uses s-box directly and XORs to produce output.
s0 = u32(s_box1[t0 >> 24]) << 24 | s0 = u32(s_box1[t0 >> 24]) << 24 | u32(s_box1[t3 >> 16 & 0xff]) << 16 | u32(s_box1[t2 >> 8 & 0xff] << 8) | u32(s_box1[t1 & u32(0xff)])
u32(s_box1[t3 >> 16 & 0xff]) << 16 | u32(s_box1[t2 >> 8 & 0xff] << 8) | u32(s_box1[t1 & u32(0xff)]) s1 = u32(s_box1[t1 >> 24]) << 24 | u32(s_box1[t0 >> 16 & 0xff]) << 16 | u32(s_box1[t3 >> 8 & 0xff] << 8) | u32(s_box1[t2 & u32(0xff)])
s1 = u32(s_box1[t1 >> 24]) << 24 | s2 = u32(s_box1[t2 >> 24]) << 24 | u32(s_box1[t1 >> 16 & 0xff]) << 16 | u32(s_box1[t0 >> 8 & 0xff] << 8) | u32(s_box1[t3 & u32(0xff)])
u32(s_box1[t0 >> 16 & 0xff]) << 16 | u32(s_box1[t3 >> 8 & 0xff] << 8) | u32(s_box1[t2 & u32(0xff)]) s3 = u32(s_box1[t3 >> 24]) << 24 | u32(s_box1[t2 >> 16 & 0xff]) << 16 | u32(s_box1[t1 >> 8 & 0xff] << 8) | u32(s_box1[t0 & u32(0xff)])
s2 = u32(s_box1[t2 >> 24]) << 24 |
u32(s_box1[t1 >> 16 & 0xff]) << 16 | u32(s_box1[t0 >> 8 & 0xff] << 8) | u32(s_box1[t3 & u32(0xff)])
s3 = u32(s_box1[t3 >> 24]) << 24 |
u32(s_box1[t2 >> 16 & 0xff]) << 16 | u32(s_box1[t1 >> 8 & 0xff] << 8) | u32(s_box1[t0 & u32(0xff)])
s0 ^= xk[k + 0] s0 ^= xk[k + 0]
s1 ^= xk[k + 1] s1 ^= xk[k + 1]
s2 ^= xk[k + 2] s2 ^= xk[k + 2]
@ -141,8 +133,7 @@ fn decrypt_block_generic(xk []u32, mut dst []byte, src []byte) {
// Apply s_box0 to each byte in w. // Apply s_box0 to each byte in w.
fn subw(w u32) u32 { fn subw(w u32) u32 {
return u32(s_box0[w >> 24]) << 24 | u32(s_box0[w >> 16 & 0xff] << 16) | u32(s_box0[w >> 8 & return u32(s_box0[w >> 24]) << 24 | u32(s_box0[w >> 16 & 0xff] << 16) | u32(s_box0[w >> 8 & 0xff] << 8) | u32(s_box0[w & u32(0xff)])
0xff] << 8) | u32(s_box0[w & u32(0xff)])
} }
// Rotate // Rotate
@ -184,8 +175,7 @@ fn expand_key_generic(key []byte, mut enc []u32, mut dec []u32) {
for j in 0 .. 4 { for j in 0 .. 4 {
mut x := enc[ei + j] mut x := enc[ei + j]
if i > 0 && i + 4 < n { if i > 0 && i + 4 < n {
x = td0[s_box0[x >> 24]] ^ td1[s_box0[x >> 16 & 0xff]] ^ td2[s_box0[x >> 8 & 0xff]] ^ x = td0[s_box0[x >> 24]] ^ td1[s_box0[x >> 16 & 0xff]] ^ td2[s_box0[x >> 8 & 0xff]] ^ td3[s_box0[x & u32(0xff)]]
td3[s_box0[x & u32(0xff)]]
} }
dec[i + j] = x dec[i + j] = x
} }

View File

@ -8,8 +8,8 @@ module aes
fn new_cipher_generic(key []byte) AesCipher { fn new_cipher_generic(key []byte) AesCipher {
n := key.len + 28 n := key.len + 28
mut c := AesCipher{ mut c := AesCipher{
enc: []u32{len: (n)} enc: []u32{len: n}
dec: []u32{len: (n)} dec: []u32{len: n}
} }
expand_key_generic(key, mut c.enc, mut c.dec) expand_key_generic(key, mut c.enc, mut c.dec)
return c return c

View File

@ -21,4 +21,3 @@ pub enum Hash {
blake2b_384 blake2b_384
blake2b_512 blake2b_512
} }

View File

@ -11,7 +11,7 @@ const (
) )
// new returns a HMAC byte array, depending on the hash algorithm used. // new returns a HMAC byte array, depending on the hash algorithm used.
pub fn new(key []byte, data []byte, hash_func fn (bytes []byte) []byte, blocksize int) []byte { pub fn new(key []byte, data []byte, hash_func fn ([]byte) []byte, blocksize int) []byte {
mut b_key := []byte{} mut b_key := []byte{}
if key.len <= blocksize { if key.len <= blocksize {
b_key = key.clone() // TODO: remove .clone() once https://github.com/vlang/v/issues/6604 gets fixed b_key = key.clone() // TODO: remove .clone() once https://github.com/vlang/v/issues/6604 gets fixed
@ -19,16 +19,16 @@ pub fn new(key []byte, data []byte, hash_func fn (bytes []byte) []byte, blocksiz
b_key = hash_func(key) b_key = hash_func(key)
} }
if b_key.len < blocksize { if b_key.len < blocksize {
b_key << npad[..blocksize - b_key.len] b_key << hmac.npad[..blocksize - b_key.len]
} }
mut inner := []byte{} mut inner := []byte{}
for i, b in ipad[..blocksize] { for i, b in hmac.ipad[..blocksize] {
inner << b_key[i] ^ b inner << b_key[i] ^ b
} }
inner << data inner << data
inner_hash := hash_func(inner) inner_hash := hash_func(inner)
mut outer := []byte{cap: b_key.len} mut outer := []byte{cap: b_key.len}
for i, b in opad[..blocksize] { for i, b in hmac.opad[..blocksize] {
outer << b_key[i] ^ b outer << b_key[i] ^ b
} }
outer << inner_hash outer << inner_hash

View File

@ -21,31 +21,37 @@ import crypto.sha512
// import crypto.blake2b_512 // import crypto.blake2b_512
const ( const (
keys = [[byte(0xb), 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb], keys = [[byte(0xb), 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb],
'Jefe'.bytes(), [byte(0xAA), 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 'Jefe'.bytes(),
0xAA, 0xAA, 0xAA, 0xAA], [byte(0x01), 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, [byte(0xAA), 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19], 0xAA, 0xAA, 0xAA, 0xAA, 0xAA],
[byte(0x0c), 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, [byte(0x01), 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
0x0c, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19],
], [byte(0xaa), 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, [byte(0x0c), 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x0c, 0x0c],
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, [byte(0xaa), 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa], [byte(0xaa), 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa],
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, [byte(0xaa), 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa]] 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa],
]
data = ['Hi There'.bytes(), 'what do ya want for nothing?'.bytes(), data = ['Hi There'.bytes(), 'what do ya want for nothing?'.bytes(),
[byte(0xDD), 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, [byte(0xDD), 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
0xDD, 0xDD, 0xDD], [byte(0xcd), 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD],
0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, [byte(0xcd), 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd], 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
'Test With Truncation'.bytes(), 'Test Using Larger Than Block-Size Key - Hash Key First'.bytes(), 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd],
'Test With Truncation'.bytes(),
'Test Using Larger Than Block-Size Key - Hash Key First'.bytes(),
'Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data'.bytes(), 'Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data'.bytes(),
] ]
) )
@ -61,8 +67,8 @@ fn test_hmac_md5() {
'6f630fad67cda0ee1fb1f562db3aa53e', '6f630fad67cda0ee1fb1f562db3aa53e',
] ]
mut result := '' mut result := ''
for i, key in keys { for i, key in hmac.keys {
result = hmac.new(key, data[i], md5.sum, md5.block_size).hex() result = hmac.new(key, hmac.data[i], md5.sum, md5.block_size).hex()
assert result == md5_expected_results[i] assert result == md5_expected_results[i]
} }
} }
@ -78,8 +84,8 @@ fn test_hmac_sha1() {
'e8e99d0f45237d786d6bbaa7965c7808bbff1a91', 'e8e99d0f45237d786d6bbaa7965c7808bbff1a91',
] ]
mut result := '' mut result := ''
for i, key in keys { for i, key in hmac.keys {
result = hmac.new(key, data[i], sha1.sum, sha1.block_size).hex() result = hmac.new(key, hmac.data[i], sha1.sum, sha1.block_size).hex()
assert result == sha1_expected_results[i] assert result == sha1_expected_results[i]
} }
} }
@ -95,8 +101,8 @@ fn test_hmac_sha224() {
'7358939e58683a448ac5065196d33191a1c1d33d4b8b0304dc60f5e0', '7358939e58683a448ac5065196d33191a1c1d33d4b8b0304dc60f5e0',
] ]
mut result := '' mut result := ''
for i, key in keys { for i, key in hmac.keys {
result = hmac.new(key, data[i], sha256.sum224, sha256.block_size).hex() result = hmac.new(key, hmac.data[i], sha256.sum224, sha256.block_size).hex()
assert result == sha224_expected_results[i] assert result == sha224_expected_results[i]
} }
} }
@ -112,8 +118,8 @@ fn test_hmac_sha256() {
'6355ac22e890d0a3c8481a5ca4825bc884d3e7a1ff98a2fc2ac7d8e064c3b2e6', '6355ac22e890d0a3c8481a5ca4825bc884d3e7a1ff98a2fc2ac7d8e064c3b2e6',
] ]
mut result := '' mut result := ''
for i, key in keys { for i, key in hmac.keys {
result = hmac.new(key, data[i], sha256.sum, sha256.block_size).hex() result = hmac.new(key, hmac.data[i], sha256.sum, sha256.block_size).hex()
assert result == sha256_expected_results[i] assert result == sha256_expected_results[i]
} }
} }
@ -129,8 +135,8 @@ fn test_hmac_sha384() {
'34f065bdedc2487c30a634d9a49cf42116f78bb386ea4d498aea05c0077f05373cfdaa9b59a7b0481bced9e3f55016a9', '34f065bdedc2487c30a634d9a49cf42116f78bb386ea4d498aea05c0077f05373cfdaa9b59a7b0481bced9e3f55016a9',
] ]
mut result := '' mut result := ''
for i, key in keys { for i, key in hmac.keys {
result = hmac.new(key, data[i], sha512.sum384, sha512.block_size).hex() result = hmac.new(key, hmac.data[i], sha512.sum384, sha512.block_size).hex()
assert result == sha384_expected_results[i] assert result == sha384_expected_results[i]
} }
} }
@ -146,8 +152,8 @@ fn test_hmac_sha512() {
'09441cda584ed2f4d2f5b519c71baf3c79cce19dfc89a548e73b3bb382a9124d6e792b77bf57903ff5858e5d111d15f45d6fd118eea023f28d2eb234ebe62f85', '09441cda584ed2f4d2f5b519c71baf3c79cce19dfc89a548e73b3bb382a9124d6e792b77bf57903ff5858e5d111d15f45d6fd118eea023f28d2eb234ebe62f85',
] ]
mut result := '' mut result := ''
for i, key in keys { for i, key in hmac.keys {
result = hmac.new(key, data[i], sha512.sum512, sha512.block_size).hex() result = hmac.new(key, hmac.data[i], sha512.sum512, sha512.block_size).hex()
assert result == sha512_expected_results[i] assert result == sha512_expected_results[i]
} }
} }

View File

@ -10,9 +10,9 @@ module subtle
// corresponding) index. The memory beyond the slice length is ignored. // corresponding) index. The memory beyond the slice length is ignored.
pub fn any_overlap(x []byte, y []byte) bool { pub fn any_overlap(x []byte, y []byte) bool {
// NOTE: Remember to come back to this (joe-c) // NOTE: Remember to come back to this (joe-c)
return x.len > 0 && y.len > 0 && // &x.data[0] <= &y.data[y.len-1] && return x.len > 0 && y.len > 0 && // &x.data[0] <= &y.data[y.len-1] &&
// &y.data[0] <= &x.data[x.len-1] // &y.data[0] <= &x.data[x.len-1]
unsafe {&x[0] <= &y[y.len - 1] && &y[0] <= &x[x.len - 1]} unsafe { &x[0] <= &y[y.len - 1] && &y[0] <= &x[x.len - 1] }
} }
// inexact_overlap reports whether x and y share memory at any non-corresponding // inexact_overlap reports whether x and y share memory at any non-corresponding
@ -22,7 +22,7 @@ pub fn any_overlap(x []byte, y []byte) bool {
// inexact_overlap can be used to implement the requirements of the crypto/cipher // inexact_overlap can be used to implement the requirements of the crypto/cipher
// AEAD, Block, BlockMode and Stream interfaces. // AEAD, Block, BlockMode and Stream interfaces.
pub fn inexact_overlap(x []byte, y []byte) bool { pub fn inexact_overlap(x []byte, y []byte) bool {
if x.len == 0 || y.len == 0 || unsafe {&x[0] == &y[0]} { if x.len == 0 || y.len == 0 || unsafe { &x[0] == &y[0] } {
return false return false
} }
return any_overlap(x, y) return any_overlap(x, y)

View File

@ -35,11 +35,11 @@ mut:
fn (mut d Digest) reset() { fn (mut d Digest) reset() {
d.s = []u32{len: (4)} d.s = []u32{len: (4)}
d.x = []byte{len: (block_size)} d.x = []byte{len: md5.block_size}
d.s[0] = u32(init0) d.s[0] = u32(md5.init0)
d.s[1] = u32(init1) d.s[1] = u32(md5.init1)
d.s[2] = u32(init2) d.s[2] = u32(md5.init2)
d.s[3] = u32(init3) d.s[3] = u32(md5.init3)
d.nx = 0 d.nx = 0
d.len = 0 d.len = 0
} }
@ -60,7 +60,7 @@ pub fn (mut d Digest) write(p_ []byte) ?int {
if d.nx > 0 { if d.nx > 0 {
n := copy(d.x[d.nx..], p) n := copy(d.x[d.nx..], p)
d.nx += n d.nx += n
if d.nx == block_size { if d.nx == md5.block_size {
block(mut d, d.x) block(mut d, d.x)
d.nx = 0 d.nx = 0
} }
@ -70,8 +70,8 @@ pub fn (mut d Digest) write(p_ []byte) ?int {
p = p[n..] p = p[n..]
} }
} }
if p.len >= block_size { if p.len >= md5.block_size {
n := p.len & ~(block_size - 1) n := p.len & ~(md5.block_size - 1)
block(mut d, p[..n]) block(mut d, p[..n])
if n >= p.len { if n >= p.len {
p = [] p = []
@ -116,7 +116,7 @@ pub fn (mut d Digest) checksum() []byte {
if d.nx != 0 { if d.nx != 0 {
panic('d.nx != 0') panic('d.nx != 0')
} }
mut digest := []byte{len: (size)} mut digest := []byte{len: md5.size}
binary.little_endian_put_u32(mut digest, d.s[0]) binary.little_endian_put_u32(mut digest, d.s[0])
binary.little_endian_put_u32(mut digest[4..], d.s[1]) binary.little_endian_put_u32(mut digest[4..], d.s[1])
binary.little_endian_put_u32(mut digest[8..], d.s[2]) binary.little_endian_put_u32(mut digest[8..], d.s[2])
@ -139,12 +139,12 @@ fn block(mut dig Digest, p []byte) {
// size returns the size of the checksum in bytes. // size returns the size of the checksum in bytes.
pub fn (d &Digest) size() int { pub fn (d &Digest) size() int {
return size return md5.size
} }
// block_size returns the block size of the checksum in bytes. // block_size returns the block size of the checksum in bytes.
pub fn (d &Digest) block_size() int { pub fn (d &Digest) block_size() int {
return block_size return md5.block_size
} }
// hexhash returns a hexadecimal MD5 hash sum `string` of `s`. // hexhash returns a hexadecimal MD5 hash sum `string` of `s`.

View File

@ -1,7 +1,6 @@
// Copyright (c) 2019-2021 Alexander Medvednikov. All rights reserved. // Copyright (c) 2019-2021 Alexander Medvednikov. All rights reserved.
// Use of this source code is governed by an MIT license // Use of this source code is governed by an MIT license
// that can be found in the LICENSE file. // that can be found in the LICENSE file.
import crypto.md5 import crypto.md5
fn test_crypto_md5() { fn test_crypto_md5() {

View File

@ -18,7 +18,7 @@ fn block_generic(mut dig Digest, p []byte) {
mut c := dig.s[2] mut c := dig.s[2]
mut d := dig.s[3] mut d := dig.s[3]
for i := 0; i <= p.len-block_size; i += block_size { for i := 0; i <= p.len - block_size; i += block_size {
mut q := p[i..] mut q := p[i..]
q = q[..block_size] q = q[..block_size]
// save current state // save current state
@ -28,94 +28,94 @@ fn block_generic(mut dig Digest, p []byte) {
dd := d dd := d
// load input block // load input block
x0 := binary.little_endian_u32(q[4*0x0..]) x0 := binary.little_endian_u32(q[4 * 0x0..])
x1 := binary.little_endian_u32(q[4*0x1..]) x1 := binary.little_endian_u32(q[4 * 0x1..])
x2 := binary.little_endian_u32(q[4*0x2..]) x2 := binary.little_endian_u32(q[4 * 0x2..])
x3 := binary.little_endian_u32(q[4*0x3..]) x3 := binary.little_endian_u32(q[4 * 0x3..])
x4 := binary.little_endian_u32(q[4*0x4..]) x4 := binary.little_endian_u32(q[4 * 0x4..])
x5 := binary.little_endian_u32(q[4*0x5..]) x5 := binary.little_endian_u32(q[4 * 0x5..])
x6 := binary.little_endian_u32(q[4*0x6..]) x6 := binary.little_endian_u32(q[4 * 0x6..])
x7 := binary.little_endian_u32(q[4*0x7..]) x7 := binary.little_endian_u32(q[4 * 0x7..])
x8 := binary.little_endian_u32(q[4*0x8..]) x8 := binary.little_endian_u32(q[4 * 0x8..])
x9 := binary.little_endian_u32(q[4*0x9..]) x9 := binary.little_endian_u32(q[4 * 0x9..])
xa := binary.little_endian_u32(q[4*0xa..]) xa := binary.little_endian_u32(q[4 * 0xa..])
xb := binary.little_endian_u32(q[4*0xb..]) xb := binary.little_endian_u32(q[4 * 0xb..])
xc := binary.little_endian_u32(q[4*0xc..]) xc := binary.little_endian_u32(q[4 * 0xc..])
xd := binary.little_endian_u32(q[4*0xd..]) xd := binary.little_endian_u32(q[4 * 0xd..])
xe := binary.little_endian_u32(q[4*0xe..]) xe := binary.little_endian_u32(q[4 * 0xe..])
xf := binary.little_endian_u32(q[4*0xf..]) xf := binary.little_endian_u32(q[4 * 0xf..])
// round 1 // round 1
a = b + bits.rotate_left_32((((c^d)&b)^d)+a+x0+u32(0xd76aa478), 7) a = b + bits.rotate_left_32((((c ^ d) & b) ^ d) + a + x0 + u32(0xd76aa478), 7)
d = a + bits.rotate_left_32((((b^c)&a)^c)+d+x1+u32(0xe8c7b756), 12) d = a + bits.rotate_left_32((((b ^ c) & a) ^ c) + d + x1 + u32(0xe8c7b756), 12)
c = d + bits.rotate_left_32((((a^b)&d)^b)+c+x2+u32(0x242070db), 17) c = d + bits.rotate_left_32((((a ^ b) & d) ^ b) + c + x2 + u32(0x242070db), 17)
b = c + bits.rotate_left_32((((d^a)&c)^a)+b+x3+u32(0xc1bdceee), 22) b = c + bits.rotate_left_32((((d ^ a) & c) ^ a) + b + x3 + u32(0xc1bdceee), 22)
a = b + bits.rotate_left_32((((c^d)&b)^d)+a+x4+u32(0xf57c0faf), 7) a = b + bits.rotate_left_32((((c ^ d) & b) ^ d) + a + x4 + u32(0xf57c0faf), 7)
d = a + bits.rotate_left_32((((b^c)&a)^c)+d+x5+u32(0x4787c62a), 12) d = a + bits.rotate_left_32((((b ^ c) & a) ^ c) + d + x5 + u32(0x4787c62a), 12)
c = d + bits.rotate_left_32((((a^b)&d)^b)+c+x6+u32(0xa8304613), 17) c = d + bits.rotate_left_32((((a ^ b) & d) ^ b) + c + x6 + u32(0xa8304613), 17)
b = c + bits.rotate_left_32((((d^a)&c)^a)+b+x7+u32(0xfd469501), 22) b = c + bits.rotate_left_32((((d ^ a) & c) ^ a) + b + x7 + u32(0xfd469501), 22)
a = b + bits.rotate_left_32((((c^d)&b)^d)+a+x8+u32(0x698098d8), 7) a = b + bits.rotate_left_32((((c ^ d) & b) ^ d) + a + x8 + u32(0x698098d8), 7)
d = a + bits.rotate_left_32((((b^c)&a)^c)+d+x9+u32(0x8b44f7af), 12) d = a + bits.rotate_left_32((((b ^ c) & a) ^ c) + d + x9 + u32(0x8b44f7af), 12)
c = d + bits.rotate_left_32((((a^b)&d)^b)+c+xa+u32(0xffff5bb1), 17) c = d + bits.rotate_left_32((((a ^ b) & d) ^ b) + c + xa + u32(0xffff5bb1), 17)
b = c + bits.rotate_left_32((((d^a)&c)^a)+b+xb+u32(0x895cd7be), 22) b = c + bits.rotate_left_32((((d ^ a) & c) ^ a) + b + xb + u32(0x895cd7be), 22)
a = b + bits.rotate_left_32((((c^d)&b)^d)+a+xc+u32(0x6b901122), 7) a = b + bits.rotate_left_32((((c ^ d) & b) ^ d) + a + xc + u32(0x6b901122), 7)
d = a + bits.rotate_left_32((((b^c)&a)^c)+d+xd+u32(0xfd987193), 12) d = a + bits.rotate_left_32((((b ^ c) & a) ^ c) + d + xd + u32(0xfd987193), 12)
c = d + bits.rotate_left_32((((a^b)&d)^b)+c+xe+u32(0xa679438e), 17) c = d + bits.rotate_left_32((((a ^ b) & d) ^ b) + c + xe + u32(0xa679438e), 17)
b = c + bits.rotate_left_32((((d^a)&c)^a)+b+xf+u32(0x49b40821), 22) b = c + bits.rotate_left_32((((d ^ a) & c) ^ a) + b + xf + u32(0x49b40821), 22)
// round 2 // round 2
a = b + bits.rotate_left_32((((b^c)&d)^c)+a+x1+u32(0xf61e2562), 5) a = b + bits.rotate_left_32((((b ^ c) & d) ^ c) + a + x1 + u32(0xf61e2562), 5)
d = a + bits.rotate_left_32((((a^b)&c)^b)+d+x6+u32(0xc040b340), 9) d = a + bits.rotate_left_32((((a ^ b) & c) ^ b) + d + x6 + u32(0xc040b340), 9)
c = d + bits.rotate_left_32((((d^a)&b)^a)+c+xb+u32(0x265e5a51), 14) c = d + bits.rotate_left_32((((d ^ a) & b) ^ a) + c + xb + u32(0x265e5a51), 14)
b = c + bits.rotate_left_32((((c^d)&a)^d)+b+x0+u32(0xe9b6c7aa), 20) b = c + bits.rotate_left_32((((c ^ d) & a) ^ d) + b + x0 + u32(0xe9b6c7aa), 20)
a = b + bits.rotate_left_32((((b^c)&d)^c)+a+x5+u32(0xd62f105d), 5) a = b + bits.rotate_left_32((((b ^ c) & d) ^ c) + a + x5 + u32(0xd62f105d), 5)
d = a + bits.rotate_left_32((((a^b)&c)^b)+d+xa+u32(0x02441453), 9) d = a + bits.rotate_left_32((((a ^ b) & c) ^ b) + d + xa + u32(0x02441453), 9)
c = d + bits.rotate_left_32((((d^a)&b)^a)+c+xf+u32(0xd8a1e681), 14) c = d + bits.rotate_left_32((((d ^ a) & b) ^ a) + c + xf + u32(0xd8a1e681), 14)
b = c + bits.rotate_left_32((((c^d)&a)^d)+b+x4+u32(0xe7d3fbc8), 20) b = c + bits.rotate_left_32((((c ^ d) & a) ^ d) + b + x4 + u32(0xe7d3fbc8), 20)
a = b + bits.rotate_left_32((((b^c)&d)^c)+a+x9+u32(0x21e1cde6), 5) a = b + bits.rotate_left_32((((b ^ c) & d) ^ c) + a + x9 + u32(0x21e1cde6), 5)
d = a + bits.rotate_left_32((((a^b)&c)^b)+d+xe+u32(0xc33707d6), 9) d = a + bits.rotate_left_32((((a ^ b) & c) ^ b) + d + xe + u32(0xc33707d6), 9)
c = d + bits.rotate_left_32((((d^a)&b)^a)+c+x3+u32(0xf4d50d87), 14) c = d + bits.rotate_left_32((((d ^ a) & b) ^ a) + c + x3 + u32(0xf4d50d87), 14)
b = c + bits.rotate_left_32((((c^d)&a)^d)+b+x8+u32(0x455a14ed), 20) b = c + bits.rotate_left_32((((c ^ d) & a) ^ d) + b + x8 + u32(0x455a14ed), 20)
a = b + bits.rotate_left_32((((b^c)&d)^c)+a+xd+u32(0xa9e3e905), 5) a = b + bits.rotate_left_32((((b ^ c) & d) ^ c) + a + xd + u32(0xa9e3e905), 5)
d = a + bits.rotate_left_32((((a^b)&c)^b)+d+x2+u32(0xfcefa3f8), 9) d = a + bits.rotate_left_32((((a ^ b) & c) ^ b) + d + x2 + u32(0xfcefa3f8), 9)
c = d + bits.rotate_left_32((((d^a)&b)^a)+c+x7+u32(0x676f02d9), 14) c = d + bits.rotate_left_32((((d ^ a) & b) ^ a) + c + x7 + u32(0x676f02d9), 14)
b = c + bits.rotate_left_32((((c^d)&a)^d)+b+xc+u32(0x8d2a4c8a), 20) b = c + bits.rotate_left_32((((c ^ d) & a) ^ d) + b + xc + u32(0x8d2a4c8a), 20)
// round 3 // round 3
a = b + bits.rotate_left_32((b^c^d)+a+x5+u32(0xfffa3942), 4) a = b + bits.rotate_left_32((b ^ c ^ d) + a + x5 + u32(0xfffa3942), 4)
d = a + bits.rotate_left_32((a^b^c)+d+x8+u32(0x8771f681), 11) d = a + bits.rotate_left_32((a ^ b ^ c) + d + x8 + u32(0x8771f681), 11)
c = d + bits.rotate_left_32((d^a^b)+c+xb+u32(0x6d9d6122), 16) c = d + bits.rotate_left_32((d ^ a ^ b) + c + xb + u32(0x6d9d6122), 16)
b = c + bits.rotate_left_32((c^d^a)+b+xe+u32(0xfde5380c), 23) b = c + bits.rotate_left_32((c ^ d ^ a) + b + xe + u32(0xfde5380c), 23)
a = b + bits.rotate_left_32((b^c^d)+a+x1+u32(0xa4beea44), 4) a = b + bits.rotate_left_32((b ^ c ^ d) + a + x1 + u32(0xa4beea44), 4)
d = a + bits.rotate_left_32((a^b^c)+d+x4+u32(0x4bdecfa9), 11) d = a + bits.rotate_left_32((a ^ b ^ c) + d + x4 + u32(0x4bdecfa9), 11)
c = d + bits.rotate_left_32((d^a^b)+c+x7+u32(0xf6bb4b60), 16) c = d + bits.rotate_left_32((d ^ a ^ b) + c + x7 + u32(0xf6bb4b60), 16)
b = c + bits.rotate_left_32((c^d^a)+b+xa+u32(0xbebfbc70), 23) b = c + bits.rotate_left_32((c ^ d ^ a) + b + xa + u32(0xbebfbc70), 23)
a = b + bits.rotate_left_32((b^c^d)+a+xd+u32(0x289b7ec6), 4) a = b + bits.rotate_left_32((b ^ c ^ d) + a + xd + u32(0x289b7ec6), 4)
d = a + bits.rotate_left_32((a^b^c)+d+x0+u32(0xeaa127fa), 11) d = a + bits.rotate_left_32((a ^ b ^ c) + d + x0 + u32(0xeaa127fa), 11)
c = d + bits.rotate_left_32((d^a^b)+c+x3+u32(0xd4ef3085), 16) c = d + bits.rotate_left_32((d ^ a ^ b) + c + x3 + u32(0xd4ef3085), 16)
b = c + bits.rotate_left_32((c^d^a)+b+x6+u32(0x04881d05), 23) b = c + bits.rotate_left_32((c ^ d ^ a) + b + x6 + u32(0x04881d05), 23)
a = b + bits.rotate_left_32((b^c^d)+a+x9+u32(0xd9d4d039), 4) a = b + bits.rotate_left_32((b ^ c ^ d) + a + x9 + u32(0xd9d4d039), 4)
d = a + bits.rotate_left_32((a^b^c)+d+xc+u32(0xe6db99e5), 11) d = a + bits.rotate_left_32((a ^ b ^ c) + d + xc + u32(0xe6db99e5), 11)
c = d + bits.rotate_left_32((d^a^b)+c+xf+u32(0x1fa27cf8), 16) c = d + bits.rotate_left_32((d ^ a ^ b) + c + xf + u32(0x1fa27cf8), 16)
b = c + bits.rotate_left_32((c^d^a)+b+x2+u32(0xc4ac5665), 23) b = c + bits.rotate_left_32((c ^ d ^ a) + b + x2 + u32(0xc4ac5665), 23)
// round 4 // round 4
a = b + bits.rotate_left_32((c^(b|~d))+a+x0+u32(0xf4292244), 6) a = b + bits.rotate_left_32((c ^ (b | ~d)) + a + x0 + u32(0xf4292244), 6)
d = a + bits.rotate_left_32((b^(a|~c))+d+x7+u32(0x432aff97), 10) d = a + bits.rotate_left_32((b ^ (a | ~c)) + d + x7 + u32(0x432aff97), 10)
c = d + bits.rotate_left_32((a^(d|~b))+c+xe+u32(0xab9423a7), 15) c = d + bits.rotate_left_32((a ^ (d | ~b)) + c + xe + u32(0xab9423a7), 15)
b = c + bits.rotate_left_32((d^(c|~a))+b+x5+u32(0xfc93a039), 21) b = c + bits.rotate_left_32((d ^ (c | ~a)) + b + x5 + u32(0xfc93a039), 21)
a = b + bits.rotate_left_32((c^(b|~d))+a+xc+u32(0x655b59c3), 6) a = b + bits.rotate_left_32((c ^ (b | ~d)) + a + xc + u32(0x655b59c3), 6)
d = a + bits.rotate_left_32((b^(a|~c))+d+x3+u32(0x8f0ccc92), 10) d = a + bits.rotate_left_32((b ^ (a | ~c)) + d + x3 + u32(0x8f0ccc92), 10)
c = d + bits.rotate_left_32((a^(d|~b))+c+xa+u32(0xffeff47d), 15) c = d + bits.rotate_left_32((a ^ (d | ~b)) + c + xa + u32(0xffeff47d), 15)
b = c + bits.rotate_left_32((d^(c|~a))+b+x1+u32(0x85845dd1), 21) b = c + bits.rotate_left_32((d ^ (c | ~a)) + b + x1 + u32(0x85845dd1), 21)
a = b + bits.rotate_left_32((c^(b|~d))+a+x8+u32(0x6fa87e4f), 6) a = b + bits.rotate_left_32((c ^ (b | ~d)) + a + x8 + u32(0x6fa87e4f), 6)
d = a + bits.rotate_left_32((b^(a|~c))+d+xf+u32(0xfe2ce6e0), 10) d = a + bits.rotate_left_32((b ^ (a | ~c)) + d + xf + u32(0xfe2ce6e0), 10)
c = d + bits.rotate_left_32((a^(d|~b))+c+x6+u32(0xa3014314), 15) c = d + bits.rotate_left_32((a ^ (d | ~b)) + c + x6 + u32(0xa3014314), 15)
b = c + bits.rotate_left_32((d^(c|~a))+b+xd+u32(0x4e0811a1), 21) b = c + bits.rotate_left_32((d ^ (c | ~a)) + b + xd + u32(0x4e0811a1), 21)
a = b + bits.rotate_left_32((c^(b|~d))+a+x4+u32(0xf7537e82), 6) a = b + bits.rotate_left_32((c ^ (b | ~d)) + a + x4 + u32(0xf7537e82), 6)
d = a + bits.rotate_left_32((b^(a|~c))+d+xb+u32(0xbd3af235), 10) d = a + bits.rotate_left_32((b ^ (a | ~c)) + d + xb + u32(0xbd3af235), 10)
c = d + bits.rotate_left_32((a^(d|~b))+c+x2+u32(0x2ad7d2bb), 15) c = d + bits.rotate_left_32((a ^ (d | ~b)) + c + x2 + u32(0x2ad7d2bb), 15)
b = c + bits.rotate_left_32((d^(c|~a))+b+x9+u32(0xeb86d391), 21) b = c + bits.rotate_left_32((d ^ (c | ~a)) + b + x9 + u32(0xeb86d391), 21)
// add saved state // add saved state
a += aa a += aa

View File

@ -4,6 +4,7 @@
module rand module rand
#include <sys/syscall.h> #include <sys/syscall.h>
const ( const (
read_batch_size = 256 read_batch_size = 256
) )
@ -15,7 +16,11 @@ pub fn read(bytes_needed int) ?[]byte {
mut remaining_bytes := bytes_needed mut remaining_bytes := bytes_needed
// getrandom syscall wont block if requesting <= 256 bytes // getrandom syscall wont block if requesting <= 256 bytes
for bytes_read < bytes_needed { for bytes_read < bytes_needed {
batch_size := if remaining_bytes > read_batch_size { read_batch_size } else { remaining_bytes } batch_size := if remaining_bytes > rand.read_batch_size {
rand.read_batch_size
} else {
remaining_bytes
}
rbytes := unsafe { getrandom(batch_size, buffer + bytes_read) } rbytes := unsafe { getrandom(batch_size, buffer + bytes_read) }
if rbytes == -1 { if rbytes == -1 {
unsafe { free(buffer) } unsafe { free(buffer) }
@ -23,12 +28,12 @@ pub fn read(bytes_needed int) ?[]byte {
} }
bytes_read += rbytes bytes_read += rbytes
} }
return unsafe {buffer.vbytes(bytes_needed)} return unsafe { buffer.vbytes(bytes_needed) }
} }
fn getrandom(bytes_needed int, buffer voidptr) int { fn getrandom(bytes_needed int, buffer voidptr) int {
if bytes_needed > read_batch_size { if bytes_needed > rand.read_batch_size {
panic('getrandom() dont request more than $read_batch_size bytes at once.') panic('getrandom() dont request more than $rand.read_batch_size bytes at once.')
} }
return unsafe { C.syscall(C.SYS_getrandom, buffer, bytes_needed, 0) } return unsafe { C.syscall(C.SYS_getrandom, buffer, bytes_needed, 0) }
} }

View File

@ -6,7 +6,7 @@ module rand
#include <sys/random.h> #include <sys/random.h>
fn C.getrandom(p byteptr, n size_t, flags u32) int fn C.getrandom(p &byte, n size_t, flags u32) int
const ( const (
read_batch_size = 256 read_batch_size = 256
@ -19,7 +19,11 @@ pub fn read(bytes_needed int) ?[]byte {
mut remaining_bytes := bytes_needed mut remaining_bytes := bytes_needed
// getrandom syscall wont block if requesting <= 256 bytes // getrandom syscall wont block if requesting <= 256 bytes
for bytes_read < bytes_needed { for bytes_read < bytes_needed {
batch_size := if remaining_bytes > read_batch_size { read_batch_size } else { remaining_bytes } batch_size := if remaining_bytes > rand.read_batch_size {
rand.read_batch_size
} else {
remaining_bytes
}
rbytes := unsafe { getrandom(batch_size, buffer + bytes_read) } rbytes := unsafe { getrandom(batch_size, buffer + bytes_read) }
if rbytes == -1 { if rbytes == -1 {
unsafe { free(buffer) } unsafe { free(buffer) }
@ -27,12 +31,12 @@ pub fn read(bytes_needed int) ?[]byte {
} }
bytes_read += rbytes bytes_read += rbytes
} }
return unsafe {buffer.vbytes(bytes_needed)} return unsafe { buffer.vbytes(bytes_needed) }
} }
fn v_getrandom(bytes_needed int, buffer voidptr) int { fn v_getrandom(bytes_needed int, buffer voidptr) int {
if bytes_needed > read_batch_size { if bytes_needed > rand.read_batch_size {
panic('getrandom() dont request more than $read_batch_size bytes at once.') panic('getrandom() dont request more than $rand.read_batch_size bytes at once.')
} }
return C.getrandom(buffer, bytes_needed, 0) return C.getrandom(buffer, bytes_needed, 0)
} }

View File

@ -15,10 +15,10 @@ const (
// read returns an array of `bytes_needed` random bytes read from the OS. // read returns an array of `bytes_needed` random bytes read from the OS.
pub fn read(bytes_needed int) ?[]byte { pub fn read(bytes_needed int) ?[]byte {
mut buffer := []byte{ len: bytes_needed } mut buffer := []byte{len: bytes_needed}
// use bcrypt_use_system_preferred_rng because we passed null as algo // use bcrypt_use_system_preferred_rng because we passed null as algo
status := C.BCryptGenRandom(0, buffer.data, bytes_needed, bcrypt_use_system_preferred_rng) status := C.BCryptGenRandom(0, buffer.data, bytes_needed, rand.bcrypt_use_system_preferred_rng)
if status != status_success { if status != rand.status_success {
return IError(&ReadError{}) return IError(&ReadError{})
} }
return buffer return buffer

View File

@ -1,7 +1,6 @@
// Copyright (c) 2019-2021 Alexander Medvednikov. All rights reserved. // Copyright (c) 2019-2021 Alexander Medvednikov. All rights reserved.
// Use of this source code is governed by an MIT license // Use of this source code is governed by an MIT license
// that can be found in the LICENSE file. // that can be found in the LICENSE file.
import crypto.rc4 import crypto.rc4
fn test_crypto_rc4() { fn test_crypto_rc4() {

View File

@ -36,13 +36,13 @@ mut:
} }
fn (mut d Digest) reset() { fn (mut d Digest) reset() {
d.x = []byte{len: (chunk)} d.x = []byte{len: sha1.chunk}
d.h = []u32{len: (5)} d.h = []u32{len: (5)}
d.h[0] = u32(init0) d.h[0] = u32(sha1.init0)
d.h[1] = u32(init1) d.h[1] = u32(sha1.init1)
d.h[2] = u32(init2) d.h[2] = u32(sha1.init2)
d.h[3] = u32(init3) d.h[3] = u32(sha1.init3)
d.h[4] = u32(init4) d.h[4] = u32(sha1.init4)
d.nx = 0 d.nx = 0
d.len = 0 d.len = 0
} }
@ -64,7 +64,7 @@ pub fn (mut d Digest) write(p_ []byte) ?int {
if d.nx > 0 { if d.nx > 0 {
n := copy(d.x[d.nx..], p) n := copy(d.x[d.nx..], p)
d.nx += n d.nx += n
if d.nx == chunk { if d.nx == sha1.chunk {
block(mut d, d.x) block(mut d, d.x)
d.nx = 0 d.nx = 0
} }
@ -74,8 +74,8 @@ pub fn (mut d Digest) write(p_ []byte) ?int {
p = p[n..] p = p[n..]
} }
} }
if p.len >= chunk { if p.len >= sha1.chunk {
n := p.len & ~(chunk - 1) n := p.len & ~(sha1.chunk - 1)
block(mut d, p[..n]) block(mut d, p[..n])
if n >= p.len { if n >= p.len {
p = [] p = []
@ -117,7 +117,7 @@ fn (mut d Digest) checksum() []byte {
len <<= 3 len <<= 3
binary.big_endian_put_u64(mut tmp, len) binary.big_endian_put_u64(mut tmp, len)
d.write(tmp[..8]) or { panic(err) } d.write(tmp[..8]) or { panic(err) }
mut digest := []byte{len: (size)} mut digest := []byte{len: sha1.size}
binary.big_endian_put_u32(mut digest, d.h[0]) binary.big_endian_put_u32(mut digest, d.h[0])
binary.big_endian_put_u32(mut digest[4..], d.h[1]) binary.big_endian_put_u32(mut digest[4..], d.h[1])
binary.big_endian_put_u32(mut digest[8..], d.h[2]) binary.big_endian_put_u32(mut digest[8..], d.h[2])
@ -141,12 +141,12 @@ fn block(mut dig Digest, p []byte) {
// size returns the size of the checksum in bytes. // size returns the size of the checksum in bytes.
pub fn (d &Digest) size() int { pub fn (d &Digest) size() int {
return size return sha1.size
} }
// block_size returns the block size of the checksum in bytes. // block_size returns the block size of the checksum in bytes.
pub fn (d &Digest) block_size() int { pub fn (d &Digest) block_size() int {
return block_size return sha1.block_size
} }
// hexhash returns a hexadecimal SHA1 hash sum `string` of `s`. // hexhash returns a hexadecimal SHA1 hash sum `string` of `s`.

View File

@ -1,7 +1,6 @@
// Copyright (c) 2019-2021 Alexander Medvednikov. All rights reserved. // Copyright (c) 2019-2021 Alexander Medvednikov. All rights reserved.
// Use of this source code is governed by an MIT license // Use of this source code is governed by an MIT license
// that can be found in the LICENSE file. // that can be found in the LICENSE file.
import crypto.sha1 import crypto.sha1
fn test_crypto_sha1() { fn test_crypto_sha1() {

View File

@ -42,7 +42,7 @@ fn block_generic(mut dig Digest, p_ []byte) {
mut i := 0 mut i := 0
for i < 16 { for i < 16 {
f := b & c | (~b) & d f := b & c | (~b) & d
t := bits.rotate_left_32(a, 5) + f + e + w[i & 0xf] + u32(_k0) t := bits.rotate_left_32(a, 5) + f + e + w[i & 0xf] + u32(sha1._k0)
e = d e = d
d = c d = c
c = bits.rotate_left_32(b, 30) c = bits.rotate_left_32(b, 30)
@ -51,10 +51,10 @@ fn block_generic(mut dig Digest, p_ []byte) {
i++ i++
} }
for i < 20 { for i < 20 {
tmp := w[(i - 3) & 0xf] ^ w[(i - 8) & 0xf] ^ w[(i - 14) & 0xf] ^ w[(i) & 0xf] tmp := w[(i - 3) & 0xf] ^ w[(i - 8) & 0xf] ^ w[(i - 14) & 0xf] ^ w[i & 0xf]
w[i & 0xf] = (tmp << 1) | (tmp >> (32 - 1)) w[i & 0xf] = (tmp << 1) | (tmp >> (32 - 1))
f := b & c | (~b) & d f := b & c | (~b) & d
t := bits.rotate_left_32(a, 5) + f + e + w[i & 0xf] + u32(_k0) t := bits.rotate_left_32(a, 5) + f + e + w[i & 0xf] + u32(sha1._k0)
e = d e = d
d = c d = c
c = bits.rotate_left_32(b, 30) c = bits.rotate_left_32(b, 30)
@ -63,10 +63,10 @@ fn block_generic(mut dig Digest, p_ []byte) {
i++ i++
} }
for i < 40 { for i < 40 {
tmp := w[(i - 3) & 0xf] ^ w[(i - 8) & 0xf] ^ w[(i - 14) & 0xf] ^ w[(i) & 0xf] tmp := w[(i - 3) & 0xf] ^ w[(i - 8) & 0xf] ^ w[(i - 14) & 0xf] ^ w[i & 0xf]
w[i & 0xf] = (tmp << 1) | (tmp >> (32 - 1)) w[i & 0xf] = (tmp << 1) | (tmp >> (32 - 1))
f := b ^ c ^ d f := b ^ c ^ d
t := bits.rotate_left_32(a, 5) + f + e + w[i & 0xf] + u32(_k1) t := bits.rotate_left_32(a, 5) + f + e + w[i & 0xf] + u32(sha1._k1)
e = d e = d
d = c d = c
c = bits.rotate_left_32(b, 30) c = bits.rotate_left_32(b, 30)
@ -75,10 +75,10 @@ fn block_generic(mut dig Digest, p_ []byte) {
i++ i++
} }
for i < 60 { for i < 60 {
tmp := w[(i - 3) & 0xf] ^ w[(i - 8) & 0xf] ^ w[(i - 14) & 0xf] ^ w[(i) & 0xf] tmp := w[(i - 3) & 0xf] ^ w[(i - 8) & 0xf] ^ w[(i - 14) & 0xf] ^ w[i & 0xf]
w[i & 0xf] = (tmp << 1) | (tmp >> (32 - 1)) w[i & 0xf] = (tmp << 1) | (tmp >> (32 - 1))
f := ((b | c) & d) | (b & c) f := ((b | c) & d) | (b & c)
t := bits.rotate_left_32(a, 5) + f + e + w[i & 0xf] + u32(_k2) t := bits.rotate_left_32(a, 5) + f + e + w[i & 0xf] + u32(sha1._k2)
e = d e = d
d = c d = c
c = bits.rotate_left_32(b, 30) c = bits.rotate_left_32(b, 30)
@ -87,10 +87,10 @@ fn block_generic(mut dig Digest, p_ []byte) {
i++ i++
} }
for i < 80 { for i < 80 {
tmp := w[(i - 3) & 0xf] ^ w[(i - 8) & 0xf] ^ w[(i - 14) & 0xf] ^ w[(i) & 0xf] tmp := w[(i - 3) & 0xf] ^ w[(i - 8) & 0xf] ^ w[(i - 14) & 0xf] ^ w[i & 0xf]
w[i & 0xf] = (tmp << 1) | (tmp >> (32 - 1)) w[i & 0xf] = (tmp << 1) | (tmp >> (32 - 1))
f := b ^ c ^ d f := b ^ c ^ d
t := bits.rotate_left_32(a, 5) + f + e + w[i & 0xf] + u32(_k3) t := bits.rotate_left_32(a, 5) + f + e + w[i & 0xf] + u32(sha1._k3)
e = d e = d
d = c d = c
c = bits.rotate_left_32(b, 30) c = bits.rotate_left_32(b, 30)

View File

@ -50,25 +50,25 @@ mut:
fn (mut d Digest) reset() { fn (mut d Digest) reset() {
d.h = []u32{len: (8)} d.h = []u32{len: (8)}
d.x = []byte{len: (chunk)} d.x = []byte{len: sha256.chunk}
if !d.is224 { if !d.is224 {
d.h[0] = u32(init0) d.h[0] = u32(sha256.init0)
d.h[1] = u32(init1) d.h[1] = u32(sha256.init1)
d.h[2] = u32(init2) d.h[2] = u32(sha256.init2)
d.h[3] = u32(init3) d.h[3] = u32(sha256.init3)
d.h[4] = u32(init4) d.h[4] = u32(sha256.init4)
d.h[5] = u32(init5) d.h[5] = u32(sha256.init5)
d.h[6] = u32(init6) d.h[6] = u32(sha256.init6)
d.h[7] = u32(init7) d.h[7] = u32(sha256.init7)
} else { } else {
d.h[0] = u32(init0_224) d.h[0] = u32(sha256.init0_224)
d.h[1] = u32(init1_224) d.h[1] = u32(sha256.init1_224)
d.h[2] = u32(init2_224) d.h[2] = u32(sha256.init2_224)
d.h[3] = u32(init3_224) d.h[3] = u32(sha256.init3_224)
d.h[4] = u32(init4_224) d.h[4] = u32(sha256.init4_224)
d.h[5] = u32(init5_224) d.h[5] = u32(sha256.init5_224)
d.h[6] = u32(init6_224) d.h[6] = u32(sha256.init6_224)
d.h[7] = u32(init7_224) d.h[7] = u32(sha256.init7_224)
} }
d.nx = 0 d.nx = 0
d.len = 0 d.len = 0
@ -98,7 +98,7 @@ fn (mut d Digest) write(p_ []byte) ?int {
if d.nx > 0 { if d.nx > 0 {
n := copy(d.x[d.nx..], p) n := copy(d.x[d.nx..], p)
d.nx += n d.nx += n
if d.nx == chunk { if d.nx == sha256.chunk {
block(mut d, d.x) block(mut d, d.x)
d.nx = 0 d.nx = 0
} }
@ -108,8 +108,8 @@ fn (mut d Digest) write(p_ []byte) ?int {
p = p[n..] p = p[n..]
} }
} }
if p.len >= chunk { if p.len >= sha256.chunk {
n := p.len & ~(chunk - 1) n := p.len & ~(sha256.chunk - 1)
block(mut d, p[..n]) block(mut d, p[..n])
if n >= p.len { if n >= p.len {
p = [] p = []
@ -130,7 +130,7 @@ pub fn (d &Digest) sum(b_in []byte) []byte {
hash := d0.checksum() hash := d0.checksum()
mut b_out := b_in.clone() mut b_out := b_in.clone()
if d0.is224 { if d0.is224 {
for b in hash[..size224] { for b in hash[..sha256.size224] {
b_out << b b_out << b
} }
} else { } else {
@ -158,7 +158,7 @@ fn (mut d Digest) checksum() []byte {
if d.nx != 0 { if d.nx != 0 {
panic('d.nx != 0') panic('d.nx != 0')
} }
mut digest := []byte{len: (size)} mut digest := []byte{len: sha256.size}
binary.big_endian_put_u32(mut digest, d.h[0]) binary.big_endian_put_u32(mut digest, d.h[0])
binary.big_endian_put_u32(mut digest[4..], d.h[1]) binary.big_endian_put_u32(mut digest[4..], d.h[1])
binary.big_endian_put_u32(mut digest[8..], d.h[2]) binary.big_endian_put_u32(mut digest[8..], d.h[2])
@ -190,8 +190,8 @@ pub fn sum224(data []byte) []byte {
mut d := new224() mut d := new224()
d.write(data) or { panic(err) } d.write(data) or { panic(err) }
sum := d.checksum() sum := d.checksum()
sum224 := []byte{len: (size224)} sum224 := []byte{len: sha256.size224}
copy(sum224, sum[..size224]) copy(sum224, sum[..sha256.size224])
return sum224 return sum224
} }
@ -204,14 +204,14 @@ fn block(mut dig Digest, p []byte) {
// size returns the size of the checksum in bytes. // size returns the size of the checksum in bytes.
pub fn (d &Digest) size() int { pub fn (d &Digest) size() int {
if !d.is224 { if !d.is224 {
return size return sha256.size
} }
return size224 return sha256.size224
} }
// block_size returns the block size of the checksum in bytes. // block_size returns the block size of the checksum in bytes.
pub fn (d &Digest) block_size() int { pub fn (d &Digest) block_size() int {
return block_size return sha256.block_size
} }
// hexhash returns a hexadecimal SHA256 hash sum `string` of `s`. // hexhash returns a hexadecimal SHA256 hash sum `string` of `s`.

View File

@ -1,12 +1,10 @@
// Copyright (c) 2019-2021 Alexander Medvednikov. All rights reserved. // Copyright (c) 2019-2021 Alexander Medvednikov. All rights reserved.
// Use of this source code is governed by an MIT license // Use of this source code is governed by an MIT license
// that can be found in the LICENSE file. // that can be found in the LICENSE file.
import crypto.sha256 import crypto.sha256
fn test_crypto_sha256() { fn test_crypto_sha256() {
assert sha256.sum('This is a sha256 checksum.'.bytes()).hex() == assert sha256.sum('This is a sha256 checksum.'.bytes()).hex() == 'dc7163299659529eae29683eb1ffec50d6c8fc7275ecb10c145fde0e125b8727'
'dc7163299659529eae29683eb1ffec50d6c8fc7275ecb10c145fde0e125b8727'
} }
fn test_crypto_sha256_writer() { fn test_crypto_sha256_writer() {

View File

@ -115,9 +115,9 @@ fn block_generic(mut dig Digest, p_ []byte) {
for i in 0 .. 64 { for i in 0 .. 64 {
t1 := h + t1 := h +
((bits.rotate_left_32(e, -6)) ^ (bits.rotate_left_32(e, -11)) ^ (bits.rotate_left_32(e, -25))) + ((bits.rotate_left_32(e, -6)) ^ (bits.rotate_left_32(e, -11)) ^ (bits.rotate_left_32(e, -25))) +
((e & f) ^ (~e & g)) + u32(_k[i]) + w[i] ((e & f) ^ (~e & g)) + u32(sha256._k[i]) + w[i]
t2 := ((bits.rotate_left_32(a, -2)) ^ t2 :=
(bits.rotate_left_32(a, -13)) ^ (bits.rotate_left_32(a, -22))) + ((bits.rotate_left_32(a, -2)) ^ (bits.rotate_left_32(a, -13)) ^ (bits.rotate_left_32(a, -22))) +
((a & b) ^ (a & c) ^ (b & c)) ((a & b) ^ (a & c) ^ (b & c))
h = g h = g
g = f g = f

View File

@ -72,47 +72,47 @@ mut:
fn (mut d Digest) reset() { fn (mut d Digest) reset() {
d.h = []u64{len: (8)} d.h = []u64{len: (8)}
d.x = []byte{len: (chunk)} d.x = []byte{len: sha512.chunk}
match d.function { match d.function {
.sha384 { .sha384 {
d.h[0] = init0_384 d.h[0] = sha512.init0_384
d.h[1] = init1_384 d.h[1] = sha512.init1_384
d.h[2] = init2_384 d.h[2] = sha512.init2_384
d.h[3] = init3_384 d.h[3] = sha512.init3_384
d.h[4] = init4_384 d.h[4] = sha512.init4_384
d.h[5] = init5_384 d.h[5] = sha512.init5_384
d.h[6] = init6_384 d.h[6] = sha512.init6_384
d.h[7] = init7_384 d.h[7] = sha512.init7_384
} }
.sha512_224 { .sha512_224 {
d.h[0] = init0_224 d.h[0] = sha512.init0_224
d.h[1] = init1_224 d.h[1] = sha512.init1_224
d.h[2] = init2_224 d.h[2] = sha512.init2_224
d.h[3] = init3_224 d.h[3] = sha512.init3_224
d.h[4] = init4_224 d.h[4] = sha512.init4_224
d.h[5] = init5_224 d.h[5] = sha512.init5_224
d.h[6] = init6_224 d.h[6] = sha512.init6_224
d.h[7] = init7_224 d.h[7] = sha512.init7_224
} }
.sha512_256 { .sha512_256 {
d.h[0] = init0_256 d.h[0] = sha512.init0_256
d.h[1] = init1_256 d.h[1] = sha512.init1_256
d.h[2] = init2_256 d.h[2] = sha512.init2_256
d.h[3] = init3_256 d.h[3] = sha512.init3_256
d.h[4] = init4_256 d.h[4] = sha512.init4_256
d.h[5] = init5_256 d.h[5] = sha512.init5_256
d.h[6] = init6_256 d.h[6] = sha512.init6_256
d.h[7] = init7_256 d.h[7] = sha512.init7_256
} }
else { else {
d.h[0] = init0 d.h[0] = sha512.init0
d.h[1] = init1 d.h[1] = sha512.init1
d.h[2] = init2 d.h[2] = sha512.init2
d.h[3] = init3 d.h[3] = sha512.init3
d.h[4] = init4 d.h[4] = sha512.init4
d.h[5] = init5 d.h[5] = sha512.init5
d.h[6] = init6 d.h[6] = sha512.init6
d.h[7] = init7 d.h[7] = sha512.init7
} }
} }
d.nx = 0 d.nx = 0
@ -157,7 +157,7 @@ fn (mut d Digest) write(p_ []byte) ?int {
if d.nx > 0 { if d.nx > 0 {
n := copy(d.x[d.nx..], p) n := copy(d.x[d.nx..], p)
d.nx += n d.nx += n
if d.nx == chunk { if d.nx == sha512.chunk {
block(mut d, d.x) block(mut d, d.x)
d.nx = 0 d.nx = 0
} }
@ -167,8 +167,8 @@ fn (mut d Digest) write(p_ []byte) ?int {
p = p[n..] p = p[n..]
} }
} }
if p.len >= chunk { if p.len >= sha512.chunk {
n := p.len & ~(chunk - 1) n := p.len & ~(sha512.chunk - 1)
block(mut d, p[..n]) block(mut d, p[..n])
if n >= p.len { if n >= p.len {
p = [] p = []
@ -190,17 +190,17 @@ fn (d &Digest) sum(b_in []byte) []byte {
mut b_out := b_in.clone() mut b_out := b_in.clone()
match d0.function { match d0.function {
.sha384 { .sha384 {
for b in hash[..size384] { for b in hash[..sha512.size384] {
b_out << b b_out << b
} }
} }
.sha512_224 { .sha512_224 {
for b in hash[..size224] { for b in hash[..sha512.size224] {
b_out << b b_out << b
} }
} }
.sha512_256 { .sha512_256 {
for b in hash[..size256] { for b in hash[..sha512.size256] {
b_out << b b_out << b
} }
} }
@ -231,7 +231,7 @@ fn (mut d Digest) checksum() []byte {
if d.nx != 0 { if d.nx != 0 {
panic('d.nx != 0') panic('d.nx != 0')
} }
mut digest := []byte{len: (size)} mut digest := []byte{len: sha512.size}
binary.big_endian_put_u64(mut digest, d.h[0]) binary.big_endian_put_u64(mut digest, d.h[0])
binary.big_endian_put_u64(mut digest[8..], d.h[1]) binary.big_endian_put_u64(mut digest[8..], d.h[1])
binary.big_endian_put_u64(mut digest[16..], d.h[2]) binary.big_endian_put_u64(mut digest[16..], d.h[2])
@ -257,8 +257,8 @@ pub fn sum384(data []byte) []byte {
mut d := new_digest(.sha384) mut d := new_digest(.sha384)
d.write(data) or { panic(err) } d.write(data) or { panic(err) }
sum := d.checksum() sum := d.checksum()
sum384 := []byte{len: (size384)} sum384 := []byte{len: sha512.size384}
copy(sum384, sum[..size384]) copy(sum384, sum[..sha512.size384])
return sum384 return sum384
} }
@ -267,8 +267,8 @@ pub fn sum512_224(data []byte) []byte {
mut d := new_digest(.sha512_224) mut d := new_digest(.sha512_224)
d.write(data) or { panic(err) } d.write(data) or { panic(err) }
sum := d.checksum() sum := d.checksum()
sum224 := []byte{len: (size224)} sum224 := []byte{len: sha512.size224}
copy(sum224, sum[..size224]) copy(sum224, sum[..sha512.size224])
return sum224 return sum224
} }
@ -277,8 +277,8 @@ pub fn sum512_256(data []byte) []byte {
mut d := new_digest(.sha512_256) mut d := new_digest(.sha512_256)
d.write(data) or { panic(err) } d.write(data) or { panic(err) }
sum := d.checksum() sum := d.checksum()
sum256 := []byte{len: (size256)} sum256 := []byte{len: sha512.size256}
copy(sum256, sum[..size256]) copy(sum256, sum[..sha512.size256])
return sum256 return sum256
} }
@ -291,16 +291,16 @@ fn block(mut dig Digest, p []byte) {
// size returns the size of the checksum in bytes. // size returns the size of the checksum in bytes.
pub fn (d &Digest) size() int { pub fn (d &Digest) size() int {
match d.function { match d.function {
.sha512_224 { return size224 } .sha512_224 { return sha512.size224 }
.sha512_256 { return size256 } .sha512_256 { return sha512.size256 }
.sha384 { return size384 } .sha384 { return sha512.size384 }
else { return size } else { return sha512.size }
} }
} }
// block_size returns the block size of the checksum in bytes. // block_size returns the block size of the checksum in bytes.
pub fn (d &Digest) block_size() int { pub fn (d &Digest) block_size() int {
return block_size return sha512.block_size
} }
// hexhash returns a hexadecimal SHA512 hash sum `string` of `s`. // hexhash returns a hexadecimal SHA512 hash sum `string` of `s`.

View File

@ -55,7 +55,7 @@ pub fn encode_str(data string) string {
// alloc_and_encode is a private function that allocates and encodes data into a string // alloc_and_encode is a private function that allocates and encodes data into a string
// Used by encode and encode_str // Used by encode and encode_str
fn alloc_and_encode(src byteptr, len int) string { fn alloc_and_encode(src &byte, len int) string {
size := 4 * ((len + 2) / 3) size := 4 * ((len + 2) / 3)
if size <= 0 { if size <= 0 {
return '' return ''
@ -107,7 +107,7 @@ pub fn url_encode_str(data string) string {
// Please note: The `buffer` should be large enough (i.e. 3/4 of the data.len, or larger) // Please note: The `buffer` should be large enough (i.e. 3/4 of the data.len, or larger)
// to hold the decoded data. // to hold the decoded data.
// Please note: This function does NOT allocate new memory, and is thus suitable for handling very large strings. // Please note: This function does NOT allocate new memory, and is thus suitable for handling very large strings.
pub fn decode_in_buffer(data &string, buffer byteptr) int { pub fn decode_in_buffer(data &string, buffer &byte) int {
mut padding := 0 mut padding := 0
if data.ends_with('=') { if data.ends_with('=') {
if data.ends_with('==') { if data.ends_with('==') {
@ -125,8 +125,8 @@ pub fn decode_in_buffer(data &string, buffer byteptr) int {
mut b := &byte(0) mut b := &byte(0)
mut d := &byte(0) mut d := &byte(0)
unsafe { unsafe {
d = byteptr(data.str) d = &byte(data.str)
b = byteptr(buffer) b = &byte(buffer)
} }
for i < input_length { for i < input_length {
mut char_a := 0 mut char_a := 0
@ -165,7 +165,7 @@ pub fn decode_in_buffer(data &string, buffer byteptr) int {
// encode_in_buffer returns the size of the encoded data in the buffer. // encode_in_buffer returns the size of the encoded data in the buffer.
// Please note: The buffer should be large enough (i.e. 4/3 of the data.len, or larger) to hold the encoded data. // Please note: The buffer should be large enough (i.e. 4/3 of the data.len, or larger) to hold the encoded data.
// Please note: The function does NOT allocate new memory, and is suitable for handling very large strings. // Please note: The function does NOT allocate new memory, and is suitable for handling very large strings.
pub fn encode_in_buffer(data []byte, buffer byteptr) int { pub fn encode_in_buffer(data []byte, buffer &byte) int {
return encode_from_buffer(buffer, data.data, data.len) return encode_from_buffer(buffer, data.data, data.len)
} }
@ -173,16 +173,16 @@ pub fn encode_in_buffer(data []byte, buffer byteptr) int {
// and write the bytes into `dest`. // and write the bytes into `dest`.
// Please note: The `dest` buffer should be large enough (i.e. 4/3 of the src_len, or larger) to hold the encoded data. // Please note: The `dest` buffer should be large enough (i.e. 4/3 of the src_len, or larger) to hold the encoded data.
// Please note: This function is for internal base64 encoding // Please note: This function is for internal base64 encoding
fn encode_from_buffer(dest byteptr, src byteptr, src_len int) int { fn encode_from_buffer(dest &byte, src &byte, src_len int) int {
input_length := src_len input_length := src_len
output_length := 4 * ((input_length + 2) / 3) output_length := 4 * ((input_length + 2) / 3)
mut i := 0 mut i := 0
mut j := 0 mut j := 0
mut d := src mut d := unsafe { src }
mut b := dest mut b := unsafe { dest }
mut etable := byteptr(base64.enc_table.str) mut etable := base64.enc_table.str
for i < input_length { for i < input_length {
mut octet_a := 0 mut octet_a := 0
mut octet_b := 0 mut octet_b := 0

View File

@ -6,12 +6,11 @@ struct TestPair {
} }
const ( const (
pairs = [ pairs = [
// RFC 3548 examples // RFC 3548 examples
TestPair{'\x14\xfb\x9c\x03\xd9\x7e', 'FPucA9l+'}, TestPair{'\x14\xfb\x9c\x03\xd9\x7e', 'FPucA9l+'},
TestPair{'\x14\xfb\x9c\x03\xd9', 'FPucA9k='}, TestPair{'\x14\xfb\x9c\x03\xd9', 'FPucA9k='},
TestPair{'\x14\xfb\x9c\x03', 'FPucAw=='}, TestPair{'\x14\xfb\x9c\x03', 'FPucAw=='},
// RFC 4648 examples // RFC 4648 examples
TestPair{'', ''}, TestPair{'', ''},
TestPair{'f', 'Zg=='}, TestPair{'f', 'Zg=='},
@ -20,7 +19,6 @@ const (
TestPair{'foob', 'Zm9vYg=='}, TestPair{'foob', 'Zm9vYg=='},
TestPair{'fooba', 'Zm9vYmE='}, TestPair{'fooba', 'Zm9vYmE='},
TestPair{'foobar', 'Zm9vYmFy'}, TestPair{'foobar', 'Zm9vYmFy'},
// Wikipedia examples // Wikipedia examples
TestPair{'sure.', 'c3VyZS4='}, TestPair{'sure.', 'c3VyZS4='},
TestPair{'sure', 'c3VyZQ=='}, TestPair{'sure', 'c3VyZQ=='},
@ -32,11 +30,7 @@ const (
TestPair{'sure.', 'c3VyZS4='}, TestPair{'sure.', 'c3VyZS4='},
] ]
man_pair = TestPair{ man_pair = TestPair{'Man is distinguished, not only by his reason, but by this singular passion from other animals, which is a lust of the mind, that by a perseverance of delight in the continued and indefatigable generation of knowledge, exceeds the short vehemence of any carnal pleasure.', 'TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB0aGlzIHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlciBhbmltYWxzLCB3aGljaCBpcyBhIGx1c3Qgb2YgdGhlIG1pbmQsIHRoYXQgYnkgYSBwZXJzZXZlcmFuY2Ugb2YgZGVsaWdodCBpbiB0aGUgY29udGludWVkIGFuZCBpbmRlZmF0aWdhYmxlIGdlbmVyYXRpb24gb2Yga25vd2xlZGdlLCBleGNlZWRzIHRoZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm5hbCBwbGVhc3VyZS4='}
'Man is distinguished, not only by his reason, but by this singular passion from other animals, which is a lust of the mind, that by a perseverance of delight in the continued and indefatigable generation of knowledge, exceeds the short vehemence of any carnal pleasure.',
'TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB0aGlzIHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlciBhbmltYWxzLCB3aGljaCBpcyBhIGx1c3Qgb2YgdGhlIG1pbmQsIHRoYXQgYnkgYSBwZXJzZXZlcmFuY2Ugb2YgZGVsaWdodCBpbiB0aGUgY29udGludWVkIGFuZCBpbmRlZmF0aWdhYmxlIGdlbmVyYXRpb24gb2Yga25vd2xlZGdlLCBleGNlZWRzIHRoZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm5hbCBwbGVhc3VyZS4='
}
) )
fn test_decode() { fn test_decode() {
@ -50,7 +44,7 @@ fn test_decode() {
for i, p in pairs { for i, p in pairs {
got := base64.decode(p.encoded) got := base64.decode(p.encoded)
if got != p.decoded.bytes() { if got != p.decoded.bytes() {
eprintln('pairs[${i}]: expected = ${p.decoded}, got = ${got}') eprintln('pairs[$i]: expected = $p.decoded, got = $got')
assert false assert false
} }
} }
@ -67,7 +61,7 @@ fn test_decode_str() {
for i, p in pairs { for i, p in pairs {
got := base64.decode_str(p.encoded) got := base64.decode_str(p.encoded)
if got != p.decoded { if got != p.decoded {
eprintln('pairs[${i}]: expected = ${p.decoded}, got = ${got}') eprintln('pairs[$i]: expected = $p.decoded, got = $got')
assert false assert false
} }
} }
@ -79,7 +73,7 @@ fn test_encode() {
for i, p in pairs { for i, p in pairs {
got := base64.encode(p.decoded.bytes()) got := base64.encode(p.decoded.bytes())
if got != p.encoded { if got != p.encoded {
eprintln('pairs[${i}]: expected = ${p.encoded}, got = ${got}') eprintln('pairs[$i]: expected = $p.encoded, got = $got')
assert false assert false
} }
} }
@ -91,7 +85,7 @@ fn test_encode_str() {
for i, p in pairs { for i, p in pairs {
got := base64.encode_str(p.decoded) got := base64.encode_str(p.decoded)
if got != p.encoded { if got != p.encoded {
eprintln('pairs[${i}]: expected = ${p.encoded}, got = ${got}') eprintln('pairs[$i]: expected = $p.encoded, got = $got')
assert false assert false
} }
} }
@ -108,31 +102,31 @@ fn test_url_encode_str() {
} }
fn test_url_decode() { fn test_url_decode() {
test := base64.url_decode("SGVsbG8gQmFzZTY0VXJsIGVuY29kaW5nIQ") test := base64.url_decode('SGVsbG8gQmFzZTY0VXJsIGVuY29kaW5nIQ')
assert test == 'Hello Base64Url encoding!'.bytes() assert test == 'Hello Base64Url encoding!'.bytes()
} }
fn test_url_decode_str() { fn test_url_decode_str() {
test := base64.url_decode_str("SGVsbG8gQmFzZTY0VXJsIGVuY29kaW5nIQ") test := base64.url_decode_str('SGVsbG8gQmFzZTY0VXJsIGVuY29kaW5nIQ')
assert test == 'Hello Base64Url encoding!' assert test == 'Hello Base64Url encoding!'
} }
fn test_encode_null_byte() { fn test_encode_null_byte() {
assert base64.encode([byte(`A`) 0 `C`]) == 'QQBD' assert base64.encode([byte(`A`), 0, `C`]) == 'QQBD'
} }
fn test_encode_null_byte_str() { fn test_encode_null_byte_str() {
// While this works, bytestr() does a memcpy // While this works, bytestr() does a memcpy
s := [byte(`A`) 0 `C`].bytestr() s := [byte(`A`), 0, `C`].bytestr()
assert base64.encode_str(s) == 'QQBD' assert base64.encode_str(s) == 'QQBD'
} }
fn test_decode_null_byte() { fn test_decode_null_byte() {
assert base64.decode('QQBD') == [byte(`A`) 0 `C`] assert base64.decode('QQBD') == [byte(`A`), 0, `C`]
} }
fn test_decode_null_byte_str() { fn test_decode_null_byte_str() {
// While this works, bytestr() does a memcpy // While this works, bytestr() does a memcpy
s := [byte(`A`) 0 `C`].bytestr() s := [byte(`A`), 0, `C`].bytestr()
assert base64.decode_str('QQBD') == s assert base64.decode_str('QQBD') == s
} }

View File

@ -2,98 +2,99 @@
// Use of this source code is governed by an MIT license // Use of this source code is governed by an MIT license
// that can be found in the LICENSE file. // that can be found in the LICENSE file.
module binary module binary
// Little Endian // Little Endian
[inline] [inline]
pub fn little_endian_u16(b []byte) u16 { pub fn little_endian_u16(b []byte) u16 {
_ = b[1] // bounds check _ = b[1] // bounds check
return u16(b[0]) | (u16(b[1])<<u16(8)) return u16(b[0]) | (u16(b[1]) << u16(8))
} }
[inline] [inline]
pub fn little_endian_put_u16(mut b []byte, v u16) { pub fn little_endian_put_u16(mut b []byte, v u16) {
_ = b[1] // bounds check _ = b[1] // bounds check
b[0] = byte(v) b[0] = byte(v)
b[1] = byte(v>>u16(8)) b[1] = byte(v >> u16(8))
} }
[inline] [inline]
pub fn little_endian_u32(b []byte) u32 { pub fn little_endian_u32(b []byte) u32 {
_ = b[3] // bounds check _ = b[3] // bounds check
return u32(b[0]) | (u32(b[1])<<u32(8)) | (u32(b[2])<<u32(16)) | (u32(b[3])<<u32(24)) return u32(b[0]) | (u32(b[1]) << u32(8)) | (u32(b[2]) << u32(16)) | (u32(b[3]) << u32(24))
} }
[inline] [inline]
pub fn little_endian_put_u32(mut b []byte, v u32) { pub fn little_endian_put_u32(mut b []byte, v u32) {
_ = b[3] // bounds check _ = b[3] // bounds check
b[0] = byte(v) b[0] = byte(v)
b[1] = byte(v>>u32(8)) b[1] = byte(v >> u32(8))
b[2] = byte(v>>u32(16)) b[2] = byte(v >> u32(16))
b[3] = byte(v>>u32(24)) b[3] = byte(v >> u32(24))
} }
[inline] [inline]
pub fn little_endian_u64(b []byte) u64 { pub fn little_endian_u64(b []byte) u64 {
_ = b[7] // bounds check _ = b[7] // bounds check
return u64(b[0]) | (u64(b[1])<<u64(8)) | (u64(b[2])<<u64(16)) | (u64(b[3])<<u64(24)) | (u64(b[4])<<u64(32)) | (u64(b[5])<<u64(40)) | (u64(b[6])<<u64(48)) | (u64(b[7])<<u64(56)) return u64(b[0]) | (u64(b[1]) << u64(8)) | (u64(b[2]) << u64(16)) | (u64(b[3]) << u64(24)) | (u64(b[4]) << u64(32)) | (u64(b[5]) << u64(40)) | (u64(b[6]) << u64(48)) | (u64(b[7]) << u64(56))
} }
[inline] [inline]
pub fn little_endian_put_u64(mut b []byte, v u64) { pub fn little_endian_put_u64(mut b []byte, v u64) {
_ = b[7] // bounds check _ = b[7] // bounds check
b[0] = byte(v) b[0] = byte(v)
b[1] = byte(v>>u64(8)) b[1] = byte(v >> u64(8))
b[2] = byte(v>>u64(16)) b[2] = byte(v >> u64(16))
b[3] = byte(v>>u64(24)) b[3] = byte(v >> u64(24))
b[4] = byte(v>>u64(32)) b[4] = byte(v >> u64(32))
b[5] = byte(v>>u64(40)) b[5] = byte(v >> u64(40))
b[6] = byte(v>>u64(48)) b[6] = byte(v >> u64(48))
b[7] = byte(v>>u64(56)) b[7] = byte(v >> u64(56))
} }
// Big Endian // Big Endian
[inline] [inline]
pub fn big_endian_u16(b []byte) u16 { pub fn big_endian_u16(b []byte) u16 {
_ = b[1] // bounds check _ = b[1] // bounds check
return u16(b[1]) | (u16(b[0])<<u16(8)) return u16(b[1]) | (u16(b[0]) << u16(8))
} }
[inline] [inline]
pub fn big_endian_put_u16(mut b []byte, v u16) { pub fn big_endian_put_u16(mut b []byte, v u16) {
_ = b[1] // bounds check _ = b[1] // bounds check
b[0] = byte(v>>u16(8)) b[0] = byte(v >> u16(8))
b[1] = byte(v) b[1] = byte(v)
} }
[inline] [inline]
pub fn big_endian_u32(b []byte) u32 { pub fn big_endian_u32(b []byte) u32 {
_ = b[3] // bounds check _ = b[3] // bounds check
return u32(b[3]) | (u32(b[2])<<u32(8)) | (u32(b[1])<<u32(16)) | (u32(b[0])<<u32(24)) return u32(b[3]) | (u32(b[2]) << u32(8)) | (u32(b[1]) << u32(16)) | (u32(b[0]) << u32(24))
} }
[inline] [inline]
pub fn big_endian_put_u32(mut b []byte, v u32) { pub fn big_endian_put_u32(mut b []byte, v u32) {
_ = b[3] // bounds check _ = b[3] // bounds check
b[0] = byte(v>>u32(24)) b[0] = byte(v >> u32(24))
b[1] = byte(v>>u32(16)) b[1] = byte(v >> u32(16))
b[2] = byte(v>>u32(8)) b[2] = byte(v >> u32(8))
b[3] = byte(v) b[3] = byte(v)
} }
[inline] [inline]
pub fn big_endian_u64(b []byte) u64 { pub fn big_endian_u64(b []byte) u64 {
_ = b[7] // bounds check _ = b[7] // bounds check
return u64(b[7]) | (u64(b[6])<<u64(8))| (u64(b[5])<<u64(16)) | (u64(b[4])<<u64(24)) | (u64(b[3])<<u64(32)) | (u64(b[2])<<u64(40)) | (u64(b[1])<<u64(48)) | (u64(b[0])<<u64(56)) return u64(b[7]) | (u64(b[6]) << u64(8)) | (u64(b[5]) << u64(16)) | (u64(b[4]) << u64(24)) | (u64(b[3]) << u64(32)) | (u64(b[2]) << u64(40)) | (u64(b[1]) << u64(48)) | (u64(b[0]) << u64(56))
} }
[inline] [inline]
pub fn big_endian_put_u64(mut b []byte, v u64) { pub fn big_endian_put_u64(mut b []byte, v u64) {
_ = b[7] // bounds check _ = b[7] // bounds check
b[0] = byte(v>>u64(56)) b[0] = byte(v >> u64(56))
b[1] = byte(v>>u64(48)) b[1] = byte(v >> u64(48))
b[2] = byte(v>>u64(40)) b[2] = byte(v >> u64(40))
b[3] = byte(v>>u64(32)) b[3] = byte(v >> u64(32))
b[4] = byte(v>>u64(24)) b[4] = byte(v >> u64(24))
b[5] = byte(v>>u64(16)) b[5] = byte(v >> u64(16))
b[6] = byte(v>>u64(8)) b[6] = byte(v >> u64(8))
b[7] = byte(v) b[7] = byte(v)
} }

View File

@ -5,9 +5,7 @@ fn test_encoding_csv_reader() {
mut csv_reader := csv.new_reader(data) mut csv_reader := csv.new_reader(data)
mut row_count := 0 mut row_count := 0
for { for {
row := csv_reader.read() or { row := csv_reader.read() or { break }
break
}
row_count++ row_count++
if row_count == 1 { if row_count == 1 {
assert row[0] == 'name' assert row[0] == 'name'
@ -35,9 +33,7 @@ fn test_line_break_lf() {
mut csv_reader := csv.new_reader(lf_data) mut csv_reader := csv.new_reader(lf_data)
mut row_count := 0 mut row_count := 0
for { for {
row := csv_reader.read() or { row := csv_reader.read() or { break }
break
}
row_count++ row_count++
if row_count == 1 { if row_count == 1 {
assert row[0] == 'name' assert row[0] == 'name'
@ -55,9 +51,7 @@ fn test_line_break_cr() {
mut csv_reader := csv.new_reader(cr_data) mut csv_reader := csv.new_reader(cr_data)
mut row_count := 0 mut row_count := 0
for { for {
row := csv_reader.read() or { row := csv_reader.read() or { break }
break
}
row_count++ row_count++
if row_count == 1 { if row_count == 1 {
assert row[0] == 'name' assert row[0] == 'name'
@ -75,9 +69,7 @@ fn test_line_break_crlf() {
mut csv_reader := csv.new_reader(crlf_data) mut csv_reader := csv.new_reader(crlf_data)
mut row_count := 0 mut row_count := 0
for { for {
row := csv_reader.read() or { row := csv_reader.read() or { break }
break
}
row_count++ row_count++
if row_count == 1 { if row_count == 1 {
assert row[0] == 'name' assert row[0] == 'name'
@ -95,9 +87,7 @@ fn test_no_line_ending() {
mut csv_reader := csv.new_reader(data) mut csv_reader := csv.new_reader(data)
mut row_count := 0 mut row_count := 0
for { for {
csv_reader.read() or { csv_reader.read() or { break }
break
}
row_count++ row_count++
} }
assert row_count == 2 assert row_count == 2
@ -108,9 +98,7 @@ fn test_last_field_empty() {
mut csv_reader := csv.new_reader(data) mut csv_reader := csv.new_reader(data)
mut row_count := 0 mut row_count := 0
for { for {
row := csv_reader.read() or { row := csv_reader.read() or { break }
break
}
row_count++ row_count++
if row_count == 1 { if row_count == 1 {
assert row[0] == 'name' assert row[0] == 'name'
@ -133,9 +121,7 @@ fn test_empty_line() {
mut csv_reader := csv.new_reader(data) mut csv_reader := csv.new_reader(data)
mut row_count := 0 mut row_count := 0
for { for {
row := csv_reader.read() or { row := csv_reader.read() or { break }
break
}
row_count++ row_count++
if row_count == 1 { if row_count == 1 {
assert row[0] == 'name' assert row[0] == 'name'
@ -160,9 +146,7 @@ fn test_field_multiple_line() {
mut csv_reader := csv.new_reader(data) mut csv_reader := csv.new_reader(data)
mut row_count := 0 mut row_count := 0
for { for {
row := csv_reader.read() or { row := csv_reader.read() or { break }
break
}
row_count++ row_count++
if row_count == 1 { if row_count == 1 {
assert row[0] == 'name' assert row[0] == 'name'
@ -182,9 +166,7 @@ fn test_field_quotes_for_parts() {
mut csv_reader := csv.new_reader(data) mut csv_reader := csv.new_reader(data)
mut row_count := 0 mut row_count := 0
for { for {
row := csv_reader.read() or { row := csv_reader.read() or { break }
break
}
row_count++ row_count++
if row_count == 1 { if row_count == 1 {
assert row[0] == 'a1' assert row[0] == 'a1'

View File

@ -83,7 +83,7 @@ pub fn (mut s Subscriber) subscribe_method(name string, handler EventHandlerFn,
} }
} }
// unsubscribe_method unsubscribe a receiver for only one method // unsubscribe_method unsubscribe a receiver for only one method
pub fn (mut s Subscriber) unsubscribe_method(name string, receiver voidptr) { pub fn (mut s Subscriber) unsubscribe_method(name string, receiver voidptr) {
s.registry.events = s.registry.events.filter(!(it.name == name && it.receiver == receiver)) s.registry.events = s.registry.events.filter(!(it.name == name && it.receiver == receiver))
} }
@ -105,8 +105,6 @@ pub fn (s &Subscriber) is_subscribed(name string) bool {
return s.registry.check_subscriber(name) return s.registry.check_subscriber(name)
} }
// is_subscribed_method checks whether a receiver was already subscribed for any events // is_subscribed_method checks whether a receiver was already subscribed for any events
pub fn (s &Subscriber) is_subscribed_method(name string, receiver voidptr) bool { pub fn (s &Subscriber) is_subscribed_method(name string, receiver voidptr) bool {
return s.registry.events.any(it.name == name && it.receiver == receiver) return s.registry.events.any(it.name == name && it.receiver == receiver)

View File

@ -12,7 +12,7 @@ fn cmp(a f32, b f32) bool {
fn test_ortho() { fn test_ortho() {
projection := glm.ortho(0, 200, 400, 0) projection := glm.ortho(0, 200, 400, 0)
$if debug { $if debug {
println(unsafe {projection.data[0]}) println(unsafe { projection.data[0] })
} }
unsafe { unsafe {
assert cmp(projection.data[0], 0.01) assert cmp(projection.data[0], 0.01)
@ -73,7 +73,7 @@ fn test_rotate() {
m2 = glm.rotate(1, glm.vec3(0, 1, 0), m2) m2 = glm.rotate(1, glm.vec3(0, 1, 0), m2)
mut same := true mut same := true
for i in 0 .. 15 { for i in 0 .. 15 {
if unsafe {m1.data[i]} != unsafe {m2.data[i]} { if unsafe { m1.data[i] } != unsafe { m2.data[i] } {
same = false same = false
} }
} }
@ -150,6 +150,6 @@ fn test_mult1() {
b := glm.Mat4{bdata} b := glm.Mat4{bdata}
a = glm.mult(a, b) a = glm.mult(a, b)
for i in 0 .. 15 { for i in 0 .. 15 {
assert unsafe {a.data[i]} == unsafe {expected[i]} assert unsafe { a.data[i] } == unsafe { expected[i] }
} }
} }

View File

@ -1,92 +1,92 @@
module gx module gx
pub const ( pub const (
blue = Color{ blue = Color{
r: 0 r: 0
g: 0 g: 0
b: 255 b: 255
} }
red = Color{ red = Color{
r: 255 r: 255
g: 0 g: 0
b: 0 b: 0
} }
green = Color{ green = Color{
r: 0 r: 0
g: 255 g: 255
b: 0 b: 0
} }
yellow = Color{ yellow = Color{
r: 255 r: 255
g: 255 g: 255
b: 0 b: 0
} }
orange = Color{ orange = Color{
r: 255 r: 255
g: 165 g: 165
b: 0 b: 0
} }
purple = Color{ purple = Color{
r: 128 r: 128
g: 0 g: 0
b: 128 b: 128
} }
black = Color{ black = Color{
r: 0 r: 0
g: 0 g: 0
b: 0 b: 0
} }
gray = Color{ gray = Color{
r: 128 r: 128
g: 128 g: 128
b: 128 b: 128
} }
indigo = Color{ indigo = Color{
r: 75 r: 75
g: 0 g: 0
b: 130 b: 130
} }
pink = Color{ pink = Color{
r: 255 r: 255
g: 192 g: 192
b: 203 b: 203
} }
violet = Color{ violet = Color{
r: 238 r: 238
g: 130 g: 130
b: 238 b: 238
} }
white = Color{ white = Color{
r: 255 r: 255
g: 255 g: 255
b: 255 b: 255
} }
dark_blue = Color{ dark_blue = Color{
r: 0 r: 0
g: 0 g: 0
b: 139 b: 139
} }
dark_gray = Color{ dark_gray = Color{
r: 169 r: 169
g: 169 g: 169
b: 169 b: 169
} }
dark_green = Color{ dark_green = Color{
r: 0 r: 0
g: 100 g: 100
b: 0 b: 0
} }
dark_red = Color{ dark_red = Color{
r: 139 r: 139
g: 0 g: 0
b: 0 b: 0
} }
light_blue = Color{ light_blue = Color{
r: 173 r: 173
g: 216 g: 216
b: 230 b: 230
} }
light_gray = Color{ light_gray = Color{
r: 211 r: 211
g: 211 g: 211
b: 211 b: 211
@ -96,7 +96,7 @@ pub const (
g: 238 g: 238
b: 144 b: 144
} }
light_red = Color{ light_red = Color{
r: 255 r: 255
g: 204 g: 204
b: 203 b: 203
@ -118,7 +118,7 @@ pub fn hex(color int) Color {
r: byte((color >> 24) & 0xFF) r: byte((color >> 24) & 0xFF)
g: byte((color >> 16) & 0xFF) g: byte((color >> 16) & 0xFF)
b: byte((color >> 8) & 0xFF) b: byte((color >> 8) & 0xFF)
a: byte((color) & 0xFF) a: byte(color & 0xFF)
} }
} }
@ -197,7 +197,7 @@ pub fn (c Color) bgra8() int {
return (int(c.b) << 24) + (int(c.g) << 16) + (int(c.r) << 8) + int(c.a) return (int(c.b) << 24) + (int(c.g) << 16) + (int(c.r) << 8) + int(c.a)
} }
// abgr8 - convert a color value to an int in the ABGR8 order. // abgr8 - convert a color value to an int in the ABGR8 order.
// see https://developer.apple.com/documentation/coreimage/ciformat // see https://developer.apple.com/documentation/coreimage/ciformat
[inline] [inline]
pub fn (c Color) abgr8() int { pub fn (c Color) abgr8() int {
@ -205,7 +205,7 @@ pub fn (c Color) abgr8() int {
} }
const ( const (
string_colors = { string_colors = map{
'black': black 'black': black
'blue': blue 'blue': blue
'red': red 'red': red
@ -213,5 +213,5 @@ const (
) )
pub fn color_from_string(s string) Color { pub fn color_from_string(s string) Color {
return string_colors[s] return gx.string_colors[s]
} }

View File

@ -2,7 +2,7 @@ module gx
pub struct Image { pub struct Image {
mut: mut:
obj voidptr obj voidptr
pub: pub:
id int id int
width int width int

View File

@ -23,10 +23,10 @@ mut:
table []u32 table []u32
} }
fn(mut c Crc32) generate_table(poly int) { fn (mut c Crc32) generate_table(poly int) {
for i in 0..256 { for i in 0 .. 256 {
mut crc := u32(i) mut crc := u32(i)
for _ in 0..8 { for _ in 0 .. 8 {
if crc & u32(1) == u32(1) { if crc & u32(1) == u32(1) {
crc = (crc >> 1) ^ u32(poly) crc = (crc >> 1) ^ u32(poly)
} else { } else {
@ -37,15 +37,15 @@ fn(mut c Crc32) generate_table(poly int) {
} }
} }
fn(c &Crc32) sum32(b []byte) u32 { fn (c &Crc32) sum32(b []byte) u32 {
mut crc := ~u32(0) mut crc := ~u32(0)
for i in 0..b.len { for i in 0 .. b.len {
crc = c.table[byte(crc)^b[i]] ^ (crc >> 8) crc = c.table[byte(crc) ^ b[i]] ^ (crc >> 8)
} }
return ~crc return ~crc
} }
pub fn(c &Crc32) checksum(b []byte) u32 { pub fn (c &Crc32) checksum(b []byte) u32 {
return c.sum32(b) return c.sum32(b)
} }
@ -58,6 +58,6 @@ pub fn new(poly int) &Crc32 {
// calculate crc32 using ieee // calculate crc32 using ieee
pub fn sum(b []byte) u32 { pub fn sum(b []byte) u32 {
c := new(int(ieee)) c := new(int(crc32.ieee))
return c.sum32(b) return c.sum32(b)
} }

View File

@ -1,44 +1,44 @@
module fnv1a module fnv1a
const ( const (
fnv64_prime = u64(1099511628211) fnv64_prime = u64(1099511628211)
fnv64_offset_basis = u64(14695981039346656037) fnv64_offset_basis = u64(14695981039346656037)
fnv32_offset_basis = u32(2166136261) fnv32_offset_basis = u32(2166136261)
fnv32_prime = u32(16777619) fnv32_prime = u32(16777619)
) )
[inline] [inline]
pub fn sum32_string(data string) u32 { pub fn sum32_string(data string) u32 {
mut hash := fnv32_offset_basis mut hash := fnv1a.fnv32_offset_basis
for i in 0..data.len { for i in 0 .. data.len {
hash = (hash ^ u32(data[i])) * fnv32_prime hash = (hash ^ u32(data[i])) * fnv1a.fnv32_prime
} }
return hash return hash
} }
[inline] [inline]
pub fn sum32(data []byte) u32 { pub fn sum32(data []byte) u32 {
mut hash := fnv32_offset_basis mut hash := fnv1a.fnv32_offset_basis
for i in 0..data.len { for i in 0 .. data.len {
hash = (hash ^ u32(data[i])) * fnv32_prime hash = (hash ^ u32(data[i])) * fnv1a.fnv32_prime
} }
return hash return hash
} }
[inline] [inline]
pub fn sum64_string(data string) u64 { pub fn sum64_string(data string) u64 {
mut hash := fnv64_offset_basis mut hash := fnv1a.fnv64_offset_basis
for i in 0..data.len { for i in 0 .. data.len {
hash = (hash ^ u64(data[i])) * fnv64_prime hash = (hash ^ u64(data[i])) * fnv1a.fnv64_prime
} }
return hash return hash
} }
[inline] [inline]
pub fn sum64(data []byte) u64 { pub fn sum64(data []byte) u64 {
mut hash := fnv64_offset_basis mut hash := fnv1a.fnv64_offset_basis
for i in 0..data.len { for i in 0 .. data.len {
hash = (hash ^ u64(data[i])) * fnv64_prime hash = (hash ^ u64(data[i])) * fnv1a.fnv64_prime
} }
return hash return hash
} }

View File

@ -7,18 +7,10 @@ struct WyHashTest {
} }
fn test_wyhash() { fn test_wyhash() {
tests := [WyHashTest{ tests := [WyHashTest{'', 0, 0x0}, WyHashTest{'v', 1, 0xc72a8f8bdfdd82},
'',0,0x0}, WyHashTest{'is', 2, 0xa1099c1c58fc13e}, WyHashTest{'the best', 3, 0x1b1215ef0b0b94c},
WyHashTest{ WyHashTest{'abcdefghijklmnopqrstuvwxyz', 4, 0x6db0e773d1503fac},
'v',1,0xc72a8f8bdfdd82}, WyHashTest{'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789', 5, 0xe062dfda99413626},
WyHashTest{
'is',2,0xa1099c1c58fc13e},
WyHashTest{
'the best',3,0x1b1215ef0b0b94c},
WyHashTest{
'abcdefghijklmnopqrstuvwxyz',4,0x6db0e773d1503fac},
WyHashTest{
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789',5,0xe062dfda99413626},
] ]
for test in tests { for test in tests {
got := wyhash.sum64(test.s.bytes(), test.seed) got := wyhash.sum64(test.s.bytes(), test.seed)

View File

@ -2,11 +2,11 @@ module hash
//#flag -I @VEXEROOT/thirdparty/wyhash //#flag -I @VEXEROOT/thirdparty/wyhash
//#include "wyhash.h" //#include "wyhash.h"
fn C.wyhash(byteptr, u64, u64, &u64) u64 fn C.wyhash(&byte, u64, u64, &u64) u64
fn C.wyhash64(u64, u64) u64 fn C.wyhash64(u64, u64) u64
[inline] [inline]
pub fn wyhash_c(key byteptr, len u64, seed u64) u64 { pub fn wyhash_c(key &byte, len u64, seed u64) u64 {
return C.wyhash(key, len, seed, &u64(C._wyp)) return C.wyhash(key, len, seed, &u64(C._wyp))
} }

View File

@ -30,39 +30,46 @@ pub fn sum64_string(key string, seed u64) u64 {
[inline] [inline]
pub fn sum64(key []byte, seed u64) u64 { pub fn sum64(key []byte, seed u64) u64 {
return wyhash64(byteptr(key.data), u64(key.len), seed) return wyhash64(&byte(key.data), u64(key.len), seed)
} }
[inline] [inline]
fn wyhash64(key byteptr, len u64, seed_ u64) u64 { fn wyhash64(key &byte, len u64, seed_ u64) u64 {
if len == 0 { if len == 0 {
return 0 return 0
} }
mut p := key mut p := unsafe { key }
mut seed := seed_ mut seed := seed_
mut i := len & 63 mut i := len & 63
seed = unsafe{match i { seed = unsafe {
0...3 { match i {
wymum(wyr3(p, i) ^ seed ^ wyp0, seed ^ wyp1) 0...3 {
wymum(wyr3(p, i) ^ seed ^ hash.wyp0, seed ^ hash.wyp1)
}
4...8 {
wymum(wyr4(p) ^ seed ^ hash.wyp0, wyr4(p + i - 4) ^ seed ^ hash.wyp1)
}
9...16 {
wymum(wyr8(p) ^ seed ^ hash.wyp0, wyr8(p + i - 8) ^ seed ^ hash.wyp1)
}
17...24 {
wymum(wyr8(p) ^ seed ^ hash.wyp0, wyr8(p + 8) ^ seed ^ hash.wyp1) ^ wymum(wyr8(p + i - 8) ^ seed ^ hash.wyp2,
seed ^ hash.wyp3)
}
25...32 {
wymum(wyr8(p) ^ seed ^ hash.wyp0, wyr8(p + 8) ^ seed ^ hash.wyp1) ^ wymum(wyr8(p +
16) ^ seed ^ hash.wyp2, wyr8(p + i - 8) ^ seed ^ hash.wyp3)
}
else {
wymum(wyr8(p) ^ seed ^ hash.wyp0, wyr8(p + 8) ^ seed ^ hash.wyp1) ^ wymum(wyr8(p +
16) ^ seed ^ hash.wyp2, wyr8(p + 24) ^ seed ^ hash.wyp3) ^ wymum(wyr8(p + i - 32) ^ seed ^ hash.wyp1,
wyr8(p + i - 24) ^ seed ^ hash.wyp2) ^ wymum(wyr8(p + i - 16) ^ seed ^ hash.wyp3,
wyr8(p + i - 8) ^ seed ^ hash.wyp0)
}
} }
4...8 { }
wymum(wyr4(p) ^ seed ^ wyp0, wyr4(p + i - 4) ^ seed ^ wyp1)
}
9...16 {
wymum(wyr8(p) ^ seed ^ wyp0, wyr8(p + i - 8) ^ seed ^ wyp1)
}
17...24 {
wymum(wyr8(p) ^ seed ^ wyp0, wyr8(p + 8) ^ seed ^ wyp1) ^ wymum(wyr8(p + i - 8) ^ seed ^ wyp2, seed ^ wyp3)
}
25...32 {
wymum(wyr8(p) ^ seed ^ wyp0, wyr8(p + 8) ^ seed ^ wyp1) ^ wymum(wyr8(p + 16) ^ seed ^ wyp2, wyr8(p + i - 8) ^ seed ^ wyp3)
}
else {
wymum(wyr8(p) ^ seed ^ wyp0, wyr8(p + 8) ^ seed ^ wyp1) ^ wymum(wyr8(p + 16) ^ seed ^ wyp2, wyr8(p + 24) ^ seed ^ wyp3) ^ wymum(wyr8(p + i - 32) ^ seed ^ wyp1, wyr8(p + i - 24) ^ seed ^ wyp2) ^ wymum(wyr8(p + i - 16) ^ seed ^ wyp3, wyr8(p + i - 8) ^ seed ^ wyp0)
}
}}
if i == len { if i == len {
return wymum(seed, len ^ wyp4) return wymum(seed, len ^ hash.wyp4)
} }
mut see1 := seed mut see1 := seed
mut see2 := seed mut see2 := seed
@ -70,19 +77,19 @@ fn wyhash64(key byteptr, len u64, seed_ u64) u64 {
unsafe { unsafe {
p = p + i p = p + i
for i = len - i; i >= 64; i -= 64 { for i = len - i; i >= 64; i -= 64 {
seed = wymum(wyr8(p) ^ seed ^ wyp0, wyr8(p + 8) ^ seed ^ wyp1) seed = wymum(wyr8(p) ^ seed ^ hash.wyp0, wyr8(p + 8) ^ seed ^ hash.wyp1)
see1 = wymum(wyr8(p + 16) ^ see1 ^ wyp2, wyr8(p + 24) ^ see1 ^ wyp3) see1 = wymum(wyr8(p + 16) ^ see1 ^ hash.wyp2, wyr8(p + 24) ^ see1 ^ hash.wyp3)
see2 = wymum(wyr8(p + 32) ^ see2 ^ wyp1, wyr8(p + 40) ^ see2 ^ wyp2) see2 = wymum(wyr8(p + 32) ^ see2 ^ hash.wyp1, wyr8(p + 40) ^ see2 ^ hash.wyp2)
see3 = wymum(wyr8(p + 48) ^ see3 ^ wyp3, wyr8(p + 56) ^ see3 ^ wyp0) see3 = wymum(wyr8(p + 48) ^ see3 ^ hash.wyp3, wyr8(p + 56) ^ see3 ^ hash.wyp0)
p = p + 64 p = p + 64
} }
} }
return wymum(seed ^ see1 ^ see2, see3 ^ len ^ wyp4) return wymum(seed ^ see1 ^ see2, see3 ^ len ^ hash.wyp4)
} }
[inline] [inline]
fn wyrotr(v u64, k u32) u64 { fn wyrotr(v u64, k u32) u64 {
return (v>>k) | (v<<(64 - k)) return (v >> k) | (v << (64 - k))
} }
[inline] [inline]
@ -94,36 +101,36 @@ pub fn wymum(a u64, b u64) u64 {
*/ */
mask32 := u32(4294967295) mask32 := u32(4294967295)
x0 := a & mask32 x0 := a & mask32
x1 := a>>32 x1 := a >> 32
y0 := b & mask32 y0 := b & mask32
y1 := b>>32 y1 := b >> 32
w0 := x0 * y0 w0 := x0 * y0
t := x1 * y0 + (w0>>32) t := x1 * y0 + (w0 >> 32)
mut w1 := t & mask32 mut w1 := t & mask32
w2 := t>>32 w2 := t >> 32
w1 += x0 * y1 w1 += x0 * y1
hi := x1 * y1 + w2 + (w1>>32) hi := x1 * y1 + w2 + (w1 >> 32)
lo := a * b lo := a * b
return hi ^ lo return hi ^ lo
} }
[inline] [inline]
fn wyr3(p byteptr, k u64) u64 { fn wyr3(p &byte, k u64) u64 {
unsafe { unsafe {
return (u64(p[0])<<16) | (u64(p[k>>1])<<8) | u64(p[k - 1]) return (u64(p[0]) << 16) | (u64(p[k >> 1]) << 8) | u64(p[k - 1])
} }
} }
[inline] [inline]
fn wyr4(p byteptr) u64 { fn wyr4(p &byte) u64 {
unsafe { unsafe {
return u32(p[0]) | (u32(p[1])<<u32(8)) | (u32(p[2])<<u32(16)) | (u32(p[3])<<u32(24)) return u32(p[0]) | (u32(p[1]) << u32(8)) | (u32(p[2]) << u32(16)) | (u32(p[3]) << u32(24))
} }
} }
[inline] [inline]
fn wyr8(p byteptr) u64 { fn wyr8(p &byte) u64 {
unsafe { unsafe {
return u64(p[0]) | (u64(p[1])<<8) | (u64(p[2])<<16) | (u64(p[3])<<24) | (u64(p[4])<<32) | (u64(p[5])<<40) | (u64(p[6])<<48) | (u64(p[7])<<56) return u64(p[0]) | (u64(p[1]) << 8) | (u64(p[2]) << 16) | (u64(p[3]) << 24) | (u64(p[4]) << 32) | (u64(p[5]) << 40) | (u64(p[6]) << 48) | (u64(p[7]) << 56)
} }
} }

View File

@ -5,12 +5,10 @@ const (
) )
pub fn cp(dst Writer, src Reader) ? { pub fn cp(dst Writer, src Reader) ? {
mut buf := []byte{len: buf_max_len} mut buf := []byte{len: io.buf_max_len}
for { for {
len := src.read(mut buf) or { break } len := src.read(mut buf) or { break }
dst.write(buf[..len]) or { dst.write(buf[..len]) or { return err }
return err
}
} }
unsafe { unsafe {
buf.free() buf.free()

View File

@ -36,8 +36,6 @@ fn test_copy() {
dst := Writ{ dst := Writ{
bytes: []byte{} bytes: []byte{}
} }
io.cp(dst, src) or { io.cp(dst, src) or { assert false }
assert false
}
assert dst.bytes == src.bytes assert dst.bytes == src.bytes
} }

View File

@ -10,7 +10,7 @@ const (
fn testsuite_begin() { fn testsuite_begin() {
eprintln('testsuite_begin, tfolder = $tfolder') eprintln('testsuite_begin, tfolder = $tfolder')
os.rmdir_all(tfolder) or { } os.rmdir_all(tfolder) or {}
assert !os.is_dir(tfolder) assert !os.is_dir(tfolder)
os.mkdir_all(tfolder) or { panic(err) } os.mkdir_all(tfolder) or { panic(err) }
os.chdir(tfolder) os.chdir(tfolder)
@ -19,7 +19,7 @@ fn testsuite_begin() {
fn testsuite_end() { fn testsuite_end() {
os.chdir(os.wd_at_startup) os.chdir(os.wd_at_startup)
os.rmdir_all(tfolder) or { } os.rmdir_all(tfolder) or {}
assert !os.is_dir(tfolder) assert !os.is_dir(tfolder)
// eprintln('testsuite_end , tfolder = $tfolder removed.') // eprintln('testsuite_end , tfolder = $tfolder removed.')
} }

View File

@ -56,7 +56,7 @@ struct User {
last_name string [json: lastName] last_name string [json: lastName]
is_registered bool [json: IsRegistered] is_registered bool [json: IsRegistered]
typ int [json: 'type'] typ int [json: 'type']
pets string [raw; json: 'pet_animals'] pets string [json: 'pet_animals'; raw]
} }
fn test_parse_user() { fn test_parse_user() {
@ -271,7 +271,7 @@ fn test_nested_type() {
} }
} }
struct Foo <T> { struct Foo<T> {
pub: pub:
name string name string
data T data T

View File

@ -4,25 +4,26 @@
module math module math
const ( const (
uvnan = u64(0x7FF8000000000001) uvnan = u64(0x7FF8000000000001)
uvinf = u64(0x7FF0000000000000) uvinf = u64(0x7FF0000000000000)
uvneginf = u64(0xFFF0000000000000) uvneginf = u64(0xFFF0000000000000)
uvone = u64(0x3FF0000000000000) uvone = u64(0x3FF0000000000000)
mask = 0x7FF mask = 0x7FF
shift = 64 - 11 - 1 shift = 64 - 11 - 1
bias = 1023 bias = 1023
sign_mask = (u64(1)<<63) sign_mask = (u64(1) << 63)
frac_mask = ((u64(1)<<u64(shift)) - u64(1)) frac_mask = ((u64(1) << u64(shift)) - u64(1))
) )
// inf returns positive infinity if sign >= 0, negative infinity if sign < 0. // inf returns positive infinity if sign >= 0, negative infinity if sign < 0.
pub fn inf(sign int) f64 { pub fn inf(sign int) f64 {
v := if sign >= 0 { uvinf } else { uvneginf } v := if sign >= 0 { math.uvinf } else { math.uvneginf }
return f64_from_bits(v) return f64_from_bits(v)
} }
// nan returns an IEEE 754 ``not-a-number'' value. // nan returns an IEEE 754 ``not-a-number'' value.
pub fn nan() f64 { pub fn nan() f64 {
return f64_from_bits(uvnan) return f64_from_bits(math.uvnan)
} }
// is_nan reports whether f is an IEEE 754 ``not-a-number'' value. // is_nan reports whether f is an IEEE 754 ``not-a-number'' value.

View File

@ -4,72 +4,76 @@
module bits module bits
const ( const (
ntz_8_tab = [byte(0x08), 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, ntz_8_tab = [byte(0x08), 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00,
0x04, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01,
0x05, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x05, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00,
0x04, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03,
0x06, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x06, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00,
0x04, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01,
0x05, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x05, 0x00, 0x01, 0x00, 0x02, 0x00,
0x04, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x02,
0x07, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x07, 0x00, 0x01, 0x00,
0x04, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x04, 0x00, 0x01,
0x05, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x05, 0x00,
0x04, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x04,
0x06, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00,
0x04, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x06, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01,
0x05, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x04, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00,
0x04, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0x00, 0x05, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02,
] 0x00, 0x01, 0x00, 0x04, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00,
pop_8_tab = [byte(0x00), 0x01, 0x01, 0x02, 0x01, 0x02, 0x02, 0x03, 0x01, 0x02, 0x02, 0x03, 0x02, 0x03, 0x03, 0x04, 0x02, 0x00, 0x01, 0x00]
0x01, 0x02, 0x02, 0x03, 0x02, 0x03, 0x03, 0x04, 0x02, 0x03, 0x03, 0x04, 0x03, 0x04, 0x04, 0x05, pop_8_tab = [byte(0x00), 0x01, 0x01, 0x02, 0x01, 0x02, 0x02, 0x03, 0x01, 0x02, 0x02, 0x03,
0x01, 0x02, 0x02, 0x03, 0x02, 0x03, 0x03, 0x04, 0x02, 0x03, 0x03, 0x04, 0x03, 0x04, 0x04, 0x05, 0x02, 0x03, 0x03, 0x04, 0x01, 0x02, 0x02, 0x03, 0x02, 0x03, 0x03, 0x04, 0x02, 0x03, 0x03,
0x02, 0x03, 0x03, 0x04, 0x03, 0x04, 0x04, 0x05, 0x03, 0x04, 0x04, 0x05, 0x04, 0x05, 0x05, 0x06, 0x04, 0x03, 0x04, 0x04, 0x05, 0x01, 0x02, 0x02, 0x03, 0x02, 0x03, 0x03, 0x04, 0x02, 0x03,
0x01, 0x02, 0x02, 0x03, 0x02, 0x03, 0x03, 0x04, 0x02, 0x03, 0x03, 0x04, 0x03, 0x04, 0x04, 0x05, 0x03, 0x04, 0x03, 0x04, 0x04, 0x05, 0x02, 0x03, 0x03, 0x04, 0x03, 0x04, 0x04, 0x05, 0x03,
0x02, 0x03, 0x03, 0x04, 0x03, 0x04, 0x04, 0x05, 0x03, 0x04, 0x04, 0x05, 0x04, 0x05, 0x05, 0x06, 0x04, 0x04, 0x05, 0x04, 0x05, 0x05, 0x06, 0x01, 0x02, 0x02, 0x03, 0x02, 0x03, 0x03, 0x04,
0x02, 0x03, 0x03, 0x04, 0x03, 0x04, 0x04, 0x05, 0x03, 0x04, 0x04, 0x05, 0x04, 0x05, 0x05, 0x06, 0x02, 0x03, 0x03, 0x04, 0x03, 0x04, 0x04, 0x05, 0x02, 0x03, 0x03, 0x04, 0x03, 0x04, 0x04,
0x03, 0x04, 0x04, 0x05, 0x04, 0x05, 0x05, 0x06, 0x04, 0x05, 0x05, 0x06, 0x05, 0x06, 0x06, 0x07, 0x05, 0x03, 0x04, 0x04, 0x05, 0x04, 0x05, 0x05, 0x06, 0x02, 0x03, 0x03, 0x04, 0x03, 0x04,
0x01, 0x02, 0x02, 0x03, 0x02, 0x03, 0x03, 0x04, 0x02, 0x03, 0x03, 0x04, 0x03, 0x04, 0x04, 0x05, 0x04, 0x05, 0x03, 0x04, 0x04, 0x05, 0x04, 0x05, 0x05, 0x06, 0x03, 0x04, 0x04, 0x05, 0x04,
0x02, 0x03, 0x03, 0x04, 0x03, 0x04, 0x04, 0x05, 0x03, 0x04, 0x04, 0x05, 0x04, 0x05, 0x05, 0x06, 0x05, 0x05, 0x06, 0x04, 0x05, 0x05, 0x06, 0x05, 0x06, 0x06, 0x07, 0x01, 0x02, 0x02, 0x03,
0x02, 0x03, 0x03, 0x04, 0x03, 0x04, 0x04, 0x05, 0x03, 0x04, 0x04, 0x05, 0x04, 0x05, 0x05, 0x06, 0x02, 0x03, 0x03, 0x04, 0x02, 0x03, 0x03, 0x04, 0x03, 0x04, 0x04, 0x05, 0x02, 0x03, 0x03,
0x03, 0x04, 0x04, 0x05, 0x04, 0x05, 0x05, 0x06, 0x04, 0x05, 0x05, 0x06, 0x05, 0x06, 0x06, 0x07, 0x04, 0x03, 0x04, 0x04, 0x05, 0x03, 0x04, 0x04, 0x05, 0x04, 0x05, 0x05, 0x06, 0x02, 0x03,
0x02, 0x03, 0x03, 0x04, 0x03, 0x04, 0x04, 0x05, 0x03, 0x04, 0x04, 0x05, 0x04, 0x05, 0x05, 0x06, 0x03, 0x04, 0x03, 0x04, 0x04, 0x05, 0x03, 0x04, 0x04, 0x05, 0x04, 0x05, 0x05, 0x06, 0x03,
0x03, 0x04, 0x04, 0x05, 0x04, 0x05, 0x05, 0x06, 0x04, 0x05, 0x05, 0x06, 0x05, 0x06, 0x06, 0x07, 0x04, 0x04, 0x05, 0x04, 0x05, 0x05, 0x06, 0x04, 0x05, 0x05, 0x06, 0x05, 0x06, 0x06, 0x07,
0x03, 0x04, 0x04, 0x05, 0x04, 0x05, 0x05, 0x06, 0x04, 0x05, 0x05, 0x06, 0x05, 0x06, 0x06, 0x07, 0x02, 0x03, 0x03, 0x04, 0x03, 0x04, 0x04, 0x05, 0x03, 0x04, 0x04, 0x05, 0x04, 0x05, 0x05,
0x04, 0x05, 0x05, 0x06, 0x05, 0x06, 0x06, 0x07, 0x05, 0x06, 0x06, 0x07, 0x06, 0x07, 0x07, 0x08, 0x06, 0x03, 0x04, 0x04, 0x05, 0x04, 0x05, 0x05, 0x06, 0x04, 0x05, 0x05, 0x06, 0x05, 0x06,
] 0x06, 0x07, 0x03, 0x04, 0x04, 0x05, 0x04, 0x05, 0x05, 0x06, 0x04, 0x05, 0x05, 0x06, 0x05,
rev_8_tab = [byte(0x00), 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0, 0x06, 0x06, 0x07, 0x04, 0x05, 0x05, 0x06, 0x05, 0x06, 0x06, 0x07, 0x05, 0x06, 0x06, 0x07,
0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8, 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8, 0x06, 0x07, 0x07, 0x08]
0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4, 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4, rev_8_tab = [byte(0x00), 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, 0x10, 0x90, 0x50, 0xd0,
0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec, 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc, 0x30, 0xb0, 0x70, 0xf0, 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8, 0x18, 0x98, 0x58,
0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2, 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2, 0xd8, 0x38, 0xb8, 0x78, 0xf8, 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4, 0x14, 0x94,
0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea, 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4, 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec, 0x1c,
0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6, 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc, 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee, 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe, 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2, 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a,
0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1, 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1, 0xea, 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa, 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6,
0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9, 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9, 0x66, 0xe6, 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6, 0x0e, 0x8e, 0x4e, 0xce, 0x2e,
0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5, 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5, 0xae, 0x6e, 0xee, 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe, 0x01, 0x81, 0x41, 0xc1,
0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed, 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd, 0x21, 0xa1, 0x61, 0xe1, 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1, 0x09, 0x89, 0x49,
0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3, 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3, 0xc9, 0x29, 0xa9, 0x69, 0xe9, 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9, 0x05, 0x85,
0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb, 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5, 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5, 0x0d,
0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7, 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed, 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef, 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff, 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3, 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73,
] 0xf3, 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb, 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb,
len_8_tab = [byte(0x00), 0x01, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x7b, 0xfb, 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7, 0x17, 0x97, 0x57, 0xd7, 0x37,
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0xb7, 0x77, 0xf7, 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef, 0x1f, 0x9f, 0x5f, 0xdf,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x3f, 0xbf, 0x7f, 0xff]
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, len_8_tab = [byte(0x00), 0x01, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04,
0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x04, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x05, 0x05, 0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x08, 0x08, 0x08, 0x08,
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
] 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
0x08, 0x08, 0x08, 0x08]
) )

View File

@ -3,9 +3,9 @@
// //
module bits module bits
fn test_bits(){ fn test_bits() {
mut i := 0 mut i := 0
mut i1:= u64(0) mut i1 := u64(0)
// //
// --- LeadingZeros --- // --- LeadingZeros ---
@ -13,29 +13,29 @@ fn test_bits(){
// 8 bit // 8 bit
i = 1 i = 1
for x in 0..8 { for x in 0 .. 8 {
//C.printf("x:%02x lz: %d cmp: %d\n", i << x, leading_zeros_8(i << x), 7-x) // C.printf("x:%02x lz: %d cmp: %d\n", i << x, leading_zeros_8(i << x), 7-x)
assert leading_zeros_8(byte(i << x)) == 7 - x assert leading_zeros_8(byte(i << x)) == 7 - x
} }
// 16 bit // 16 bit
i = 1 i = 1
for x in 0..16 { for x in 0 .. 16 {
//C.printf("x:%04x lz: %d cmp: %d\n", u16(i) << x, leading_zeros_16(u16(i) << x), 15-x) // C.printf("x:%04x lz: %d cmp: %d\n", u16(i) << x, leading_zeros_16(u16(i) << x), 15-x)
assert leading_zeros_16(u16(i) << x) == 15 - x assert leading_zeros_16(u16(i) << x) == 15 - x
} }
// 32 bit // 32 bit
i = 1 i = 1
for x in 0..32 { for x in 0 .. 32 {
//C.printf("x:%08x lz: %d cmp: %d\n", u32(i) << x, leading_zeros_32(u32(i) << x), 31-x) // C.printf("x:%08x lz: %d cmp: %d\n", u32(i) << x, leading_zeros_32(u32(i) << x), 31-x)
assert leading_zeros_32(u32(i) << x) == 31 - x assert leading_zeros_32(u32(i) << x) == 31 - x
} }
// 64 bit // 64 bit
i = 1 i = 1
for x in 0..64 { for x in 0 .. 64 {
//C.printf("x:%016llx lz: %llu cmp: %d\n", u64(i) << x, leading_zeros_64(u64(i) << x), 63-x) // C.printf("x:%016llx lz: %llu cmp: %d\n", u64(i) << x, leading_zeros_64(u64(i) << x), 63-x)
assert leading_zeros_64(u64(i) << x) == 63 - x assert leading_zeros_64(u64(i) << x) == 63 - x
} }
@ -45,32 +45,32 @@ fn test_bits(){
// 8 bit // 8 bit
i = 0 i = 0
for x in 0..9 { for x in 0 .. 9 {
//C.printf("x:%02x lz: %llu cmp: %d\n", byte(i), ones_count_8(byte(i)), x) // C.printf("x:%02x lz: %llu cmp: %d\n", byte(i), ones_count_8(byte(i)), x)
assert ones_count_8(byte(i)) == x assert ones_count_8(byte(i)) == x
i = (i << 1) + 1 i = (i << 1) + 1
} }
// 16 bit // 16 bit
i = 0 i = 0
for x in 0..17 { for x in 0 .. 17 {
//C.printf("x:%04x lz: %llu cmp: %d\n", u16(i), ones_count_16(u16(i)), x) // C.printf("x:%04x lz: %llu cmp: %d\n", u16(i), ones_count_16(u16(i)), x)
assert ones_count_16(u16(i)) == x assert ones_count_16(u16(i)) == x
i = (i << 1) + 1 i = (i << 1) + 1
} }
// 32 bit // 32 bit
i = 0 i = 0
for x in 0..33 { for x in 0 .. 33 {
//C.printf("x:%08x lz: %llu cmp: %d\n", u32(i), ones_count_32(u32(i)), x) // C.printf("x:%08x lz: %llu cmp: %d\n", u32(i), ones_count_32(u32(i)), x)
assert ones_count_32(u32(i)) == x assert ones_count_32(u32(i)) == x
i = (i << 1) + 1 i = (i << 1) + 1
} }
// 64 bit // 64 bit
i1 = 0 i1 = 0
for x in 0..65 { for x in 0 .. 65 {
//C.printf("x:%016llx lz: %llu cmp: %d\n", u64(i1), ones_count_64(u64(i1)), x) // C.printf("x:%016llx lz: %llu cmp: %d\n", u64(i1), ones_count_64(u64(i1)), x)
assert ones_count_64(i1) == x assert ones_count_64(i1) == x
i1 = (i1 << 1) + 1 i1 = (i1 << 1) + 1
} }
@ -78,10 +78,10 @@ fn test_bits(){
// //
// --- rotate_left/right --- // --- rotate_left/right ---
// //
assert rotate_left_8( 0x12 , 4) == 0x21 assert rotate_left_8(0x12, 4) == 0x21
assert rotate_left_16( 0x1234 , 8) == 0x3412 assert rotate_left_16(0x1234, 8) == 0x3412
assert rotate_left_32( 0x12345678 , 16) == 0x56781234 assert rotate_left_32(0x12345678, 16) == 0x56781234
assert rotate_left_64( 0x1234567887654321 , 32) == 0x8765432112345678 assert rotate_left_64(0x1234567887654321, 32) == 0x8765432112345678
// //
// --- reverse --- // --- reverse ---
@ -89,7 +89,7 @@ fn test_bits(){
// 8 bit // 8 bit
i = 0 i = 0
for _ in 0..9 { for _ in 0 .. 9 {
mut rv := byte(0) mut rv := byte(0)
mut bc := 0 mut bc := 0
mut n := i mut n := i
@ -98,14 +98,14 @@ fn test_bits(){
bc++ bc++
n = n >> 1 n = n >> 1
} }
//C.printf("x:%02x lz: %llu cmp: %d\n", byte(i), reverse_8(byte(i)), rv) // C.printf("x:%02x lz: %llu cmp: %d\n", byte(i), reverse_8(byte(i)), rv)
assert reverse_8(byte(i)) == rv assert reverse_8(byte(i)) == rv
i = (i << 1) + 1 i = (i << 1) + 1
} }
// 16 bit // 16 bit
i = 0 i = 0
for _ in 0..17 { for _ in 0 .. 17 {
mut rv := u16(0) mut rv := u16(0)
mut bc := 0 mut bc := 0
mut n := i mut n := i
@ -114,14 +114,14 @@ fn test_bits(){
bc++ bc++
n = n >> 1 n = n >> 1
} }
//C.printf("x:%04x lz: %llu cmp: %d\n", u16(i), reverse_16(u16(i)), rv) // C.printf("x:%04x lz: %llu cmp: %d\n", u16(i), reverse_16(u16(i)), rv)
assert reverse_16(u16(i)) == rv assert reverse_16(u16(i)) == rv
i = (i << 1) + 1 i = (i << 1) + 1
} }
// 32 bit // 32 bit
i = 0 i = 0
for _ in 0..33 { for _ in 0 .. 33 {
mut rv := u32(0) mut rv := u32(0)
mut bc := 0 mut bc := 0
mut n := i mut n := i
@ -130,14 +130,14 @@ fn test_bits(){
bc++ bc++
n = n >> 1 n = n >> 1
} }
//C.printf("x:%08x lz: %llu cmp: %d\n", u32(i), reverse_32(u32(i)), rv) // C.printf("x:%08x lz: %llu cmp: %d\n", u32(i), reverse_32(u32(i)), rv)
assert reverse_32(u32(i)) == rv assert reverse_32(u32(i)) == rv
i = (i << 1) + 1 i = (i << 1) + 1
} }
// 64 bit // 64 bit
i1 = 0 i1 = 0
for _ in 0..64 { for _ in 0 .. 64 {
mut rv := u64(0) mut rv := u64(0)
mut bc := 0 mut bc := 0
mut n := i1 mut n := i1
@ -146,7 +146,7 @@ fn test_bits(){
bc++ bc++
n = n >> 1 n = n >> 1
} }
//C.printf("x:%016llx lz: %016llx cmp: %016llx\n", u64(i1), reverse_64(u64(i1)), rv) // C.printf("x:%016llx lz: %016llx cmp: %016llx\n", u64(i1), reverse_64(u64(i1)), rv)
assert reverse_64(i1) == rv assert reverse_64(i1) == rv
i1 = (i1 << 1) + 1 i1 = (i1 << 1) + 1
} }
@ -157,10 +157,10 @@ fn test_bits(){
// 32 bit // 32 bit
i = 1 i = 1
for x in 0..32 { for x in 0 .. 32 {
v := u32(i) << x v := u32(i) << x
sum,carry := add_32(v, v, u32(0)) sum, carry := add_32(v, v, u32(0))
//C.printf("x:%08x [%llu,%llu] %llu\n", u32(i) << x, sum, carry, u64(v) + u64(v)) // C.printf("x:%08x [%llu,%llu] %llu\n", u32(i) << x, sum, carry, u64(v) + u64(v))
assert ((u64(carry) << 32) | u64(sum)) == u64(v) + u64(v) assert ((u64(carry) << 32) | u64(sum)) == u64(v) + u64(v)
} }
mut sum_32t, mut carry_32t := add_32(0x8000_0000, 0x8000_0000, u32(0)) mut sum_32t, mut carry_32t := add_32(0x8000_0000, 0x8000_0000, u32(0))
@ -173,13 +173,14 @@ fn test_bits(){
// 64 bit // 64 bit
i = 1 i = 1
for x in 0..63 { for x in 0 .. 63 {
v := u64(i) << x v := u64(i) << x
sum,carry := add_64(v, v, u64(0)) sum, carry := add_64(v, v, u64(0))
//C.printf("x:%16x [%llu,%llu] %llu\n", u64(i) << x, sum, carry, u64(v >> 32) + u64(v >> 32)) // C.printf("x:%16x [%llu,%llu] %llu\n", u64(i) << x, sum, carry, u64(v >> 32) + u64(v >> 32))
assert ((carry << 32) | sum) == v + v assert ((carry << 32) | sum) == v + v
} }
mut sum_64t, mut carry_64t := add_64(0x8000_0000_0000_0000, 0x8000_0000_0000_0000, u64(0)) mut sum_64t, mut carry_64t := add_64(0x8000_0000_0000_0000, 0x8000_0000_0000_0000,
u64(0))
assert sum_64t == u64(0) assert sum_64t == u64(0)
assert carry_64t == u64(1) assert carry_64t == u64(1)
@ -193,39 +194,39 @@ fn test_bits(){
// 32 bit // 32 bit
i = 1 i = 1
for x in 1..32 { for x in 1 .. 32 {
v0 := u32(i) << x v0 := u32(i) << x
v1 := v0 >> 1 v1 := v0 >> 1
mut diff, mut borrow_out := sub_32(v0, v1, u32(0)) mut diff, mut borrow_out := sub_32(v0, v1, u32(0))
//C.printf("x:%08x [%llu,%llu] %08x\n", u32(i) << x, diff, borrow_out, v0 - v1) // C.printf("x:%08x [%llu,%llu] %08x\n", u32(i) << x, diff, borrow_out, v0 - v1)
assert diff == v1 assert diff == v1
diff, borrow_out = sub_32(v0, v1, u32(1)) diff, borrow_out = sub_32(v0, v1, u32(1))
//C.printf("x:%08x [%llu,%llu] %08x\n", u32(i) << x, diff, borrow_out, v0 - v1) // C.printf("x:%08x [%llu,%llu] %08x\n", u32(i) << x, diff, borrow_out, v0 - v1)
assert diff == (v1 - 1) assert diff == (v1 - 1)
assert borrow_out == u32(0) assert borrow_out == u32(0)
diff, borrow_out = sub_32(v1, v0, u32(1)) diff, borrow_out = sub_32(v1, v0, u32(1))
//C.printf("x:%08x [%llu,%llu] %08x\n", u32(i) << x, diff, borrow_out, v1 - v0) // C.printf("x:%08x [%llu,%llu] %08x\n", u32(i) << x, diff, borrow_out, v1 - v0)
assert borrow_out == u32(1) assert borrow_out == u32(1)
} }
// 64 bit // 64 bit
i = 1 i = 1
for x in 1..64 { for x in 1 .. 64 {
v0 := u64(i) << x v0 := u64(i) << x
v1 := v0 >> 1 v1 := v0 >> 1
mut diff, mut borrow_out := sub_64(v0, v1, u64(0)) mut diff, mut borrow_out := sub_64(v0, v1, u64(0))
//C.printf("x:%08x [%llu,%llu] %08x\n", u64(i) << x, diff, borrow_out, v0 - v1) // C.printf("x:%08x [%llu,%llu] %08x\n", u64(i) << x, diff, borrow_out, v0 - v1)
assert diff == v1 assert diff == v1
diff, borrow_out = sub_64(v0, v1, u64(1)) diff, borrow_out = sub_64(v0, v1, u64(1))
//C.printf("x:%08x [%llu,%llu] %08x\n", u64(i) << x, diff, borrow_out, v0 - v1) // C.printf("x:%08x [%llu,%llu] %08x\n", u64(i) << x, diff, borrow_out, v0 - v1)
assert diff == (v1 - 1) assert diff == (v1 - 1)
assert borrow_out == u64(0) assert borrow_out == u64(0)
diff, borrow_out = sub_64(v1, v0, u64(1)) diff, borrow_out = sub_64(v1, v0, u64(1))
//C.printf("x:%08x [%llu,%llu] %08x\n",u64(i) << x, diff, borrow_out, v1 - v0) // C.printf("x:%08x [%llu,%llu] %08x\n",u64(i) << x, diff, borrow_out, v1 - v0)
assert borrow_out == u64(1) assert borrow_out == u64(1)
} }
@ -235,7 +236,7 @@ fn test_bits(){
// 32 bit // 32 bit
i = 1 i = 1
for x in 0..32 { for x in 0 .. 32 {
v0 := u32(i) << x v0 := u32(i) << x
v1 := v0 - 1 v1 := v0 - 1
hi, lo := mul_32(v0, v1) hi, lo := mul_32(v0, v1)
@ -244,12 +245,12 @@ fn test_bits(){
// 64 bit // 64 bit
i = 1 i = 1
for x in 0..64 { for x in 0 .. 64 {
v0 := u64(i) << x v0 := u64(i) << x
v1 := v0 - 1 v1 := v0 - 1
hi, lo := mul_64(v0, v1) hi, lo := mul_64(v0, v1)
//C.printf("v0: %llu v1: %llu [%llu,%llu] tt: %llu\n", v0, v1, hi, lo, (v0 >> 32) * (v1 >> 32)) // C.printf("v0: %llu v1: %llu [%llu,%llu] tt: %llu\n", v0, v1, hi, lo, (v0 >> 32) * (v1 >> 32))
assert (hi & 0xFFFF_FFFF_0000_0000) == (((v0 >> 32)*(v1 >> 32)) & 0xFFFF_FFFF_0000_0000) assert (hi & 0xFFFF_FFFF_0000_0000) == (((v0 >> 32) * (v1 >> 32)) & 0xFFFF_FFFF_0000_0000)
assert (lo & 0x0000_0000_FFFF_FFFF) == (((v0 & 0x0000_0000_FFFF_FFFF) * (v1 & 0x0000_0000_FFFF_FFFF)) & 0x0000_0000_FFFF_FFFF) assert (lo & 0x0000_0000_FFFF_FFFF) == (((v0 & 0x0000_0000_FFFF_FFFF) * (v1 & 0x0000_0000_FFFF_FFFF)) & 0x0000_0000_FFFF_FFFF)
} }
@ -259,12 +260,12 @@ fn test_bits(){
// 32 bit // 32 bit
i = 1 i = 1
for x in 0..31 { for x in 0 .. 31 {
hi := u32(i) << x hi := u32(i) << x
lo := hi - 1 lo := hi - 1
y := u32(3) << x y := u32(3) << x
quo, rem := div_32(hi, lo, y) quo, rem := div_32(hi, lo, y)
//C.printf("[%08x_%08x] %08x (%08x,%08x)\n", hi, lo, y, quo, rem) // C.printf("[%08x_%08x] %08x (%08x,%08x)\n", hi, lo, y, quo, rem)
tst := ((u64(hi) << 32) | u64(lo)) tst := ((u64(hi) << 32) | u64(lo))
assert quo == (tst / u64(y)) assert quo == (tst / u64(y))
assert rem == (tst % u64(y)) assert rem == (tst % u64(y))
@ -273,16 +274,15 @@ fn test_bits(){
// 64 bit // 64 bit
i = 1 i = 1
for x in 0..62 { for x in 0 .. 62 {
hi := u64(i) << x hi := u64(i) << x
lo := u64(2) //hi - 1 lo := u64(2) // hi - 1
y := u64(0x4000_0000_0000_0000) y := u64(0x4000_0000_0000_0000)
quo, rem := div_64(hi, lo, y) quo, rem := div_64(hi, lo, y)
//C.printf("[%016llx_%016llx] %016llx (%016llx,%016llx)\n", hi, lo, y, quo, rem) // C.printf("[%016llx_%016llx] %016llx (%016llx,%016llx)\n", hi, lo, y, quo, rem)
assert quo == u64(2)<<(x+1) assert quo == u64(2) << (x + 1)
_, rem1 := div_64(hi%y, lo, y) _, rem1 := div_64(hi % y, lo, y)
assert rem == rem1 assert rem == rem1
assert rem == rem_64(hi, lo, y) assert rem == rem_64(hi, lo, y)
} }
} }

View File

@ -19,12 +19,7 @@ pub fn complex(re f64, im f64) Complex {
// To String method // To String method
pub fn (c Complex) str() string { pub fn (c Complex) str() string {
mut out := '${c.re:f}' mut out := '${c.re:f}'
out += if c.im >= 0 { out += if c.im >= 0 { '+${c.im:f}' } else { '${c.im:f}' }
'+${c.im:f}'
}
else {
'${c.im:f}'
}
out += 'i' out += 'i'
return out return out
} }
@ -34,11 +29,11 @@ pub fn (c Complex) str() string {
pub fn (c Complex) abs() f64 { pub fn (c Complex) abs() f64 {
return C.hypot(c.re, c.im) return C.hypot(c.re, c.im)
} }
pub fn (c Complex) mod() f64 { pub fn (c Complex) mod() f64 {
return c.abs() return c.abs()
} }
// Complex Angle // Complex Angle
pub fn (c Complex) angle() f64 { pub fn (c Complex) angle() f64 {
return math.atan2(c.im, c.re) return math.atan2(c.im, c.re)
@ -56,19 +51,14 @@ pub fn (c1 Complex) - (c2 Complex) Complex {
// Complex Multiplication c1 * c2 // Complex Multiplication c1 * c2
pub fn (c1 Complex) * (c2 Complex) Complex { pub fn (c1 Complex) * (c2 Complex) Complex {
return Complex{ return Complex{(c1.re * c2.re) + ((c1.im * c2.im) * -1), (c1.re * c2.im) + (c1.im * c2.re)}
(c1.re * c2.re) + ((c1.im * c2.im) * -1),
(c1.re * c2.im) + (c1.im * c2.re)
}
} }
// Complex Division c1 / c2 // Complex Division c1 / c2
pub fn (c1 Complex) / (c2 Complex) Complex { pub fn (c1 Complex) / (c2 Complex) Complex {
denom := (c2.re * c2.re) + (c2.im * c2.im) denom := (c2.re * c2.re) + (c2.im * c2.im)
return Complex { return Complex{((c1.re * c2.re) + ((c1.im * -c2.im) * -1)) / denom, ((c1.re * -c2.im) +
((c1.re * c2.re) + ((c1.im * -c2.im) * -1))/denom, (c1.im * c2.re)) / denom}
((c1.re * -c2.im) + (c1.im * c2.re))/denom
}
} }
// Complex Addition c1.add(c2) // Complex Addition c1.add(c2)
@ -83,23 +73,18 @@ pub fn (c1 Complex) subtract(c2 Complex) Complex {
// Complex Multiplication c1.multiply(c2) // Complex Multiplication c1.multiply(c2)
pub fn (c1 Complex) multiply(c2 Complex) Complex { pub fn (c1 Complex) multiply(c2 Complex) Complex {
return Complex{ return Complex{(c1.re * c2.re) + ((c1.im * c2.im) * -1), (c1.re * c2.im) + (c1.im * c2.re)}
(c1.re * c2.re) + ((c1.im * c2.im) * -1),
(c1.re * c2.im) + (c1.im * c2.re)
}
} }
// Complex Division c1.divide(c2) // Complex Division c1.divide(c2)
pub fn (c1 Complex) divide(c2 Complex) Complex { pub fn (c1 Complex) divide(c2 Complex) Complex {
denom := (c2.re * c2.re) + (c2.im * c2.im) denom := (c2.re * c2.re) + (c2.im * c2.im)
return Complex { return Complex{((c1.re * c2.re) + ((c1.im * -c2.im) * -1)) / denom, ((c1.re * -c2.im) +
((c1.re * c2.re) + ((c1.im * -c2.im) * -1)) / denom, (c1.im * c2.re)) / denom}
((c1.re * -c2.im) + (c1.im * c2.re)) / denom
}
} }
// Complex Conjugate // Complex Conjugate
pub fn (c Complex) conjugate() Complex{ pub fn (c Complex) conjugate() Complex {
return Complex{c.re, -c.im} return Complex{c.re, -c.im}
} }
@ -114,10 +99,7 @@ pub fn (c Complex) addinv() Complex {
// Based on // Based on
// http://tutorial.math.lamar.edu/Extras/ComplexPrimer/Arithmetic.aspx // http://tutorial.math.lamar.edu/Extras/ComplexPrimer/Arithmetic.aspx
pub fn (c Complex) mulinv() Complex { pub fn (c Complex) mulinv() Complex {
return Complex { return Complex{c.re / (c.re * c.re + c.im * c.im), -c.im / (c.re * c.re + c.im * c.im)}
c.re / (c.re * c.re + c.im * c.im),
-c.im / (c.re * c.re + c.im * c.im)
}
} }
// Complex Power // Complex Power
@ -126,10 +108,7 @@ pub fn (c Complex) mulinv() Complex {
pub fn (c Complex) pow(n f64) Complex { pub fn (c Complex) pow(n f64) Complex {
r := math.pow(c.abs(), n) r := math.pow(c.abs(), n)
angle := c.angle() angle := c.angle()
return Complex { return Complex{r * math.cos(n * angle), r * math.sin(n * angle)}
r * math.cos(n * angle),
r * math.sin(n * angle)
}
} }
// Complex nth root // Complex nth root
@ -143,20 +122,14 @@ pub fn (c Complex) root(n f64) Complex {
// https://www.math.wisc.edu/~angenent/Free-Lecture-Notes/freecomplexnumbers.pdf // https://www.math.wisc.edu/~angenent/Free-Lecture-Notes/freecomplexnumbers.pdf
pub fn (c Complex) exp() Complex { pub fn (c Complex) exp() Complex {
a := math.exp(c.re) a := math.exp(c.re)
return Complex { return Complex{a * math.cos(c.im), a * math.sin(c.im)}
a * math.cos(c.im),
a * math.sin(c.im)
}
} }
// Complex Natural Logarithm // Complex Natural Logarithm
// Based on // Based on
// http://www.chemistrylearning.com/logarithm-of-complex-number/ // http://www.chemistrylearning.com/logarithm-of-complex-number/
pub fn (c Complex) ln() Complex { pub fn (c Complex) ln() Complex {
return Complex { return Complex{math.log(c.abs()), c.angle()}
math.log(c.abs()),
c.angle()
}
} }
// Complex Log Base Complex // Complex Log Base Complex
@ -170,7 +143,7 @@ pub fn (c Complex) log(base Complex) Complex {
// Based on // Based on
// http://mathworld.wolfram.com/ComplexArgument.html // http://mathworld.wolfram.com/ComplexArgument.html
pub fn (c Complex) arg() f64 { pub fn (c Complex) arg() f64 {
return math.atan2(c.im,c.re) return math.atan2(c.im, c.re)
} }
// Complex raised to Complex Power // Complex raised to Complex Power
@ -178,33 +151,24 @@ pub fn (c Complex) arg() f64 {
// http://mathworld.wolfram.com/ComplexExponentiation.html // http://mathworld.wolfram.com/ComplexExponentiation.html
pub fn (c Complex) cpow(p Complex) Complex { pub fn (c Complex) cpow(p Complex) Complex {
a := c.arg() a := c.arg()
b := math.pow(c.re,2) + math.pow(c.im,2) b := math.pow(c.re, 2) + math.pow(c.im, 2)
d := p.re * a + (1.0/2) * p.im * math.log(b) d := p.re * a + (1.0 / 2) * p.im * math.log(b)
t1 := math.pow(b,p.re/2) * math.exp(-p.im*a) t1 := math.pow(b, p.re / 2) * math.exp(-p.im * a)
return Complex{ return Complex{t1 * math.cos(d), t1 * math.sin(d)}
t1 * math.cos(d),
t1 * math.sin(d)
}
} }
// Complex Sin // Complex Sin
// Based on // Based on
// http://www.milefoot.com/math/complex/functionsofi.htm // http://www.milefoot.com/math/complex/functionsofi.htm
pub fn (c Complex) sin() Complex { pub fn (c Complex) sin() Complex {
return Complex{ return Complex{math.sin(c.re) * math.cosh(c.im), math.cos(c.re) * math.sinh(c.im)}
math.sin(c.re) * math.cosh(c.im),
math.cos(c.re) * math.sinh(c.im)
}
} }
// Complex Cosine // Complex Cosine
// Based on // Based on
// http://www.milefoot.com/math/complex/functionsofi.htm // http://www.milefoot.com/math/complex/functionsofi.htm
pub fn (c Complex) cos() Complex { pub fn (c Complex) cos() Complex {
return Complex{ return Complex{math.cos(c.re) * math.cosh(c.im), -(math.sin(c.re) * math.sinh(c.im))}
math.cos(c.re) * math.cosh(c.im),
-(math.sin(c.re) * math.sinh(c.im))
}
} }
// Complex Tangent // Complex Tangent
@ -225,102 +189,71 @@ pub fn (c Complex) cot() Complex {
// Based on // Based on
// http://www.suitcaseofdreams.net/Trigonometric_Functions.htm // http://www.suitcaseofdreams.net/Trigonometric_Functions.htm
pub fn (c Complex) sec() Complex { pub fn (c Complex) sec() Complex {
return complex(1,0).divide(c.cos()) return complex(1, 0).divide(c.cos())
} }
// Complex Cosecant // Complex Cosecant
// Based on // Based on
// http://www.suitcaseofdreams.net/Trigonometric_Functions.htm // http://www.suitcaseofdreams.net/Trigonometric_Functions.htm
pub fn (c Complex) csc() Complex { pub fn (c Complex) csc() Complex {
return complex(1,0).divide(c.sin()) return complex(1, 0).divide(c.sin())
} }
// Complex Arc Sin / Sin Inverse // Complex Arc Sin / Sin Inverse
// Based on // Based on
// http://www.milefoot.com/math/complex/summaryops.htm // http://www.milefoot.com/math/complex/summaryops.htm
pub fn (c Complex) asin() Complex { pub fn (c Complex) asin() Complex {
return complex(0,-1).multiply( return complex(0, -1).multiply(complex(0, 1).multiply(c).add(complex(1, 0).subtract(c.pow(2)).root(2)).ln())
complex(0,1)
.multiply(c)
.add(
complex(1,0)
.subtract(c.pow(2))
.root(2)
)
.ln()
)
} }
// Complex Arc Consine / Consine Inverse // Complex Arc Consine / Consine Inverse
// Based on // Based on
// http://www.milefoot.com/math/complex/summaryops.htm // http://www.milefoot.com/math/complex/summaryops.htm
pub fn (c Complex) acos() Complex { pub fn (c Complex) acos() Complex {
return complex(0,-1).multiply( return complex(0, -1).multiply(c.add(complex(0, 1).multiply(complex(1, 0).subtract(c.pow(2)).root(2))).ln())
c.add(
complex(0,1)
.multiply(
complex(1,0)
.subtract(c.pow(2))
.root(2)
)
)
.ln()
)
} }
// Complex Arc Tangent / Tangent Inverse // Complex Arc Tangent / Tangent Inverse
// Based on // Based on
// http://www.milefoot.com/math/complex/summaryops.htm // http://www.milefoot.com/math/complex/summaryops.htm
pub fn (c Complex) atan() Complex { pub fn (c Complex) atan() Complex {
i := complex(0,1) i := complex(0, 1)
return complex(0,1.0/2).multiply( return complex(0, 1.0 / 2).multiply(i.add(c).divide(i.subtract(c)).ln())
i.add(c)
.divide(
i.subtract(c)
)
.ln()
)
} }
// Complex Arc Cotangent / Cotangent Inverse // Complex Arc Cotangent / Cotangent Inverse
// Based on // Based on
// http://www.suitcaseofdreams.net/Inverse_Functions.htm // http://www.suitcaseofdreams.net/Inverse_Functions.htm
pub fn (c Complex) acot() Complex { pub fn (c Complex) acot() Complex {
return complex(1,0).divide(c).atan() return complex(1, 0).divide(c).atan()
} }
// Complex Arc Secant / Secant Inverse // Complex Arc Secant / Secant Inverse
// Based on // Based on
// http://www.suitcaseofdreams.net/Inverse_Functions.htm // http://www.suitcaseofdreams.net/Inverse_Functions.htm
pub fn (c Complex) asec() Complex { pub fn (c Complex) asec() Complex {
return complex(1,0).divide(c).acos() return complex(1, 0).divide(c).acos()
} }
// Complex Arc Cosecant / Cosecant Inverse // Complex Arc Cosecant / Cosecant Inverse
// Based on // Based on
// http://www.suitcaseofdreams.net/Inverse_Functions.htm // http://www.suitcaseofdreams.net/Inverse_Functions.htm
pub fn (c Complex) acsc() Complex { pub fn (c Complex) acsc() Complex {
return complex(1,0).divide(c).asin() return complex(1, 0).divide(c).asin()
} }
// Complex Hyperbolic Sin // Complex Hyperbolic Sin
// Based on // Based on
// http://www.milefoot.com/math/complex/functionsofi.htm // http://www.milefoot.com/math/complex/functionsofi.htm
pub fn (c Complex) sinh() Complex { pub fn (c Complex) sinh() Complex {
return Complex{ return Complex{math.cos(c.im) * math.sinh(c.re), math.sin(c.im) * math.cosh(c.re)}
math.cos(c.im) * math.sinh(c.re),
math.sin(c.im) * math.cosh(c.re)
}
} }
// Complex Hyperbolic Cosine // Complex Hyperbolic Cosine
// Based on // Based on
// http://www.milefoot.com/math/complex/functionsofi.htm // http://www.milefoot.com/math/complex/functionsofi.htm
pub fn (c Complex) cosh() Complex { pub fn (c Complex) cosh() Complex {
return Complex{ return Complex{math.cos(c.im) * math.cosh(c.re), math.sin(c.im) * math.sinh(c.re)}
math.cos(c.im) * math.cosh(c.re),
math.sin(c.im) * math.sinh(c.re)
}
} }
// Complex Hyperbolic Tangent // Complex Hyperbolic Tangent
@ -341,25 +274,21 @@ pub fn (c Complex) coth() Complex {
// Based on // Based on
// http://www.suitcaseofdreams.net/Hyperbolic_Functions.htm // http://www.suitcaseofdreams.net/Hyperbolic_Functions.htm
pub fn (c Complex) sech() Complex { pub fn (c Complex) sech() Complex {
return complex(1,0).divide(c.cosh()) return complex(1, 0).divide(c.cosh())
} }
// Complex Hyperbolic Cosecant // Complex Hyperbolic Cosecant
// Based on // Based on
// http://www.suitcaseofdreams.net/Hyperbolic_Functions.htm // http://www.suitcaseofdreams.net/Hyperbolic_Functions.htm
pub fn (c Complex) csch() Complex { pub fn (c Complex) csch() Complex {
return complex(1,0).divide(c.sinh()) return complex(1, 0).divide(c.sinh())
} }
// Complex Hyperbolic Arc Sin / Sin Inverse // Complex Hyperbolic Arc Sin / Sin Inverse
// Based on // Based on
// http://www.suitcaseofdreams.net/Inverse__Hyperbolic_Functions.htm // http://www.suitcaseofdreams.net/Inverse__Hyperbolic_Functions.htm
pub fn (c Complex) asinh() Complex { pub fn (c Complex) asinh() Complex {
return c.add( return c.add(c.pow(2).add(complex(1, 0)).root(2)).ln()
c.pow(2)
.add(complex(1,0))
.root(2)
).ln()
} }
// Complex Hyperbolic Arc Consine / Consine Inverse // Complex Hyperbolic Arc Consine / Consine Inverse
@ -367,22 +296,10 @@ pub fn (c Complex) asinh() Complex {
// http://www.suitcaseofdreams.net/Inverse__Hyperbolic_Functions.htm // http://www.suitcaseofdreams.net/Inverse__Hyperbolic_Functions.htm
pub fn (c Complex) acosh() Complex { pub fn (c Complex) acosh() Complex {
if c.re > 1 { if c.re > 1 {
return c.add( return c.add(c.pow(2).subtract(complex(1, 0)).root(2)).ln()
c.pow(2) } else {
.subtract(complex(1,0)) one := complex(1, 0)
.root(2) return c.add(c.add(one).root(2).multiply(c.subtract(one).root(2))).ln()
).ln()
}
else {
one := complex(1,0)
return c.add(
c.add(one)
.root(2)
.multiply(
c.subtract(one)
.root(2)
)
).ln()
} }
} }
@ -390,29 +307,11 @@ pub fn (c Complex) acosh() Complex {
// Based on // Based on
// http://www.suitcaseofdreams.net/Inverse__Hyperbolic_Functions.htm // http://www.suitcaseofdreams.net/Inverse__Hyperbolic_Functions.htm
pub fn (c Complex) atanh() Complex { pub fn (c Complex) atanh() Complex {
one := complex(1,0) one := complex(1, 0)
if c.re < 1 { if c.re < 1 {
return complex(1.0/2,0).multiply( return complex(1.0 / 2, 0).multiply(one.add(c).divide(one.subtract(c)).ln())
one } else {
.add(c) return complex(1.0 / 2, 0).multiply(one.add(c).ln().subtract(one.subtract(c).ln()))
.divide(
one
.subtract(c)
)
.ln()
)
}
else {
return complex(1.0/2,0).multiply(
one
.add(c)
.ln()
.subtract(
one
.subtract(c)
.ln()
)
)
} }
} }
@ -420,29 +319,12 @@ pub fn (c Complex) atanh() Complex {
// Based on // Based on
// http://www.suitcaseofdreams.net/Inverse__Hyperbolic_Functions.htm // http://www.suitcaseofdreams.net/Inverse__Hyperbolic_Functions.htm
pub fn (c Complex) acoth() Complex { pub fn (c Complex) acoth() Complex {
one := complex(1,0) one := complex(1, 0)
if c.re < 0 || c.re > 1 { if c.re < 0 || c.re > 1 {
return complex(1.0/2,0).multiply( return complex(1.0 / 2, 0).multiply(c.add(one).divide(c.subtract(one)).ln())
c } else {
.add(one)
.divide(
c.subtract(one)
)
.ln()
)
}
else {
div := one.divide(c) div := one.divide(c)
return complex(1.0/2,0).multiply( return complex(1.0 / 2, 0).multiply(one.add(div).ln().subtract(one.subtract(div).ln()))
one
.add(div)
.ln()
.subtract(
one
.subtract(div)
.ln()
)
)
} }
} }
@ -452,51 +334,37 @@ pub fn (c Complex) acoth() Complex {
// For certain scenarios, Result mismatch in crossverification with Wolfram Alpha - analysis pending // For certain scenarios, Result mismatch in crossverification with Wolfram Alpha - analysis pending
// pub fn (c Complex) asech() Complex { // pub fn (c Complex) asech() Complex {
// one := complex(1,0) // one := complex(1,0)
// if(c.re < -1.0) { // if(c.re < -1.0) {
// return one.subtract( // return one.subtract(
// one.subtract( // one.subtract(
// c.pow(2) // c.pow(2)
// ) // )
// .root(2) // .root(2)
// ) // )
// .divide(c) // .divide(c)
// .ln() // .ln()
// } // }
// else { // else {
// return one.add( // return one.add(
// one.subtract( // one.subtract(
// c.pow(2) // c.pow(2)
// ) // )
// .root(2) // .root(2)
// ) // )
// .divide(c) // .divide(c)
// .ln() // .ln()
// } // }
// } // }
// Complex Hyperbolic Arc Cosecant / Cosecant Inverse // Complex Hyperbolic Arc Cosecant / Cosecant Inverse
// Based on // Based on
// http://www.suitcaseofdreams.net/Inverse__Hyperbolic_Functions.htm // http://www.suitcaseofdreams.net/Inverse__Hyperbolic_Functions.htm
pub fn (c Complex) acsch() Complex { pub fn (c Complex) acsch() Complex {
one := complex(1,0) one := complex(1, 0)
if c.re < 0 { if c.re < 0 {
return one.subtract( return one.subtract(one.add(c.pow(2)).root(2)).divide(c).ln()
one.add(
c.pow(2)
)
.root(2)
)
.divide(c)
.ln()
} else { } else {
return one.add( return one.add(one.add(c.pow(2)).root(2)).divide(c).ln()
one.add(
c.pow(2)
)
.root(2)
)
.divide(c)
.ln()
} }
} }

View File

@ -11,124 +11,124 @@ fn tst_res(str1 string, str2 string) bool {
fn test_complex_addition() { fn test_complex_addition() {
// Test is based on and verified from practice examples of Khan Academy // Test is based on and verified from practice examples of Khan Academy
// https://www.khanacademy.org/math/precalculus/imaginary-and-complex-numbers // https://www.khanacademy.org/math/precalculus/imaginary-and-complex-numbers
mut c1 := cmplx.complex(0,-10) mut c1 := cmplx.complex(0, -10)
mut c2 := cmplx.complex(-40,8) mut c2 := cmplx.complex(-40, 8)
mut result := c1 + c2 mut result := c1 + c2
assert result.equals(cmplx.complex(-40,-2)) assert result.equals(cmplx.complex(-40, -2))
c1 = cmplx.complex(-71,2) c1 = cmplx.complex(-71, 2)
c2 = cmplx.complex(88,-12) c2 = cmplx.complex(88, -12)
result = c1 + c2 result = c1 + c2
assert result.equals(cmplx.complex(17,-10)) assert result.equals(cmplx.complex(17, -10))
c1 = cmplx.complex(0,-30) c1 = cmplx.complex(0, -30)
c2 = cmplx.complex(52,-30) c2 = cmplx.complex(52, -30)
result = c1 + c2 result = c1 + c2
assert result.equals(cmplx.complex(52,-60)) assert result.equals(cmplx.complex(52, -60))
c1 = cmplx.complex(12,-9) c1 = cmplx.complex(12, -9)
c2 = cmplx.complex(32,-6) c2 = cmplx.complex(32, -6)
result = c1 + c2 result = c1 + c2
assert result.equals(cmplx.complex(44,-15)) assert result.equals(cmplx.complex(44, -15))
} }
fn test_complex_subtraction() { fn test_complex_subtraction() {
// Test is based on and verified from practice examples of Khan Academy // Test is based on and verified from practice examples of Khan Academy
// https://www.khanacademy.org/math/precalculus/imaginary-and-complex-numbers // https://www.khanacademy.org/math/precalculus/imaginary-and-complex-numbers
mut c1 := cmplx.complex(-8,0) mut c1 := cmplx.complex(-8, 0)
mut c2 := cmplx.complex(6,30) mut c2 := cmplx.complex(6, 30)
mut result := c1 - c2 mut result := c1 - c2
assert result.equals(cmplx.complex(-14,-30)) assert result.equals(cmplx.complex(-14, -30))
c1 = cmplx.complex(-19,7) c1 = cmplx.complex(-19, 7)
c2 = cmplx.complex(29,32) c2 = cmplx.complex(29, 32)
result = c1 - c2 result = c1 - c2
assert result.equals(cmplx.complex(-48,-25)) assert result.equals(cmplx.complex(-48, -25))
c1 = cmplx.complex(12,0) c1 = cmplx.complex(12, 0)
c2 = cmplx.complex(23,13) c2 = cmplx.complex(23, 13)
result = c1 - c2 result = c1 - c2
assert result.equals(cmplx.complex(-11,-13)) assert result.equals(cmplx.complex(-11, -13))
c1 = cmplx.complex(-14,3) c1 = cmplx.complex(-14, 3)
c2 = cmplx.complex(0,14) c2 = cmplx.complex(0, 14)
result = c1 - c2 result = c1 - c2
assert result.equals(cmplx.complex(-14,-11)) assert result.equals(cmplx.complex(-14, -11))
} }
fn test_complex_multiplication() { fn test_complex_multiplication() {
// Test is based on and verified from practice examples of Khan Academy // Test is based on and verified from practice examples of Khan Academy
// https://www.khanacademy.org/math/precalculus/imaginary-and-complex-numbers // https://www.khanacademy.org/math/precalculus/imaginary-and-complex-numbers
mut c1 := cmplx.complex(1,2) mut c1 := cmplx.complex(1, 2)
mut c2 := cmplx.complex(1,-4) mut c2 := cmplx.complex(1, -4)
mut result := c1 * c2 mut result := c1 * c2
assert result.equals(cmplx.complex(9,-2)) assert result.equals(cmplx.complex(9, -2))
c1 = cmplx.complex(-4,-4) c1 = cmplx.complex(-4, -4)
c2 = cmplx.complex(-5,-3) c2 = cmplx.complex(-5, -3)
result = c1 * c2 result = c1 * c2
assert result.equals(cmplx.complex(8,32)) assert result.equals(cmplx.complex(8, 32))
c1 = cmplx.complex(4,4) c1 = cmplx.complex(4, 4)
c2 = cmplx.complex(-2,-5) c2 = cmplx.complex(-2, -5)
result = c1 * c2 result = c1 * c2
assert result.equals(cmplx.complex(12,-28)) assert result.equals(cmplx.complex(12, -28))
c1 = cmplx.complex(2,-2) c1 = cmplx.complex(2, -2)
c2 = cmplx.complex(4,-4) c2 = cmplx.complex(4, -4)
result = c1 * c2 result = c1 * c2
assert result.equals(cmplx.complex(0,-16)) assert result.equals(cmplx.complex(0, -16))
} }
fn test_complex_division() { fn test_complex_division() {
// Test is based on and verified from practice examples of Khan Academy // Test is based on and verified from practice examples of Khan Academy
// https://www.khanacademy.org/math/precalculus/imaginary-and-complex-numbers // https://www.khanacademy.org/math/precalculus/imaginary-and-complex-numbers
mut c1 := cmplx.complex(-9,-6) mut c1 := cmplx.complex(-9, -6)
mut c2 := cmplx.complex(-3,-2) mut c2 := cmplx.complex(-3, -2)
mut result := c1 / c2 mut result := c1 / c2
assert result.equals(cmplx.complex(3,0)) assert result.equals(cmplx.complex(3, 0))
c1 = cmplx.complex(-23,11) c1 = cmplx.complex(-23, 11)
c2 = cmplx.complex(5,1) c2 = cmplx.complex(5, 1)
result = c1 / c2 result = c1 / c2
assert result.equals(cmplx.complex(-4,3)) assert result.equals(cmplx.complex(-4, 3))
c1 = cmplx.complex(8,-2) c1 = cmplx.complex(8, -2)
c2 = cmplx.complex(-4,1) c2 = cmplx.complex(-4, 1)
result = c1 / c2 result = c1 / c2
assert result.equals(cmplx.complex(-2,0)) assert result.equals(cmplx.complex(-2, 0))
c1 = cmplx.complex(11,24) c1 = cmplx.complex(11, 24)
c2 = cmplx.complex(-4,-1) c2 = cmplx.complex(-4, -1)
result = c1 / c2 result = c1 / c2
assert result.equals(cmplx.complex(-4,-5)) assert result.equals(cmplx.complex(-4, -5))
} }
fn test_complex_conjugate() { fn test_complex_conjugate() {
// Test is based on and verified from practice examples of Khan Academy // Test is based on and verified from practice examples of Khan Academy
// https://www.khanacademy.org/math/precalculus/imaginary-and-complex-numbers // https://www.khanacademy.org/math/precalculus/imaginary-and-complex-numbers
mut c1 := cmplx.complex(0,8) mut c1 := cmplx.complex(0, 8)
mut result := c1.conjugate() mut result := c1.conjugate()
assert result.equals(cmplx.complex(0,-8)) assert result.equals(cmplx.complex(0, -8))
c1 = cmplx.complex(7,3) c1 = cmplx.complex(7, 3)
result = c1.conjugate() result = c1.conjugate()
assert result.equals(cmplx.complex(7,-3)) assert result.equals(cmplx.complex(7, -3))
c1 = cmplx.complex(2,2) c1 = cmplx.complex(2, 2)
result = c1.conjugate() result = c1.conjugate()
assert result.equals(cmplx.complex(2,-2)) assert result.equals(cmplx.complex(2, -2))
c1 = cmplx.complex(7,0) c1 = cmplx.complex(7, 0)
result = c1.conjugate() result = c1.conjugate()
assert result.equals(cmplx.complex(7,0)) assert result.equals(cmplx.complex(7, 0))
} }
fn test_complex_equals() { fn test_complex_equals() {
mut c1 := cmplx.complex(0,8) mut c1 := cmplx.complex(0, 8)
mut c2 := cmplx.complex(0,8) mut c2 := cmplx.complex(0, 8)
assert c1.equals(c2) assert c1.equals(c2)
c1 = cmplx.complex(-3,19) c1 = cmplx.complex(-3, 19)
c2 = cmplx.complex(-3,19) c2 = cmplx.complex(-3, 19)
assert c1.equals(c2) assert c1.equals(c2)
} }
fn test_complex_abs() { fn test_complex_abs() {
mut c1 := cmplx.complex(3,4) mut c1 := cmplx.complex(3, 4)
assert c1.abs() == 5 assert c1.abs() == 5
c1 = cmplx.complex(1,2) c1 = cmplx.complex(1, 2)
assert c1.abs() == math.sqrt(5) assert c1.abs() == math.sqrt(5)
assert c1.abs() == c1.conjugate().abs() assert c1.abs() == c1.conjugate().abs()
c1 = cmplx.complex(7,0) c1 = cmplx.complex(7, 0)
assert c1.abs() == 7 assert c1.abs() == 7
} }
fn test_complex_angle(){ fn test_complex_angle() {
// Test is based on and verified from practice examples of Khan Academy // Test is based on and verified from practice examples of Khan Academy
// https://www.khanacademy.org/math/precalculus/imaginary-and-complex-numbers // https://www.khanacademy.org/math/precalculus/imaginary-and-complex-numbers
mut c := cmplx.complex(1, 0) mut c := cmplx.complex(1, 0)
@ -145,52 +145,51 @@ fn test_complex_angle(){
assert cc.angle() + c.angle() == 0 assert cc.angle() + c.angle() == 0
} }
fn test_complex_addinv() { fn test_complex_addinv() {
// Tests were also verified on Wolfram Alpha // Tests were also verified on Wolfram Alpha
mut c1 := cmplx.complex(5,7) mut c1 := cmplx.complex(5, 7)
mut c2 := cmplx.complex(-5,-7) mut c2 := cmplx.complex(-5, -7)
mut result := c1.addinv() mut result := c1.addinv()
assert result.equals(c2) assert result.equals(c2)
c1 = cmplx.complex(-3,4) c1 = cmplx.complex(-3, 4)
c2 = cmplx.complex(3,-4) c2 = cmplx.complex(3, -4)
result = c1.addinv() result = c1.addinv()
assert result.equals(c2) assert result.equals(c2)
c1 = cmplx.complex(-1,-2) c1 = cmplx.complex(-1, -2)
c2 = cmplx.complex(1,2) c2 = cmplx.complex(1, 2)
result = c1.addinv() result = c1.addinv()
assert result.equals(c2) assert result.equals(c2)
} }
fn test_complex_mulinv() { fn test_complex_mulinv() {
// Tests were also verified on Wolfram Alpha // Tests were also verified on Wolfram Alpha
mut c1 := cmplx.complex(5,7) mut c1 := cmplx.complex(5, 7)
mut c2 := cmplx.complex(0.067568,-0.094595) mut c2 := cmplx.complex(0.067568, -0.094595)
mut result := c1.mulinv() mut result := c1.mulinv()
// Some issue with precision comparison in f64 using == operator hence serializing to string // Some issue with precision comparison in f64 using == operator hence serializing to string
println(c2.str()) println(c2.str())
println(result.str()) println(result.str())
assert result.str().eq(c2.str()) assert result.str().eq(c2.str())
c1 = cmplx.complex(-3,4) c1 = cmplx.complex(-3, 4)
c2 = cmplx.complex(-0.12,-0.16) c2 = cmplx.complex(-0.12, -0.16)
result = c1.mulinv() result = c1.mulinv()
assert result.str().eq(c2.str()) assert result.str().eq(c2.str())
c1 = cmplx.complex(-1,-2) c1 = cmplx.complex(-1, -2)
c2 = cmplx.complex(-0.2,0.4) c2 = cmplx.complex(-0.2, 0.4)
result = c1.mulinv() result = c1.mulinv()
assert result.equals(c2) assert result.equals(c2)
} }
fn test_complex_mod() { fn test_complex_mod() {
// Tests were also verified on Wolfram Alpha // Tests were also verified on Wolfram Alpha
mut c1 := cmplx.complex(5,7) mut c1 := cmplx.complex(5, 7)
mut result := c1.mod() mut result := c1.mod()
// Some issue with precision comparison in f64 using == operator hence serializing to string // Some issue with precision comparison in f64 using == operator hence serializing to string
assert tst_res(result.str(), '8.602325') assert tst_res(result.str(), '8.602325')
c1 = cmplx.complex(-3,4) c1 = cmplx.complex(-3, 4)
result = c1.mod() result = c1.mod()
assert result == 5 assert result == 5
c1 = cmplx.complex(-1,-2) c1 = cmplx.complex(-1, -2)
result = c1.mod() result = c1.mod()
// Some issue with precision comparison in f64 using == operator hence serializing to string // Some issue with precision comparison in f64 using == operator hence serializing to string
assert tst_res(result.str(), '2.236068') assert tst_res(result.str(), '2.236068')
@ -198,18 +197,18 @@ fn test_complex_mod() {
fn test_complex_pow() { fn test_complex_pow() {
// Tests were also verified on Wolfram Alpha // Tests were also verified on Wolfram Alpha
mut c1 := cmplx.complex(5,7) mut c1 := cmplx.complex(5, 7)
mut c2 := cmplx.complex(-24.0,70.0) mut c2 := cmplx.complex(-24.0, 70.0)
mut result := c1.pow(2) mut result := c1.pow(2)
// Some issue with precision comparison in f64 using == operator hence serializing to string // Some issue with precision comparison in f64 using == operator hence serializing to string
assert result.str().eq(c2.str()) assert result.str().eq(c2.str())
c1 = cmplx.complex(-3,4) c1 = cmplx.complex(-3, 4)
c2 = cmplx.complex(117,44) c2 = cmplx.complex(117, 44)
result = c1.pow(3) result = c1.pow(3)
// Some issue with precision comparison in f64 using == operator hence serializing to string // Some issue with precision comparison in f64 using == operator hence serializing to string
assert result.str().eq(c2.str()) assert result.str().eq(c2.str())
c1 = cmplx.complex(-1,-2) c1 = cmplx.complex(-1, -2)
c2 = cmplx.complex(-7,-24) c2 = cmplx.complex(-7, -24)
result = c1.pow(4) result = c1.pow(4)
// Some issue with precision comparison in f64 using == operator hence serializing to string // Some issue with precision comparison in f64 using == operator hence serializing to string
assert result.str().eq(c2.str()) assert result.str().eq(c2.str())
@ -217,18 +216,18 @@ fn test_complex_pow() {
fn test_complex_root() { fn test_complex_root() {
// Tests were also verified on Wolfram Alpha // Tests were also verified on Wolfram Alpha
mut c1 := cmplx.complex(5,7) mut c1 := cmplx.complex(5, 7)
mut c2 := cmplx.complex(2.607904,1.342074) mut c2 := cmplx.complex(2.607904, 1.342074)
mut result := c1.root(2) mut result := c1.root(2)
// Some issue with precision comparison in f64 using == operator hence serializing to string // Some issue with precision comparison in f64 using == operator hence serializing to string
assert result.str().eq(c2.str()) assert result.str().eq(c2.str())
c1 = cmplx.complex(-3,4) c1 = cmplx.complex(-3, 4)
c2 = cmplx.complex(1.264953,1.150614) c2 = cmplx.complex(1.264953, 1.150614)
result = c1.root(3) result = c1.root(3)
// Some issue with precision comparison in f64 using == operator hence serializing to string // Some issue with precision comparison in f64 using == operator hence serializing to string
assert result.str().eq(c2.str()) assert result.str().eq(c2.str())
c1 = cmplx.complex(-1,-2) c1 = cmplx.complex(-1, -2)
c2 = cmplx.complex(1.068059,-0.595482) c2 = cmplx.complex(1.068059, -0.595482)
result = c1.root(4) result = c1.root(4)
// Some issue with precision comparison in f64 using == operator hence serializing to string // Some issue with precision comparison in f64 using == operator hence serializing to string
assert result.str().eq(c2.str()) assert result.str().eq(c2.str())
@ -236,18 +235,18 @@ fn test_complex_root() {
fn test_complex_exp() { fn test_complex_exp() {
// Tests were also verified on Wolfram Alpha // Tests were also verified on Wolfram Alpha
mut c1 := cmplx.complex(5,7) mut c1 := cmplx.complex(5, 7)
mut c2 := cmplx.complex(111.889015,97.505457) mut c2 := cmplx.complex(111.889015, 97.505457)
mut result := c1.exp() mut result := c1.exp()
// Some issue with precision comparison in f64 using == operator hence serializing to string // Some issue with precision comparison in f64 using == operator hence serializing to string
assert result.str().eq(c2.str()) assert result.str().eq(c2.str())
c1 = cmplx.complex(-3,4) c1 = cmplx.complex(-3, 4)
c2 = cmplx.complex(-0.032543,-0.037679) c2 = cmplx.complex(-0.032543, -0.037679)
result = c1.exp() result = c1.exp()
// Some issue with precision comparison in f64 using == operator hence serializing to string // Some issue with precision comparison in f64 using == operator hence serializing to string
assert result.str().eq(c2.str()) assert result.str().eq(c2.str())
c1 = cmplx.complex(-1,-2) c1 = cmplx.complex(-1, -2)
c2 = cmplx.complex(-0.153092,-0.334512) c2 = cmplx.complex(-0.153092, -0.334512)
result = c1.exp() result = c1.exp()
// Some issue with precision comparison in f64 using == operator hence serializing to string // Some issue with precision comparison in f64 using == operator hence serializing to string
assert result.str().eq(c2.str()) assert result.str().eq(c2.str())
@ -255,18 +254,18 @@ fn test_complex_exp() {
fn test_complex_ln() { fn test_complex_ln() {
// Tests were also verified on Wolfram Alpha // Tests were also verified on Wolfram Alpha
mut c1 := cmplx.complex(5,7) mut c1 := cmplx.complex(5, 7)
mut c2 := cmplx.complex(2.152033,0.950547) mut c2 := cmplx.complex(2.152033, 0.950547)
mut result := c1.ln() mut result := c1.ln()
// Some issue with precision comparison in f64 using == operator hence serializing to string // Some issue with precision comparison in f64 using == operator hence serializing to string
assert result.str().eq(c2.str()) assert result.str().eq(c2.str())
c1 = cmplx.complex(-3,4) c1 = cmplx.complex(-3, 4)
c2 = cmplx.complex(1.609438,2.214297) c2 = cmplx.complex(1.609438, 2.214297)
result = c1.ln() result = c1.ln()
// Some issue with precision comparison in f64 using == operator hence serializing to string // Some issue with precision comparison in f64 using == operator hence serializing to string
assert result.str().eq(c2.str()) assert result.str().eq(c2.str())
c1 = cmplx.complex(-1,-2) c1 = cmplx.complex(-1, -2)
c2 = cmplx.complex(0.804719,-2.034444) c2 = cmplx.complex(0.804719, -2.034444)
result = c1.ln() result = c1.ln()
// Some issue with precision comparison in f64 using == operator hence serializing to string // Some issue with precision comparison in f64 using == operator hence serializing to string
assert result.str().eq(c2.str()) assert result.str().eq(c2.str())
@ -274,18 +273,18 @@ fn test_complex_ln() {
fn test_complex_arg() { fn test_complex_arg() {
// Tests were also verified on Wolfram Alpha // Tests were also verified on Wolfram Alpha
mut c1 := cmplx.complex(5,7) mut c1 := cmplx.complex(5, 7)
mut c2 := cmplx.complex(2.152033,0.950547) mut c2 := cmplx.complex(2.152033, 0.950547)
mut result := c1.arg() mut result := c1.arg()
// Some issue with precision comparison in f64 using == operator hence serializing to string // Some issue with precision comparison in f64 using == operator hence serializing to string
assert tst_res(result.str(), '0.950547') assert tst_res(result.str(), '0.950547')
c1 = cmplx.complex(-3,4) c1 = cmplx.complex(-3, 4)
c2 = cmplx.complex(1.609438,2.214297) c2 = cmplx.complex(1.609438, 2.214297)
result = c1.arg() result = c1.arg()
// Some issue with precision comparison in f64 using == operator hence serializing to string // Some issue with precision comparison in f64 using == operator hence serializing to string
assert tst_res(result.str(), '2.214297') assert tst_res(result.str(), '2.214297')
c1 = cmplx.complex(-1,-2) c1 = cmplx.complex(-1, -2)
c2 = cmplx.complex(0.804719,-2.034444) c2 = cmplx.complex(0.804719, -2.034444)
result = c1.arg() result = c1.arg()
// Some issue with precision comparison in f64 using == operator hence serializing to string // Some issue with precision comparison in f64 using == operator hence serializing to string
assert tst_res(result.str(), '-2.034444') assert tst_res(result.str(), '-2.034444')
@ -293,21 +292,21 @@ fn test_complex_arg() {
fn test_complex_log() { fn test_complex_log() {
// Tests were also verified on Wolfram Alpha // Tests were also verified on Wolfram Alpha
mut c1 := cmplx.complex(5,7) mut c1 := cmplx.complex(5, 7)
mut b1 := cmplx.complex(-6,-2) mut b1 := cmplx.complex(-6, -2)
mut c2 := cmplx.complex(0.232873,-1.413175) mut c2 := cmplx.complex(0.232873, -1.413175)
mut result := c1.log(b1) mut result := c1.log(b1)
// Some issue with precision comparison in f64 using == operator hence serializing to string // Some issue with precision comparison in f64 using == operator hence serializing to string
assert result.str().eq(c2.str()) assert result.str().eq(c2.str())
c1 = cmplx.complex(-3,4) c1 = cmplx.complex(-3, 4)
b1 = cmplx.complex(3,-1) b1 = cmplx.complex(3, -1)
c2 = cmplx.complex(0.152198,-0.409312) c2 = cmplx.complex(0.152198, -0.409312)
result = c1.log(b1) result = c1.log(b1)
// Some issue with precision comparison in f64 using == operator hence serializing to string // Some issue with precision comparison in f64 using == operator hence serializing to string
assert result.str().eq(c2.str()) assert result.str().eq(c2.str())
c1 = cmplx.complex(-1,-2) c1 = cmplx.complex(-1, -2)
b1 = cmplx.complex(0,9) b1 = cmplx.complex(0, 9)
c2 = cmplx.complex(-0.298243,1.197981) c2 = cmplx.complex(-0.298243, 1.197981)
result = c1.log(b1) result = c1.log(b1)
// Some issue with precision comparison in f64 using == operator hence serializing to string // Some issue with precision comparison in f64 using == operator hence serializing to string
assert result.str().eq(c2.str()) assert result.str().eq(c2.str())
@ -315,21 +314,21 @@ fn test_complex_log() {
fn test_complex_cpow() { fn test_complex_cpow() {
// Tests were also verified on Wolfram Alpha // Tests were also verified on Wolfram Alpha
mut c1 := cmplx.complex(5,7) mut c1 := cmplx.complex(5, 7)
mut r1 := cmplx.complex(2,2) mut r1 := cmplx.complex(2, 2)
mut c2 := cmplx.complex(11.022341,-0.861785) mut c2 := cmplx.complex(11.022341, -0.861785)
mut result := c1.cpow(r1) mut result := c1.cpow(r1)
// Some issue with precision comparison in f64 using == operator hence serializing to string // Some issue with precision comparison in f64 using == operator hence serializing to string
assert result.str().eq(c2.str()) assert result.str().eq(c2.str())
c1 = cmplx.complex(-3,4) c1 = cmplx.complex(-3, 4)
r1 = cmplx.complex(-4,-2) r1 = cmplx.complex(-4, -2)
c2 = cmplx.complex(0.118303,0.063148) c2 = cmplx.complex(0.118303, 0.063148)
result = c1.cpow(r1) result = c1.cpow(r1)
// Some issue with precision comparison in f64 using == operator hence serializing to string // Some issue with precision comparison in f64 using == operator hence serializing to string
assert result.str().eq(c2.str()) assert result.str().eq(c2.str())
c1 = cmplx.complex(-1,-2) c1 = cmplx.complex(-1, -2)
r1 = cmplx.complex(8,-9) r1 = cmplx.complex(8, -9)
c2 = cmplx.complex(-0.000000,0.000007) c2 = cmplx.complex(-0.000000, 0.000007)
result = c1.cpow(r1) result = c1.cpow(r1)
// Some issue with precision comparison in f64 using == operator hence serializing to string // Some issue with precision comparison in f64 using == operator hence serializing to string
assert result.str().eq(c2.str()) assert result.str().eq(c2.str())
@ -337,18 +336,18 @@ fn test_complex_cpow() {
fn test_complex_sin() { fn test_complex_sin() {
// Tests were also verified on Wolfram Alpha // Tests were also verified on Wolfram Alpha
mut c1 := cmplx.complex(5,7) mut c1 := cmplx.complex(5, 7)
mut c2 := cmplx.complex(-525.794515,155.536550) mut c2 := cmplx.complex(-525.794515, 155.536550)
mut result := c1.sin() mut result := c1.sin()
// Some issue with precision comparison in f64 using == operator hence serializing to string // Some issue with precision comparison in f64 using == operator hence serializing to string
assert result.str().eq(c2.str()) assert result.str().eq(c2.str())
c1 = cmplx.complex(-3,4) c1 = cmplx.complex(-3, 4)
c2 = cmplx.complex(-3.853738,-27.016813) c2 = cmplx.complex(-3.853738, -27.016813)
result = c1.sin() result = c1.sin()
// Some issue with precision comparison in f64 using == operator hence serializing to string // Some issue with precision comparison in f64 using == operator hence serializing to string
assert result.str().eq(c2.str()) assert result.str().eq(c2.str())
c1 = cmplx.complex(-1,-2) c1 = cmplx.complex(-1, -2)
c2 = cmplx.complex(-3.165779,-1.959601) c2 = cmplx.complex(-3.165779, -1.959601)
result = c1.sin() result = c1.sin()
// Some issue with precision comparison in f64 using == operator hence serializing to string // Some issue with precision comparison in f64 using == operator hence serializing to string
assert result.str().eq(c2.str()) assert result.str().eq(c2.str())
@ -356,18 +355,18 @@ fn test_complex_sin() {
fn test_complex_cos() { fn test_complex_cos() {
// Tests were also verified on Wolfram Alpha // Tests were also verified on Wolfram Alpha
mut c1 := cmplx.complex(5,7) mut c1 := cmplx.complex(5, 7)
mut c2 := cmplx.complex(155.536809,525.793641) mut c2 := cmplx.complex(155.536809, 525.793641)
mut result := c1.cos() mut result := c1.cos()
// Some issue with precision comparison in f64 using == operator hence serializing to string // Some issue with precision comparison in f64 using == operator hence serializing to string
assert result.str().eq(c2.str()) assert result.str().eq(c2.str())
c1 = cmplx.complex(-3,4) c1 = cmplx.complex(-3, 4)
c2 = cmplx.complex(-27.034946,3.851153) c2 = cmplx.complex(-27.034946, 3.851153)
result = c1.cos() result = c1.cos()
// Some issue with precision comparison in f64 using == operator hence serializing to string // Some issue with precision comparison in f64 using == operator hence serializing to string
assert result.str().eq(c2.str()) assert result.str().eq(c2.str())
c1 = cmplx.complex(-1,-2) c1 = cmplx.complex(-1, -2)
c2 = cmplx.complex(2.032723,-3.051898) c2 = cmplx.complex(2.032723, -3.051898)
result = c1.cos() result = c1.cos()
// Some issue with precision comparison in f64 using == operator hence serializing to string // Some issue with precision comparison in f64 using == operator hence serializing to string
assert result.str().eq(c2.str()) assert result.str().eq(c2.str())
@ -375,18 +374,18 @@ fn test_complex_cos() {
fn test_complex_tan() { fn test_complex_tan() {
// Tests were also verified on Wolfram Alpha // Tests were also verified on Wolfram Alpha
mut c1 := cmplx.complex(5,7) mut c1 := cmplx.complex(5, 7)
mut c2 := cmplx.complex(-0.000001,1.000001) mut c2 := cmplx.complex(-0.000001, 1.000001)
mut result := c1.tan() mut result := c1.tan()
// Some issue with precision comparison in f64 using == operator hence serializing to string // Some issue with precision comparison in f64 using == operator hence serializing to string
assert result.str().eq(c2.str()) assert result.str().eq(c2.str())
c1 = cmplx.complex(-3,4) c1 = cmplx.complex(-3, 4)
c2 = cmplx.complex(0.000187,0.999356) c2 = cmplx.complex(0.000187, 0.999356)
result = c1.tan() result = c1.tan()
// Some issue with precision comparison in f64 using == operator hence serializing to string // Some issue with precision comparison in f64 using == operator hence serializing to string
assert result.str().eq(c2.str()) assert result.str().eq(c2.str())
c1 = cmplx.complex(-1,-2) c1 = cmplx.complex(-1, -2)
c2 = cmplx.complex(-0.033813,-1.014794) c2 = cmplx.complex(-0.033813, -1.014794)
result = c1.tan() result = c1.tan()
// Some issue with precision comparison in f64 using == operator hence serializing to string // Some issue with precision comparison in f64 using == operator hence serializing to string
assert result.str().eq(c2.str()) assert result.str().eq(c2.str())
@ -394,18 +393,18 @@ fn test_complex_tan() {
fn test_complex_cot() { fn test_complex_cot() {
// Tests were also verified on Wolfram Alpha // Tests were also verified on Wolfram Alpha
mut c1 := cmplx.complex(5,7) mut c1 := cmplx.complex(5, 7)
mut c2 := cmplx.complex(-0.000001,-0.999999) mut c2 := cmplx.complex(-0.000001, -0.999999)
mut result := c1.cot() mut result := c1.cot()
// Some issue with precision comparison in f64 using == operator hence serializing to string // Some issue with precision comparison in f64 using == operator hence serializing to string
assert result.str().eq(c2.str()) assert result.str().eq(c2.str())
c1 = cmplx.complex(-3,4) c1 = cmplx.complex(-3, 4)
c2 = cmplx.complex(0.000188,-1.000644) c2 = cmplx.complex(0.000188, -1.000644)
result = c1.cot() result = c1.cot()
// Some issue with precision comparison in f64 using == operator hence serializing to string // Some issue with precision comparison in f64 using == operator hence serializing to string
assert result.str().eq(c2.str()) assert result.str().eq(c2.str())
c1 = cmplx.complex(-1,-2) c1 = cmplx.complex(-1, -2)
c2 = cmplx.complex(-0.032798,0.984329) c2 = cmplx.complex(-0.032798, 0.984329)
result = c1.cot() result = c1.cot()
// Some issue with precision comparison in f64 using == operator hence serializing to string // Some issue with precision comparison in f64 using == operator hence serializing to string
assert result.str().eq(c2.str()) assert result.str().eq(c2.str())
@ -413,18 +412,18 @@ fn test_complex_cot() {
fn test_complex_sec() { fn test_complex_sec() {
// Tests were also verified on Wolfram Alpha // Tests were also verified on Wolfram Alpha
mut c1 := cmplx.complex(5,7) mut c1 := cmplx.complex(5, 7)
mut c2 := cmplx.complex(0.000517,-0.001749) mut c2 := cmplx.complex(0.000517, -0.001749)
mut result := c1.sec() mut result := c1.sec()
// Some issue with precision comparison in f64 using == operator hence serializing to string // Some issue with precision comparison in f64 using == operator hence serializing to string
assert result.str().eq(c2.str()) assert result.str().eq(c2.str())
c1 = cmplx.complex(-3,4) c1 = cmplx.complex(-3, 4)
c2 = cmplx.complex(-0.036253,-0.005164) c2 = cmplx.complex(-0.036253, -0.005164)
result = c1.sec() result = c1.sec()
// Some issue with precision comparison in f64 using == operator hence serializing to string // Some issue with precision comparison in f64 using == operator hence serializing to string
assert result.str().eq(c2.str()) assert result.str().eq(c2.str())
c1 = cmplx.complex(-1,-2) c1 = cmplx.complex(-1, -2)
c2 = cmplx.complex(0.151176,0.226974) c2 = cmplx.complex(0.151176, 0.226974)
result = c1.sec() result = c1.sec()
// Some issue with precision comparison in f64 using == operator hence serializing to string // Some issue with precision comparison in f64 using == operator hence serializing to string
assert result.str().eq(c2.str()) assert result.str().eq(c2.str())
@ -432,18 +431,18 @@ fn test_complex_sec() {
fn test_complex_csc() { fn test_complex_csc() {
// Tests were also verified on Wolfram Alpha // Tests were also verified on Wolfram Alpha
mut c1 := cmplx.complex(5,7) mut c1 := cmplx.complex(5, 7)
mut c2 := cmplx.complex(-0.001749,-0.000517) mut c2 := cmplx.complex(-0.001749, -0.000517)
mut result := c1.csc() mut result := c1.csc()
// Some issue with precision comparison in f64 using == operator hence serializing to string // Some issue with precision comparison in f64 using == operator hence serializing to string
assert result.str().eq(c2.str()) assert result.str().eq(c2.str())
c1 = cmplx.complex(-3,4) c1 = cmplx.complex(-3, 4)
c2 = cmplx.complex(-0.005174,0.036276) c2 = cmplx.complex(-0.005174, 0.036276)
result = c1.csc() result = c1.csc()
// Some issue with precision comparison in f64 using == operator hence serializing to string // Some issue with precision comparison in f64 using == operator hence serializing to string
assert result.str().eq(c2.str()) assert result.str().eq(c2.str())
c1 = cmplx.complex(-1,-2) c1 = cmplx.complex(-1, -2)
c2 = cmplx.complex(-0.228375,0.141363) c2 = cmplx.complex(-0.228375, 0.141363)
result = c1.csc() result = c1.csc()
// Some issue with precision comparison in f64 using == operator hence serializing to string // Some issue with precision comparison in f64 using == operator hence serializing to string
assert result.str().eq(c2.str()) assert result.str().eq(c2.str())
@ -451,18 +450,18 @@ fn test_complex_csc() {
fn test_complex_asin() { fn test_complex_asin() {
// Tests were also verified on Wolfram Alpha // Tests were also verified on Wolfram Alpha
mut c1 := cmplx.complex(5,7) mut c1 := cmplx.complex(5, 7)
mut c2 := cmplx.complex(0.617064,2.846289) mut c2 := cmplx.complex(0.617064, 2.846289)
mut result := c1.asin() mut result := c1.asin()
// Some issue with precision comparison in f64 using == operator hence serializing to string // Some issue with precision comparison in f64 using == operator hence serializing to string
assert result.str().eq(c2.str()) assert result.str().eq(c2.str())
c1 = cmplx.complex(-3,4) c1 = cmplx.complex(-3, 4)
c2 = cmplx.complex(-0.633984,2.305509) c2 = cmplx.complex(-0.633984, 2.305509)
result = c1.asin() result = c1.asin()
// Some issue with precision comparison in f64 using == operator hence serializing to string // Some issue with precision comparison in f64 using == operator hence serializing to string
assert result.str().eq(c2.str()) assert result.str().eq(c2.str())
c1 = cmplx.complex(-1,-2) c1 = cmplx.complex(-1, -2)
c2 = cmplx.complex(-0.427079,-1.528571) c2 = cmplx.complex(-0.427079, -1.528571)
result = c1.asin() result = c1.asin()
// Some issue with precision comparison in f64 using == operator hence serializing to string // Some issue with precision comparison in f64 using == operator hence serializing to string
assert result.str().eq(c2.str()) assert result.str().eq(c2.str())
@ -470,18 +469,18 @@ fn test_complex_asin() {
fn test_complex_acos() { fn test_complex_acos() {
// Tests were also verified on Wolfram Alpha // Tests were also verified on Wolfram Alpha
mut c1 := cmplx.complex(5,7) mut c1 := cmplx.complex(5, 7)
mut c2 := cmplx.complex(0.953732,-2.846289) mut c2 := cmplx.complex(0.953732, -2.846289)
mut result := c1.acos() mut result := c1.acos()
// Some issue with precision comparison in f64 using == operator hence serializing to string // Some issue with precision comparison in f64 using == operator hence serializing to string
assert result.str().eq(c2.str()) assert result.str().eq(c2.str())
c1 = cmplx.complex(-3,4) c1 = cmplx.complex(-3, 4)
c2 = cmplx.complex(2.204780,-2.305509) c2 = cmplx.complex(2.204780, -2.305509)
result = c1.acos() result = c1.acos()
// Some issue with precision comparison in f64 using == operator hence serializing to string // Some issue with precision comparison in f64 using == operator hence serializing to string
assert result.str().eq(c2.str()) assert result.str().eq(c2.str())
c1 = cmplx.complex(-1,-2) c1 = cmplx.complex(-1, -2)
c2 = cmplx.complex(1.997875,1.528571) c2 = cmplx.complex(1.997875, 1.528571)
result = c1.acos() result = c1.acos()
// Some issue with precision comparison in f64 using == operator hence serializing to string // Some issue with precision comparison in f64 using == operator hence serializing to string
assert result.str().eq(c2.str()) assert result.str().eq(c2.str())
@ -489,18 +488,18 @@ fn test_complex_acos() {
fn test_complex_atan() { fn test_complex_atan() {
// Tests were also verified on Wolfram Alpha // Tests were also verified on Wolfram Alpha
mut c1 := cmplx.complex(5,7) mut c1 := cmplx.complex(5, 7)
mut c2 := cmplx.complex(1.502727,0.094441) mut c2 := cmplx.complex(1.502727, 0.094441)
mut result := c1.atan() mut result := c1.atan()
// Some issue with precision comparison in f64 using == operator hence serializing to string // Some issue with precision comparison in f64 using == operator hence serializing to string
assert result.str().eq(c2.str()) assert result.str().eq(c2.str())
c1 = cmplx.complex(-3,4) c1 = cmplx.complex(-3, 4)
c2 = cmplx.complex(-1.448307,0.158997) c2 = cmplx.complex(-1.448307, 0.158997)
result = c1.atan() result = c1.atan()
// Some issue with precision comparison in f64 using == operator hence serializing to string // Some issue with precision comparison in f64 using == operator hence serializing to string
assert result.str().eq(c2.str()) assert result.str().eq(c2.str())
c1 = cmplx.complex(-1,-2) c1 = cmplx.complex(-1, -2)
c2 = cmplx.complex(-1.338973,-0.402359) c2 = cmplx.complex(-1.338973, -0.402359)
result = c1.atan() result = c1.atan()
// Some issue with precision comparison in f64 using == operator hence serializing to string // Some issue with precision comparison in f64 using == operator hence serializing to string
assert result.str().eq(c2.str()) assert result.str().eq(c2.str())
@ -508,18 +507,18 @@ fn test_complex_atan() {
fn test_complex_acot() { fn test_complex_acot() {
// Tests were also verified on Wolfram Alpha // Tests were also verified on Wolfram Alpha
mut c1 := cmplx.complex(5,7) mut c1 := cmplx.complex(5, 7)
mut c2 := cmplx.complex(0.068069,-0.094441) mut c2 := cmplx.complex(0.068069, -0.094441)
mut result := c1.acot() mut result := c1.acot()
// Some issue with precision comparison in f64 using == operator hence serializing to string // Some issue with precision comparison in f64 using == operator hence serializing to string
assert result.str().eq(c2.str()) assert result.str().eq(c2.str())
c1 = cmplx.complex(-3,4) c1 = cmplx.complex(-3, 4)
c2 = cmplx.complex(-0.122489,-0.158997) c2 = cmplx.complex(-0.122489, -0.158997)
result = c1.acot() result = c1.acot()
// Some issue with precision comparison in f64 using == operator hence serializing to string // Some issue with precision comparison in f64 using == operator hence serializing to string
assert result.str().eq(c2.str()) assert result.str().eq(c2.str())
c1 = cmplx.complex(-1,-2) c1 = cmplx.complex(-1, -2)
c2 = cmplx.complex(-0.231824,0.402359) c2 = cmplx.complex(-0.231824, 0.402359)
result = c1.acot() result = c1.acot()
// Some issue with precision comparison in f64 using == operator hence serializing to string // Some issue with precision comparison in f64 using == operator hence serializing to string
assert result.str().eq(c2.str()) assert result.str().eq(c2.str())
@ -527,18 +526,18 @@ fn test_complex_acot() {
fn test_complex_asec() { fn test_complex_asec() {
// Tests were also verified on Wolfram Alpha // Tests were also verified on Wolfram Alpha
mut c1 := cmplx.complex(5,7) mut c1 := cmplx.complex(5, 7)
mut c2 := cmplx.complex(1.503480,0.094668) mut c2 := cmplx.complex(1.503480, 0.094668)
mut result := c1.asec() mut result := c1.asec()
// Some issue with precision comparison in f64 using == operator hence serializing to string // Some issue with precision comparison in f64 using == operator hence serializing to string
assert result.str().eq(c2.str()) assert result.str().eq(c2.str())
c1 = cmplx.complex(-3,4) c1 = cmplx.complex(-3, 4)
c2 = cmplx.complex(1.689547,0.160446) c2 = cmplx.complex(1.689547, 0.160446)
result = c1.asec() result = c1.asec()
// Some issue with precision comparison in f64 using == operator hence serializing to string // Some issue with precision comparison in f64 using == operator hence serializing to string
assert result.str().eq(c2.str()) assert result.str().eq(c2.str())
c1 = cmplx.complex(-1,-2) c1 = cmplx.complex(-1, -2)
c2 = cmplx.complex(1.757114,-0.396568) c2 = cmplx.complex(1.757114, -0.396568)
result = c1.asec() result = c1.asec()
// Some issue with precision comparison in f64 using == operator hence serializing to string // Some issue with precision comparison in f64 using == operator hence serializing to string
assert result.str().eq(c2.str()) assert result.str().eq(c2.str())
@ -546,18 +545,18 @@ fn test_complex_asec() {
fn test_complex_acsc() { fn test_complex_acsc() {
// Tests were also verified on Wolfram Alpha // Tests were also verified on Wolfram Alpha
mut c1 := cmplx.complex(5,7) mut c1 := cmplx.complex(5, 7)
mut c2 := cmplx.complex(0.067317,-0.094668) mut c2 := cmplx.complex(0.067317, -0.094668)
mut result := c1.acsc() mut result := c1.acsc()
// Some issue with precision comparison in f64 using == operator hence serializing to string // Some issue with precision comparison in f64 using == operator hence serializing to string
assert result.str().eq(c2.str()) assert result.str().eq(c2.str())
c1 = cmplx.complex(-3,4) c1 = cmplx.complex(-3, 4)
c2 = cmplx.complex(-0.118751,-0.160446) c2 = cmplx.complex(-0.118751, -0.160446)
result = c1.acsc() result = c1.acsc()
// Some issue with precision comparison in f64 using == operator hence serializing to string // Some issue with precision comparison in f64 using == operator hence serializing to string
assert result.str().eq(c2.str()) assert result.str().eq(c2.str())
c1 = cmplx.complex(-1,-2) c1 = cmplx.complex(-1, -2)
c2 = cmplx.complex(-0.186318,0.396568) c2 = cmplx.complex(-0.186318, 0.396568)
result = c1.acsc() result = c1.acsc()
// Some issue with precision comparison in f64 using == operator hence serializing to string // Some issue with precision comparison in f64 using == operator hence serializing to string
assert result.str().eq(c2.str()) assert result.str().eq(c2.str())
@ -565,18 +564,18 @@ fn test_complex_acsc() {
fn test_complex_sinh() { fn test_complex_sinh() {
// Tests were also verified on Wolfram Alpha // Tests were also verified on Wolfram Alpha
mut c1 := cmplx.complex(5,7) mut c1 := cmplx.complex(5, 7)
mut c2 := cmplx.complex(55.941968,48.754942) mut c2 := cmplx.complex(55.941968, 48.754942)
mut result := c1.sinh() mut result := c1.sinh()
// Some issue with precision comparison in f64 using == operator hence serializing to string // Some issue with precision comparison in f64 using == operator hence serializing to string
assert result.str().eq(c2.str()) assert result.str().eq(c2.str())
c1 = cmplx.complex(-3,4) c1 = cmplx.complex(-3, 4)
c2 = cmplx.complex(6.548120,-7.619232) c2 = cmplx.complex(6.548120, -7.619232)
result = c1.sinh() result = c1.sinh()
// Some issue with precision comparison in f64 using == operator hence serializing to string // Some issue with precision comparison in f64 using == operator hence serializing to string
assert result.str().eq(c2.str()) assert result.str().eq(c2.str())
c1 = cmplx.complex(-1,-2) c1 = cmplx.complex(-1, -2)
c2 = cmplx.complex(0.489056,-1.403119) c2 = cmplx.complex(0.489056, -1.403119)
result = c1.sinh() result = c1.sinh()
// Some issue with precision comparison in f64 using == operator hence serializing to string // Some issue with precision comparison in f64 using == operator hence serializing to string
assert result.str().eq(c2.str()) assert result.str().eq(c2.str())
@ -584,18 +583,18 @@ fn test_complex_sinh() {
fn test_complex_cosh() { fn test_complex_cosh() {
// Tests were also verified on Wolfram Alpha // Tests were also verified on Wolfram Alpha
mut c1 := cmplx.complex(5,7) mut c1 := cmplx.complex(5, 7)
mut c2 := cmplx.complex(55.947047,48.750515) mut c2 := cmplx.complex(55.947047, 48.750515)
mut result := c1.cosh() mut result := c1.cosh()
// Some issue with precision comparison in f64 using == operator hence serializing to string // Some issue with precision comparison in f64 using == operator hence serializing to string
assert result.str().eq(c2.str()) assert result.str().eq(c2.str())
c1 = cmplx.complex(-3,4) c1 = cmplx.complex(-3, 4)
c2 = cmplx.complex(-6.580663,7.581553) c2 = cmplx.complex(-6.580663, 7.581553)
result = c1.cosh() result = c1.cosh()
// Some issue with precision comparison in f64 using == operator hence serializing to string // Some issue with precision comparison in f64 using == operator hence serializing to string
assert result.str().eq(c2.str()) assert result.str().eq(c2.str())
c1 = cmplx.complex(-1,-2) c1 = cmplx.complex(-1, -2)
c2 = cmplx.complex(-0.642148,1.068607) c2 = cmplx.complex(-0.642148, 1.068607)
result = c1.cosh() result = c1.cosh()
// Some issue with precision comparison in f64 using == operator hence serializing to string // Some issue with precision comparison in f64 using == operator hence serializing to string
assert result.str().eq(c2.str()) assert result.str().eq(c2.str())
@ -603,18 +602,18 @@ fn test_complex_cosh() {
fn test_complex_tanh() { fn test_complex_tanh() {
// Tests were also verified on Wolfram Alpha // Tests were also verified on Wolfram Alpha
mut c1 := cmplx.complex(5,7) mut c1 := cmplx.complex(5, 7)
mut c2 := cmplx.complex(0.999988,0.000090) mut c2 := cmplx.complex(0.999988, 0.000090)
mut result := c1.tanh() mut result := c1.tanh()
// Some issue with precision comparison in f64 using == operator hence serializing to string // Some issue with precision comparison in f64 using == operator hence serializing to string
assert result.str().eq(c2.str()) assert result.str().eq(c2.str())
c1 = cmplx.complex(-3,4) c1 = cmplx.complex(-3, 4)
c2 = cmplx.complex(-1.000710,0.004908) c2 = cmplx.complex(-1.000710, 0.004908)
result = c1.tanh() result = c1.tanh()
// Some issue with precision comparison in f64 using == operator hence serializing to string // Some issue with precision comparison in f64 using == operator hence serializing to string
assert result.str().eq(c2.str()) assert result.str().eq(c2.str())
c1 = cmplx.complex(-1,-2) c1 = cmplx.complex(-1, -2)
c2 = cmplx.complex(-1.166736,0.243458) c2 = cmplx.complex(-1.166736, 0.243458)
result = c1.tanh() result = c1.tanh()
// Some issue with precision comparison in f64 using == operator hence serializing to string // Some issue with precision comparison in f64 using == operator hence serializing to string
assert result.str().eq(c2.str()) assert result.str().eq(c2.str())
@ -622,18 +621,18 @@ fn test_complex_tanh() {
fn test_complex_coth() { fn test_complex_coth() {
// Tests were also verified on Wolfram Alpha // Tests were also verified on Wolfram Alpha
mut c1 := cmplx.complex(5,7) mut c1 := cmplx.complex(5, 7)
mut c2 := cmplx.complex(1.000012,-0.000090) mut c2 := cmplx.complex(1.000012, -0.000090)
mut result := c1.coth() mut result := c1.coth()
// Some issue with precision comparison in f64 using == operator hence serializing to string // Some issue with precision comparison in f64 using == operator hence serializing to string
assert result.str().eq(c2.str()) assert result.str().eq(c2.str())
c1 = cmplx.complex(-3,4) c1 = cmplx.complex(-3, 4)
c2 = cmplx.complex(-0.999267,-0.004901) c2 = cmplx.complex(-0.999267, -0.004901)
result = c1.coth() result = c1.coth()
// Some issue with precision comparison in f64 using == operator hence serializing to string // Some issue with precision comparison in f64 using == operator hence serializing to string
assert result.str().eq(c2.str()) assert result.str().eq(c2.str())
c1 = cmplx.complex(-1,-2) c1 = cmplx.complex(-1, -2)
c2 = cmplx.complex(-0.821330,-0.171384) c2 = cmplx.complex(-0.821330, -0.171384)
result = c1.coth() result = c1.coth()
// Some issue with precision comparison in f64 using == operator hence serializing to string // Some issue with precision comparison in f64 using == operator hence serializing to string
assert result.str().eq(c2.str()) assert result.str().eq(c2.str())
@ -641,18 +640,18 @@ fn test_complex_coth() {
fn test_complex_sech() { fn test_complex_sech() {
// Tests were also verified on Wolfram Alpha // Tests were also verified on Wolfram Alpha
mut c1 := cmplx.complex(5,7) mut c1 := cmplx.complex(5, 7)
mut c2 := cmplx.complex(0.010160,-0.008853) mut c2 := cmplx.complex(0.010160, -0.008853)
mut result := c1.sech() mut result := c1.sech()
// Some issue with precision comparison in f64 using == operator hence serializing to string // Some issue with precision comparison in f64 using == operator hence serializing to string
assert result.str().eq(c2.str()) assert result.str().eq(c2.str())
c1 = cmplx.complex(-3,4) c1 = cmplx.complex(-3, 4)
c2 = cmplx.complex(-0.065294,-0.075225) c2 = cmplx.complex(-0.065294, -0.075225)
result = c1.sech() result = c1.sech()
// Some issue with precision comparison in f64 using == operator hence serializing to string // Some issue with precision comparison in f64 using == operator hence serializing to string
assert result.str().eq(c2.str()) assert result.str().eq(c2.str())
c1 = cmplx.complex(-1,-2) c1 = cmplx.complex(-1, -2)
c2 = cmplx.complex(-0.413149,-0.687527) c2 = cmplx.complex(-0.413149, -0.687527)
result = c1.sech() result = c1.sech()
// Some issue with precision comparison in f64 using == operator hence serializing to string // Some issue with precision comparison in f64 using == operator hence serializing to string
assert result.str().eq(c2.str()) assert result.str().eq(c2.str())
@ -660,18 +659,18 @@ fn test_complex_sech() {
fn test_complex_csch() { fn test_complex_csch() {
// Tests were also verified on Wolfram Alpha // Tests were also verified on Wolfram Alpha
mut c1 := cmplx.complex(5,7) mut c1 := cmplx.complex(5, 7)
mut c2 := cmplx.complex(0.010159,-0.008854) mut c2 := cmplx.complex(0.010159, -0.008854)
mut result := c1.csch() mut result := c1.csch()
// Some issue with precision comparison in f64 using == operator hence serializing to string // Some issue with precision comparison in f64 using == operator hence serializing to string
assert result.str().eq(c2.str()) assert result.str().eq(c2.str())
c1 = cmplx.complex(-3,4) c1 = cmplx.complex(-3, 4)
c2 = cmplx.complex(0.064877,0.075490) c2 = cmplx.complex(0.064877, 0.075490)
result = c1.csch() result = c1.csch()
// Some issue with precision comparison in f64 using == operator hence serializing to string // Some issue with precision comparison in f64 using == operator hence serializing to string
assert result.str().eq(c2.str()) assert result.str().eq(c2.str())
c1 = cmplx.complex(-1,-2) c1 = cmplx.complex(-1, -2)
c2 = cmplx.complex(0.221501,0.635494) c2 = cmplx.complex(0.221501, 0.635494)
result = c1.csch() result = c1.csch()
// Some issue with precision comparison in f64 using == operator hence serializing to string // Some issue with precision comparison in f64 using == operator hence serializing to string
assert result.str().eq(c2.str()) assert result.str().eq(c2.str())
@ -679,18 +678,18 @@ fn test_complex_csch() {
fn test_complex_asinh() { fn test_complex_asinh() {
// Tests were also verified on Wolfram Alpha // Tests were also verified on Wolfram Alpha
mut c1 := cmplx.complex(5,7) mut c1 := cmplx.complex(5, 7)
mut c2 := cmplx.complex(2.844098,0.947341) mut c2 := cmplx.complex(2.844098, 0.947341)
mut result := c1.asinh() mut result := c1.asinh()
// Some issue with precision comparison in f64 using == operator hence serializing to string // Some issue with precision comparison in f64 using == operator hence serializing to string
assert result.str().eq(c2.str()) assert result.str().eq(c2.str())
c1 = cmplx.complex(-3,4) c1 = cmplx.complex(-3, 4)
c2 = cmplx.complex(-2.299914,0.917617) c2 = cmplx.complex(-2.299914, 0.917617)
result = c1.asinh() result = c1.asinh()
// Some issue with precision comparison in f64 using == operator hence serializing to string // Some issue with precision comparison in f64 using == operator hence serializing to string
assert result.str().eq(c2.str()) assert result.str().eq(c2.str())
c1 = cmplx.complex(-1,-2) c1 = cmplx.complex(-1, -2)
c2 = cmplx.complex(-1.469352,-1.063440) c2 = cmplx.complex(-1.469352, -1.063440)
result = c1.asinh() result = c1.asinh()
// Some issue with precision comparison in f64 using == operator hence serializing to string // Some issue with precision comparison in f64 using == operator hence serializing to string
assert result.str().eq(c2.str()) assert result.str().eq(c2.str())
@ -698,18 +697,18 @@ fn test_complex_asinh() {
fn test_complex_acosh() { fn test_complex_acosh() {
// Tests were also verified on Wolfram Alpha // Tests were also verified on Wolfram Alpha
mut c1 := cmplx.complex(5,7) mut c1 := cmplx.complex(5, 7)
mut c2 := cmplx.complex(2.846289,0.953732) mut c2 := cmplx.complex(2.846289, 0.953732)
mut result := c1.acosh() mut result := c1.acosh()
// Some issue with precision comparison in f64 using == operator hence serializing to string // Some issue with precision comparison in f64 using == operator hence serializing to string
assert result.str().eq(c2.str()) assert result.str().eq(c2.str())
c1 = cmplx.complex(-3,4) c1 = cmplx.complex(-3, 4)
c2 = cmplx.complex(2.305509,2.204780) c2 = cmplx.complex(2.305509, 2.204780)
result = c1.acosh() result = c1.acosh()
// Some issue with precision comparison in f64 using == operator hence serializing to string // Some issue with precision comparison in f64 using == operator hence serializing to string
assert result.str().eq(c2.str()) assert result.str().eq(c2.str())
c1 = cmplx.complex(-1,-2) c1 = cmplx.complex(-1, -2)
c2 = cmplx.complex(1.528571,-1.997875) c2 = cmplx.complex(1.528571, -1.997875)
result = c1.acosh() result = c1.acosh()
// Some issue with precision comparison in f64 using == operator hence serializing to string // Some issue with precision comparison in f64 using == operator hence serializing to string
assert result.str().eq(c2.str()) assert result.str().eq(c2.str())
@ -717,18 +716,18 @@ fn test_complex_acosh() {
fn test_complex_atanh() { fn test_complex_atanh() {
// Tests were also verified on Wolfram Alpha // Tests were also verified on Wolfram Alpha
mut c1 := cmplx.complex(5,7) mut c1 := cmplx.complex(5, 7)
mut c2 := cmplx.complex(0.067066,1.476056) mut c2 := cmplx.complex(0.067066, 1.476056)
mut result := c1.atanh() mut result := c1.atanh()
// Some issue with precision comparison in f64 using == operator hence serializing to string // Some issue with precision comparison in f64 using == operator hence serializing to string
assert result.str().eq(c2.str()) assert result.str().eq(c2.str())
c1 = cmplx.complex(-3,4) c1 = cmplx.complex(-3, 4)
c2 = cmplx.complex(-0.117501,1.409921) c2 = cmplx.complex(-0.117501, 1.409921)
result = c1.atanh() result = c1.atanh()
// Some issue with precision comparison in f64 using == operator hence serializing to string // Some issue with precision comparison in f64 using == operator hence serializing to string
assert result.str().eq(c2.str()) assert result.str().eq(c2.str())
c1 = cmplx.complex(-1,-2) c1 = cmplx.complex(-1, -2)
c2 = cmplx.complex(-0.173287,-1.178097) c2 = cmplx.complex(-0.173287, -1.178097)
result = c1.atanh() result = c1.atanh()
// Some issue with precision comparison in f64 using == operator hence serializing to string // Some issue with precision comparison in f64 using == operator hence serializing to string
assert result.str().eq(c2.str()) assert result.str().eq(c2.str())
@ -736,18 +735,18 @@ fn test_complex_atanh() {
fn test_complex_acoth() { fn test_complex_acoth() {
// Tests were also verified on Wolfram Alpha // Tests were also verified on Wolfram Alpha
mut c1 := cmplx.complex(5,7) mut c1 := cmplx.complex(5, 7)
mut c2 := cmplx.complex(0.067066,-0.094740) mut c2 := cmplx.complex(0.067066, -0.094740)
mut result := c1.acoth() mut result := c1.acoth()
// Some issue with precision comparison in f64 using == operator hence serializing to string // Some issue with precision comparison in f64 using == operator hence serializing to string
assert result.str().eq(c2.str()) assert result.str().eq(c2.str())
c1 = cmplx.complex(-3,4) c1 = cmplx.complex(-3, 4)
c2 = cmplx.complex(-0.117501,-0.160875) c2 = cmplx.complex(-0.117501, -0.160875)
result = c1.acoth() result = c1.acoth()
// Some issue with precision comparison in f64 using == operator hence serializing to string // Some issue with precision comparison in f64 using == operator hence serializing to string
assert result.str().eq(c2.str()) assert result.str().eq(c2.str())
c1 = cmplx.complex(-1,-2) c1 = cmplx.complex(-1, -2)
c2 = cmplx.complex(-0.173287,0.392699) c2 = cmplx.complex(-0.173287, 0.392699)
result = c1.acoth() result = c1.acoth()
// Some issue with precision comparison in f64 using == operator hence serializing to string // Some issue with precision comparison in f64 using == operator hence serializing to string
assert result.str().eq(c2.str()) assert result.str().eq(c2.str())
@ -774,18 +773,18 @@ fn test_complex_acoth() {
fn test_complex_acsch() { fn test_complex_acsch() {
// Tests were also verified on Wolfram Alpha // Tests were also verified on Wolfram Alpha
mut c1 := cmplx.complex(5,7) mut c1 := cmplx.complex(5, 7)
mut c2 := cmplx.complex(0.067819,-0.094518) mut c2 := cmplx.complex(0.067819, -0.094518)
mut result := c1.acsch() mut result := c1.acsch()
// Some issue with precision comparison in f64 using == operator hence serializing to string // Some issue with precision comparison in f64 using == operator hence serializing to string
assert result.str().eq(c2.str()) assert result.str().eq(c2.str())
c1 = cmplx.complex(-3,4) c1 = cmplx.complex(-3, 4)
c2 = cmplx.complex(-0.121246,-0.159507) c2 = cmplx.complex(-0.121246, -0.159507)
result = c1.acsch() result = c1.acsch()
// Some issue with precision comparison in f64 using == operator hence serializing to string // Some issue with precision comparison in f64 using == operator hence serializing to string
assert result.str().eq(c2.str()) assert result.str().eq(c2.str())
c1 = cmplx.complex(-1,-2) c1 = cmplx.complex(-1, -2)
c2 = cmplx.complex(-0.215612,0.401586) c2 = cmplx.complex(-0.215612, 0.401586)
result = c1.acsch() result = c1.acsch()
// Some issue with precision comparison in f64 using == operator hence serializing to string // Some issue with precision comparison in f64 using == operator hence serializing to string
assert result.str().eq(c2.str()) assert result.str().eq(c2.str())

View File

@ -4,33 +4,35 @@
module math module math
pub const ( pub const (
e = 2.71828182845904523536028747135266249775724709369995957496696763 e = 2.71828182845904523536028747135266249775724709369995957496696763
pi = 3.14159265358979323846264338327950288419716939937510582097494459 pi = 3.14159265358979323846264338327950288419716939937510582097494459
phi = 1.61803398874989484820458683436563811772030917980576286213544862 phi = 1.61803398874989484820458683436563811772030917980576286213544862
tau = 6.28318530717958647692528676655900576839433879875021164194988918 tau = 6.28318530717958647692528676655900576839433879875021164194988918
sqrt2 = 1.41421356237309504880168872420969807856967187537694807317667974 sqrt2 = 1.41421356237309504880168872420969807856967187537694807317667974
sqrt_e = 1.64872127070012814684865078781416357165377610071014801157507931 sqrt_e = 1.64872127070012814684865078781416357165377610071014801157507931
sqrt_pi = 1.77245385090551602729816748334114518279754945612238712821380779 sqrt_pi = 1.77245385090551602729816748334114518279754945612238712821380779
sqrt_tau = 2.50662827463100050241576528481104525300698674060993831662992357 sqrt_tau = 2.50662827463100050241576528481104525300698674060993831662992357
sqrt_phi = 1.27201964951406896425242246173749149171560804184009624861664038 sqrt_phi = 1.27201964951406896425242246173749149171560804184009624861664038
ln2 = 0.693147180559945309417232121458176568075500134360255254120680009 ln2 = 0.693147180559945309417232121458176568075500134360255254120680009
log2_e = 1.0 / ln2 log2_e = 1.0 / ln2
ln10 = 2.30258509299404568401799145468436420760110148862877297603332790 ln10 = 2.30258509299404568401799145468436420760110148862877297603332790
log10_e = 1.0 / ln10 log10_e = 1.0 / ln10
) )
// Floating-point limit values // Floating-point limit values
// max is the largest finite value representable by the type. // max is the largest finite value representable by the type.
// smallest_non_zero is the smallest positive, non-zero value representable by the type. // smallest_non_zero is the smallest positive, non-zero value representable by the type.
pub const ( pub const (
max_f32 = 3.40282346638528859811704183484516925440e+38 // 2**127 * (2**24 - 1) / 2**23 max_f32 = 3.40282346638528859811704183484516925440e+38 // 2**127 * (2**24 - 1) / 2**23
smallest_non_zero_f32 = 1.401298464324817070923729583289916131280e-45 // 1 / 2**(127 - 1 + 23) smallest_non_zero_f32 = 1.401298464324817070923729583289916131280e-45 // 1 / 2**(127 - 1 + 23)
max_f64 = 1.797693134862315708145274237317043567981e+308 // 2**1023 * (2**53 - 1) / 2**52 max_f64 = 1.797693134862315708145274237317043567981e+308 // 2**1023 * (2**53 - 1) / 2**52
smallest_non_zero_f64 = 4.940656458412465441765687928682213723651e-324 // 1 / 2**(1023 - 1 + 52) smallest_non_zero_f64 = 4.940656458412465441765687928682213723651e-324 // 1 / 2**(1023 - 1 + 52)
) )
// Integer limit values // Integer limit values
pub const ( pub const (
max_i8 = 127 max_i8 = 127
min_i8 = -128 min_i8 = -128
max_i16 = 32767 max_i16 = 32767
min_i16 = -32768 min_i16 = -32768
max_i32 = 2147483647 max_i32 = 2147483647
@ -40,7 +42,7 @@ pub const (
// consecutive subtraction by 1 // consecutive subtraction by 1
min_i64 = i64(-9223372036854775807 - 1) min_i64 = i64(-9223372036854775807 - 1)
max_i64 = i64(9223372036854775807) max_i64 = i64(9223372036854775807)
max_u8 = 255 max_u8 = 255
max_u16 = 65535 max_u16 = 65535
max_u32 = u32(4294967295) max_u32 = u32(4294967295)
max_u64 = u64(18446744073709551615) max_u64 = u64(18446744073709551615)

View File

@ -14,7 +14,7 @@ pub fn factorial(n f64) f64 {
// For a large postive argument (n >= FACTORIALS.len) return max_f64 // For a large postive argument (n >= FACTORIALS.len) return max_f64
if n >= factorials_table.len { if n >= factorials_table.len {
return math.max_f64 return math.max_f64
} }
// Otherwise return n!. // Otherwise return n!.
@ -30,51 +30,51 @@ pub fn log_factorial(n f64) f64 {
// For a large postive argument (n < 0) return max_f64 // For a large postive argument (n < 0) return max_f64
if n < 0 { if n < 0 {
return -math.max_f64 return -math.max_f64
} }
// If n < N then return ln(n!). // If n < N then return ln(n!).
if n != f64(i64(n)) { if n != f64(i64(n)) {
return math.log_gamma(n+1) return math.log_gamma(n + 1)
} else if n < log_factorials_table.len { } else if n < log_factorials_table.len {
return log_factorials_table[i64(n)] return log_factorials_table[i64(n)]
} }
// Otherwise return asymptotic expansion of ln(n!). // Otherwise return asymptotic expansion of ln(n!).
return log_factorial_asymptotic_expansion(int(n)) return log_factorial_asymptotic_expansion(int(n))
} }
fn log_factorial_asymptotic_expansion(n int) f64 { fn log_factorial_asymptotic_expansion(n int) f64 {
m := 6 m := 6
mut term := []f64{} mut term := []f64{}
xx := f64((n + 1) * (n + 1)) xx := f64((n + 1) * (n + 1))
mut xj := f64(n + 1) mut xj := f64(n + 1)
log_factorial := log_sqrt_2pi - xj + (xj - 0.5) * math.log(xj) log_factorial := log_sqrt_2pi - xj + (xj - 0.5) * math.log(xj)
mut i := 0 mut i := 0
for i = 0; i < m; i++ { for i = 0; i < m; i++ {
term << b_numbers[i] / xj term << b_numbers[i] / xj
xj *= xx xj *= xx
} }
mut sum := term[m-1] mut sum := term[m - 1]
for i = m - 2; i >= 0; i-- { for i = m - 2; i >= 0; i-- {
if math.abs(sum) <= math.abs(term[i]) { if math.abs(sum) <= math.abs(term[i]) {
break break
} }
sum = term[i] sum = term[i]
} }
for i >= 0 { for i >= 0 {
sum += term[i] sum += term[i]
i-- i--
} }
return log_factorial + sum return log_factorial + sum
} }

View File

@ -5,370 +5,371 @@
module factorial module factorial
const ( const (
log_sqrt_2pi = 9.18938533204672741780329736e-1 log_sqrt_2pi = 9.18938533204672741780329736e-1
b_numbers = [ b_numbers = [
/* Bernoulli numbers B(2),B(4),B(6),...,B(20). Only B(2),...,B(10) currently /*
Bernoulli numbers B(2),B(4),B(6),...,B(20). Only B(2),...,B(10) currently
* used. * used.
*/ */
f64(1.0 / (6.0 * 2.0 * 1.0)), f64(1.0 / (6.0 * 2.0 * 1.0)),
-1.0 / (30.0 * 4.0 * 3.0), -1.0 / (30.0 * 4.0 * 3.0),
1.0 / (42.0 * 6.0 * 5.0), 1.0 / (42.0 * 6.0 * 5.0),
-1.0 / (30.0 * 8.0 * 7.0), -1.0 / (30.0 * 8.0 * 7.0),
5.0 / (66.0 * 10.0 * 9.0), 5.0 / (66.0 * 10.0 * 9.0),
-691.0 / (2730.0 * 12.0 * 11.0), -691.0 / (2730.0 * 12.0 * 11.0),
7.0 / (6.0 * 14.0 * 13.0), 7.0 / (6.0 * 14.0 * 13.0),
-3617.0 / (510.0 * 16.0 * 15.0), -3617.0 / (510.0 * 16.0 * 15.0),
43867.0 / (796.0 * 18.0 * 17.0), 43867.0 / (796.0 * 18.0 * 17.0),
-174611.0 / (330.0 * 20.0 * 19.0) -174611.0 / (330.0 * 20.0 * 19.0),
] ]
factorials_table = [ factorials_table = [
f64(1.000000000000000000000e+0), /* 0! */ f64(1.000000000000000000000e+0), /* 0! */
1.000000000000000000000e+0, /* 1! */ 1.000000000000000000000e+0, /* 1! */
2.000000000000000000000e+0, /* 2! */ 2.000000000000000000000e+0, /* 2! */
6.000000000000000000000e+0, /* 3! */ 6.000000000000000000000e+0, /* 3! */
2.400000000000000000000e+1, /* 4! */ 2.400000000000000000000e+1, /* 4! */
1.200000000000000000000e+2, /* 5! */ 1.200000000000000000000e+2, /* 5! */
7.200000000000000000000e+2, /* 6! */ 7.200000000000000000000e+2, /* 6! */
5.040000000000000000000e+3, /* 7! */ 5.040000000000000000000e+3, /* 7! */
4.032000000000000000000e+4, /* 8! */ 4.032000000000000000000e+4, /* 8! */
3.628800000000000000000e+5, /* 9! */ 3.628800000000000000000e+5, /* 9! */
3.628800000000000000000e+6, /* 10! */ 3.628800000000000000000e+6, /* 10! */
3.991680000000000000000e+7, /* 11! */ 3.991680000000000000000e+7, /* 11! */
4.790016000000000000000e+8, /* 12! */ 4.790016000000000000000e+8, /* 12! */
6.227020800000000000000e+9, /* 13! */ 6.227020800000000000000e+9, /* 13! */
8.717829120000000000000e+10, /* 14! */ 8.717829120000000000000e+10, /* 14! */
1.307674368000000000000e+12, /* 15! */ 1.307674368000000000000e+12, /* 15! */
2.092278988800000000000e+13, /* 16! */ 2.092278988800000000000e+13, /* 16! */
3.556874280960000000000e+14, /* 17! */ 3.556874280960000000000e+14, /* 17! */
6.402373705728000000000e+15, /* 18! */ 6.402373705728000000000e+15, /* 18! */
1.216451004088320000000e+17, /* 19! */ 1.216451004088320000000e+17, /* 19! */
2.432902008176640000000e+18, /* 20! */ 2.432902008176640000000e+18, /* 20! */
5.109094217170944000000e+19, /* 21! */ 5.109094217170944000000e+19, /* 21! */
1.124000727777607680000e+21, /* 22! */ 1.124000727777607680000e+21, /* 22! */
2.585201673888497664000e+22, /* 23! */ 2.585201673888497664000e+22, /* 23! */
6.204484017332394393600e+23, /* 24! */ 6.204484017332394393600e+23, /* 24! */
1.551121004333098598400e+25, /* 25! */ 1.551121004333098598400e+25, /* 25! */
4.032914611266056355840e+26, /* 26! */ 4.032914611266056355840e+26, /* 26! */
1.088886945041835216077e+28, /* 27! */ 1.088886945041835216077e+28, /* 27! */
3.048883446117138605015e+29, /* 28! */ 3.048883446117138605015e+29, /* 28! */
8.841761993739701954544e+30, /* 29! */ 8.841761993739701954544e+30, /* 29! */
2.652528598121910586363e+32, /* 30! */ 2.652528598121910586363e+32, /* 30! */
8.222838654177922817726e+33, /* 31! */ 8.222838654177922817726e+33, /* 31! */
2.631308369336935301672e+35, /* 32! */ 2.631308369336935301672e+35, /* 32! */
8.683317618811886495518e+36, /* 33! */ 8.683317618811886495518e+36, /* 33! */
2.952327990396041408476e+38, /* 34! */ 2.952327990396041408476e+38, /* 34! */
1.033314796638614492967e+40, /* 35! */ 1.033314796638614492967e+40, /* 35! */
3.719933267899012174680e+41, /* 36! */ 3.719933267899012174680e+41, /* 36! */
1.376375309122634504632e+43, /* 37! */ 1.376375309122634504632e+43, /* 37! */
5.230226174666011117600e+44, /* 38! */ 5.230226174666011117600e+44, /* 38! */
2.039788208119744335864e+46, /* 39! */ 2.039788208119744335864e+46, /* 39! */
8.159152832478977343456e+47, /* 40! */ 8.159152832478977343456e+47, /* 40! */
3.345252661316380710817e+49, /* 41! */ 3.345252661316380710817e+49, /* 41! */
1.405006117752879898543e+51, /* 42! */ 1.405006117752879898543e+51, /* 42! */
6.041526306337383563736e+52, /* 43! */ 6.041526306337383563736e+52, /* 43! */
2.658271574788448768044e+54, /* 44! */ 2.658271574788448768044e+54, /* 44! */
1.196222208654801945620e+56, /* 45! */ 1.196222208654801945620e+56, /* 45! */
5.502622159812088949850e+57, /* 46! */ 5.502622159812088949850e+57, /* 46! */
2.586232415111681806430e+59, /* 47! */ 2.586232415111681806430e+59, /* 47! */
1.241391559253607267086e+61, /* 48! */ 1.241391559253607267086e+61, /* 48! */
6.082818640342675608723e+62, /* 49! */ 6.082818640342675608723e+62, /* 49! */
3.041409320171337804361e+64, /* 50! */ 3.041409320171337804361e+64, /* 50! */
1.551118753287382280224e+66, /* 51! */ 1.551118753287382280224e+66, /* 51! */
8.065817517094387857166e+67, /* 52! */ 8.065817517094387857166e+67, /* 52! */
4.274883284060025564298e+69, /* 53! */ 4.274883284060025564298e+69, /* 53! */
2.308436973392413804721e+71, /* 54! */ 2.308436973392413804721e+71, /* 54! */
1.269640335365827592597e+73, /* 55! */ 1.269640335365827592597e+73, /* 55! */
7.109985878048634518540e+74, /* 56! */ 7.109985878048634518540e+74, /* 56! */
4.052691950487721675568e+76, /* 57! */ 4.052691950487721675568e+76, /* 57! */
2.350561331282878571829e+78, /* 58! */ 2.350561331282878571829e+78, /* 58! */
1.386831185456898357379e+80, /* 59! */ 1.386831185456898357379e+80, /* 59! */
8.320987112741390144276e+81, /* 60! */ 8.320987112741390144276e+81, /* 60! */
5.075802138772247988009e+83, /* 61! */ 5.075802138772247988009e+83, /* 61! */
3.146997326038793752565e+85, /* 62! */ 3.146997326038793752565e+85, /* 62! */
1.982608315404440064116e+87, /* 63! */ 1.982608315404440064116e+87, /* 63! */
1.268869321858841641034e+89, /* 64! */ 1.268869321858841641034e+89, /* 64! */
8.247650592082470666723e+90, /* 65! */ 8.247650592082470666723e+90, /* 65! */
5.443449390774430640037e+92, /* 66! */ 5.443449390774430640037e+92, /* 66! */
3.647111091818868528825e+94, /* 67! */ 3.647111091818868528825e+94, /* 67! */
2.480035542436830599601e+96, /* 68! */ 2.480035542436830599601e+96, /* 68! */
1.711224524281413113725e+98, /* 69! */ 1.711224524281413113725e+98, /* 69! */
1.197857166996989179607e+100, /* 70! */ 1.197857166996989179607e+100, /* 70! */
8.504785885678623175212e+101, /* 71! */ 8.504785885678623175212e+101, /* 71! */
6.123445837688608686152e+103, /* 72! */ 6.123445837688608686152e+103, /* 72! */
4.470115461512684340891e+105, /* 73! */ 4.470115461512684340891e+105, /* 73! */
3.307885441519386412260e+107, /* 74! */ 3.307885441519386412260e+107, /* 74! */
2.480914081139539809195e+109, /* 75! */ 2.480914081139539809195e+109, /* 75! */
1.885494701666050254988e+111, /* 76! */ 1.885494701666050254988e+111, /* 76! */
1.451830920282858696341e+113, /* 77! */ 1.451830920282858696341e+113, /* 77! */
1.132428117820629783146e+115, /* 78! */ 1.132428117820629783146e+115, /* 78! */
8.946182130782975286851e+116, /* 79! */ 8.946182130782975286851e+116, /* 79! */
7.156945704626380229481e+118, /* 80! */ 7.156945704626380229481e+118, /* 80! */
5.797126020747367985880e+120, /* 81! */ 5.797126020747367985880e+120, /* 81! */
4.753643337012841748421e+122, /* 82! */ 4.753643337012841748421e+122, /* 82! */
3.945523969720658651190e+124, /* 83! */ 3.945523969720658651190e+124, /* 83! */
3.314240134565353266999e+126, /* 84! */ 3.314240134565353266999e+126, /* 84! */
2.817104114380550276949e+128, /* 85! */ 2.817104114380550276949e+128, /* 85! */
2.422709538367273238177e+130, /* 86! */ 2.422709538367273238177e+130, /* 86! */
2.107757298379527717214e+132, /* 87! */ 2.107757298379527717214e+132, /* 87! */
1.854826422573984391148e+134, /* 88! */ 1.854826422573984391148e+134, /* 88! */
1.650795516090846108122e+136, /* 89! */ 1.650795516090846108122e+136, /* 89! */
1.485715964481761497310e+138, /* 90! */ 1.485715964481761497310e+138, /* 90! */
1.352001527678402962552e+140, /* 91! */ 1.352001527678402962552e+140, /* 91! */
1.243841405464130725548e+142, /* 92! */ 1.243841405464130725548e+142, /* 92! */
1.156772507081641574759e+144, /* 93! */ 1.156772507081641574759e+144, /* 93! */
1.087366156656743080274e+146, /* 94! */ 1.087366156656743080274e+146, /* 94! */
1.032997848823905926260e+148, /* 95! */ 1.032997848823905926260e+148, /* 95! */
9.916779348709496892096e+149, /* 96! */ 9.916779348709496892096e+149, /* 96! */
9.619275968248211985333e+151, /* 97! */ 9.619275968248211985333e+151, /* 97! */
9.426890448883247745626e+153, /* 98! */ 9.426890448883247745626e+153, /* 98! */
9.332621544394415268170e+155, /* 99! */ 9.332621544394415268170e+155, /* 99! */
9.332621544394415268170e+157, /* 100! */ 9.332621544394415268170e+157, /* 100! */
9.425947759838359420852e+159, /* 101! */ 9.425947759838359420852e+159, /* 101! */
9.614466715035126609269e+161, /* 102! */ 9.614466715035126609269e+161, /* 102! */
9.902900716486180407547e+163, /* 103! */ 9.902900716486180407547e+163, /* 103! */
1.029901674514562762385e+166, /* 104! */ 1.029901674514562762385e+166, /* 104! */
1.081396758240290900504e+168, /* 105! */ 1.081396758240290900504e+168, /* 105! */
1.146280563734708354534e+170, /* 106! */ 1.146280563734708354534e+170, /* 106! */
1.226520203196137939352e+172, /* 107! */ 1.226520203196137939352e+172, /* 107! */
1.324641819451828974500e+174, /* 108! */ 1.324641819451828974500e+174, /* 108! */
1.443859583202493582205e+176, /* 109! */ 1.443859583202493582205e+176, /* 109! */
1.588245541522742940425e+178, /* 110! */ 1.588245541522742940425e+178, /* 110! */
1.762952551090244663872e+180, /* 111! */ 1.762952551090244663872e+180, /* 111! */
1.974506857221074023537e+182, /* 112! */ 1.974506857221074023537e+182, /* 112! */
2.231192748659813646597e+184, /* 113! */ 2.231192748659813646597e+184, /* 113! */
2.543559733472187557120e+186, /* 114! */ 2.543559733472187557120e+186, /* 114! */
2.925093693493015690688e+188, /* 115! */ 2.925093693493015690688e+188, /* 115! */
3.393108684451898201198e+190, /* 116! */ 3.393108684451898201198e+190, /* 116! */
3.969937160808720895402e+192, /* 117! */ 3.969937160808720895402e+192, /* 117! */
4.684525849754290656574e+194, /* 118! */ 4.684525849754290656574e+194, /* 118! */
5.574585761207605881323e+196, /* 119! */ 5.574585761207605881323e+196, /* 119! */
6.689502913449127057588e+198, /* 120! */ 6.689502913449127057588e+198, /* 120! */
8.094298525273443739682e+200, /* 121! */ 8.094298525273443739682e+200, /* 121! */
9.875044200833601362412e+202, /* 122! */ 9.875044200833601362412e+202, /* 122! */
1.214630436702532967577e+205, /* 123! */ 1.214630436702532967577e+205, /* 123! */
1.506141741511140879795e+207, /* 124! */ 1.506141741511140879795e+207, /* 124! */
1.882677176888926099744e+209, /* 125! */ 1.882677176888926099744e+209, /* 125! */
2.372173242880046885677e+211, /* 126! */ 2.372173242880046885677e+211, /* 126! */
3.012660018457659544810e+213, /* 127! */ 3.012660018457659544810e+213, /* 127! */
3.856204823625804217357e+215, /* 128! */ 3.856204823625804217357e+215, /* 128! */
4.974504222477287440390e+217, /* 129! */ 4.974504222477287440390e+217, /* 129! */
6.466855489220473672507e+219, /* 130! */ 6.466855489220473672507e+219, /* 130! */
8.471580690878820510985e+221, /* 131! */ 8.471580690878820510985e+221, /* 131! */
1.118248651196004307450e+224, /* 132! */ 1.118248651196004307450e+224, /* 132! */
1.487270706090685728908e+226, /* 133! */ 1.487270706090685728908e+226, /* 133! */
1.992942746161518876737e+228, /* 134! */ 1.992942746161518876737e+228, /* 134! */
2.690472707318050483595e+230, /* 135! */ 2.690472707318050483595e+230, /* 135! */
3.659042881952548657690e+232, /* 136! */ 3.659042881952548657690e+232, /* 136! */
5.012888748274991661035e+234, /* 137! */ 5.012888748274991661035e+234, /* 137! */
6.917786472619488492228e+236, /* 138! */ 6.917786472619488492228e+236, /* 138! */
9.615723196941089004197e+238, /* 139! */ 9.615723196941089004197e+238, /* 139! */
1.346201247571752460588e+241, /* 140! */ 1.346201247571752460588e+241, /* 140! */
1.898143759076170969429e+243, /* 141! */ 1.898143759076170969429e+243, /* 141! */
2.695364137888162776589e+245, /* 142! */ 2.695364137888162776589e+245, /* 142! */
3.854370717180072770522e+247, /* 143! */ 3.854370717180072770522e+247, /* 143! */
5.550293832739304789551e+249, /* 144! */ 5.550293832739304789551e+249, /* 144! */
8.047926057471991944849e+251, /* 145! */ 8.047926057471991944849e+251, /* 145! */
1.174997204390910823948e+254, /* 146! */ 1.174997204390910823948e+254, /* 146! */
1.727245890454638911203e+256, /* 147! */ 1.727245890454638911203e+256, /* 147! */
2.556323917872865588581e+258, /* 148! */ 2.556323917872865588581e+258, /* 148! */
3.808922637630569726986e+260, /* 149! */ 3.808922637630569726986e+260, /* 149! */
5.713383956445854590479e+262, /* 150! */ 5.713383956445854590479e+262, /* 150! */
8.627209774233240431623e+264, /* 151! */ 8.627209774233240431623e+264, /* 151! */
1.311335885683452545607e+267, /* 152! */ 1.311335885683452545607e+267, /* 152! */
2.006343905095682394778e+269, /* 153! */ 2.006343905095682394778e+269, /* 153! */
3.089769613847350887959e+271, /* 154! */ 3.089769613847350887959e+271, /* 154! */
4.789142901463393876336e+273, /* 155! */ 4.789142901463393876336e+273, /* 155! */
7.471062926282894447084e+275, /* 156! */ 7.471062926282894447084e+275, /* 156! */
1.172956879426414428192e+278, /* 157! */ 1.172956879426414428192e+278, /* 157! */
1.853271869493734796544e+280, /* 158! */ 1.853271869493734796544e+280, /* 158! */
2.946702272495038326504e+282, /* 159! */ 2.946702272495038326504e+282, /* 159! */
4.714723635992061322407e+284, /* 160! */ 4.714723635992061322407e+284, /* 160! */
7.590705053947218729075e+286, /* 161! */ 7.590705053947218729075e+286, /* 161! */
1.229694218739449434110e+289, /* 162! */ 1.229694218739449434110e+289, /* 162! */
2.004401576545302577600e+291, /* 163! */ 2.004401576545302577600e+291, /* 163! */
3.287218585534296227263e+293, /* 164! */ 3.287218585534296227263e+293, /* 164! */
5.423910666131588774984e+295, /* 165! */ 5.423910666131588774984e+295, /* 165! */
9.003691705778437366474e+297, /* 166! */ 9.003691705778437366474e+297, /* 166! */
1.503616514864999040201e+300, /* 167! */ 1.503616514864999040201e+300, /* 167! */
2.526075744973198387538e+302, /* 168! */ 2.526075744973198387538e+302, /* 168! */
4.269068009004705274939e+304, /* 169! */ 4.269068009004705274939e+304, /* 169! */
7.257415615307998967397e+306 /* 170! */ 7.257415615307998967397e+306, /* 170! */
] ]
log_factorials_table = [ log_factorials_table = [
f64(0.000000000000000000000e+0), /* 0! */ f64(0.000000000000000000000e+0), /* 0! */
0.000000000000000000000e+0, /* 1! */ 0.000000000000000000000e+0, /* 1! */
6.931471805599453094172e-1, /* 2! */ 6.931471805599453094172e-1, /* 2! */
1.791759469228055000812e+0, /* 3! */ 1.791759469228055000812e+0, /* 3! */
3.178053830347945619647e+0, /* 4! */ 3.178053830347945619647e+0, /* 4! */
4.787491742782045994248e+0, /* 5! */ 4.787491742782045994248e+0, /* 5! */
6.579251212010100995060e+0, /* 6! */ 6.579251212010100995060e+0, /* 6! */
8.525161361065414300166e+0, /* 7! */ 8.525161361065414300166e+0, /* 7! */
1.060460290274525022842e+1, /* 8! */ 1.060460290274525022842e+1, /* 8! */
1.280182748008146961121e+1, /* 9! */ 1.280182748008146961121e+1, /* 9! */
1.510441257307551529523e+1, /* 10! */ 1.510441257307551529523e+1, /* 10! */
1.750230784587388583929e+1, /* 11! */ 1.750230784587388583929e+1, /* 11! */
1.998721449566188614952e+1, /* 12! */ 1.998721449566188614952e+1, /* 12! */
2.255216385312342288557e+1, /* 13! */ 2.255216385312342288557e+1, /* 13! */
2.519122118273868150009e+1, /* 14! */ 2.519122118273868150009e+1, /* 14! */
2.789927138384089156609e+1, /* 15! */ 2.789927138384089156609e+1, /* 15! */
3.067186010608067280376e+1, /* 16! */ 3.067186010608067280376e+1, /* 16! */
3.350507345013688888401e+1, /* 17! */ 3.350507345013688888401e+1, /* 17! */
3.639544520803305357622e+1, /* 18! */ 3.639544520803305357622e+1, /* 18! */
3.933988418719949403622e+1, /* 19! */ 3.933988418719949403622e+1, /* 19! */
4.233561646075348502966e+1, /* 20! */ 4.233561646075348502966e+1, /* 20! */
4.538013889847690802616e+1, /* 21! */ 4.538013889847690802616e+1, /* 21! */
4.847118135183522387964e+1, /* 22! */ 4.847118135183522387964e+1, /* 22! */
5.160667556776437357045e+1, /* 23! */ 5.160667556776437357045e+1, /* 23! */
5.478472939811231919009e+1, /* 24! */ 5.478472939811231919009e+1, /* 24! */
5.800360522298051993929e+1, /* 25! */ 5.800360522298051993929e+1, /* 25! */
6.126170176100200198477e+1, /* 26! */ 6.126170176100200198477e+1, /* 26! */
6.455753862700633105895e+1, /* 27! */ 6.455753862700633105895e+1, /* 27! */
6.788974313718153498289e+1, /* 28! */ 6.788974313718153498289e+1, /* 28! */
7.125703896716800901007e+1, /* 29! */ 7.125703896716800901007e+1, /* 29! */
7.465823634883016438549e+1, /* 30! */ 7.465823634883016438549e+1, /* 30! */
7.809222355331531063142e+1, /* 31! */ 7.809222355331531063142e+1, /* 31! */
8.155795945611503717850e+1, /* 32! */ 8.155795945611503717850e+1, /* 32! */
8.505446701758151741396e+1, /* 33! */ 8.505446701758151741396e+1, /* 33! */
8.858082754219767880363e+1, /* 34! */ 8.858082754219767880363e+1, /* 34! */
9.213617560368709248333e+1, /* 35! */ 9.213617560368709248333e+1, /* 35! */
9.571969454214320248496e+1, /* 36! */ 9.571969454214320248496e+1, /* 36! */
9.933061245478742692933e+1, /* 37! */ 9.933061245478742692933e+1, /* 37! */
1.029681986145138126988e+2, /* 38! */ 1.029681986145138126988e+2, /* 38! */
1.066317602606434591262e+2, /* 39! */ 1.066317602606434591262e+2, /* 39! */
1.103206397147573954291e+2, /* 40! */ 1.103206397147573954291e+2, /* 40! */
1.140342117814617032329e+2, /* 41! */ 1.140342117814617032329e+2, /* 41! */
1.177718813997450715388e+2, /* 42! */ 1.177718813997450715388e+2, /* 42! */
1.215330815154386339623e+2, /* 43! */ 1.215330815154386339623e+2, /* 43! */
1.253172711493568951252e+2, /* 44! */ 1.253172711493568951252e+2, /* 44! */
1.291239336391272148826e+2, /* 45! */ 1.291239336391272148826e+2, /* 45! */
1.329525750356163098828e+2, /* 46! */ 1.329525750356163098828e+2, /* 46! */
1.368027226373263684696e+2, /* 47! */ 1.368027226373263684696e+2, /* 47! */
1.406739236482342593987e+2, /* 48! */ 1.406739236482342593987e+2, /* 48! */
1.445657439463448860089e+2, /* 49! */ 1.445657439463448860089e+2, /* 49! */
1.484777669517730320675e+2, /* 50! */ 1.484777669517730320675e+2, /* 50! */
1.524095925844973578392e+2, /* 51! */ 1.524095925844973578392e+2, /* 51! */
1.563608363030787851941e+2, /* 52! */ 1.563608363030787851941e+2, /* 52! */
1.603311282166309070282e+2, /* 53! */ 1.603311282166309070282e+2, /* 53! */
1.643201122631951814118e+2, /* 54! */ 1.643201122631951814118e+2, /* 54! */
1.683274454484276523305e+2, /* 55! */ 1.683274454484276523305e+2, /* 55! */
1.723527971391628015638e+2, /* 56! */ 1.723527971391628015638e+2, /* 56! */
1.763958484069973517152e+2, /* 57! */ 1.763958484069973517152e+2, /* 57! */
1.804562914175437710518e+2, /* 58! */ 1.804562914175437710518e+2, /* 58! */
1.845338288614494905025e+2, /* 59! */ 1.845338288614494905025e+2, /* 59! */
1.886281734236715911873e+2, /* 60! */ 1.886281734236715911873e+2, /* 60! */
1.927390472878449024360e+2, /* 61! */ 1.927390472878449024360e+2, /* 61! */
1.968661816728899939914e+2, /* 62! */ 1.968661816728899939914e+2, /* 62! */
2.010093163992815266793e+2, /* 63! */ 2.010093163992815266793e+2, /* 63! */
2.051681994826411985358e+2, /* 64! */ 2.051681994826411985358e+2, /* 64! */
2.093425867525368356464e+2, /* 65! */ 2.093425867525368356464e+2, /* 65! */
2.135322414945632611913e+2, /* 66! */ 2.135322414945632611913e+2, /* 66! */
2.177369341139542272510e+2, /* 67! */ 2.177369341139542272510e+2, /* 67! */
2.219564418191303339501e+2, /* 68! */ 2.219564418191303339501e+2, /* 68! */
2.261905483237275933323e+2, /* 69! */ 2.261905483237275933323e+2, /* 69! */
2.304390435657769523214e+2, /* 70! */ 2.304390435657769523214e+2, /* 70! */
2.347017234428182677427e+2, /* 71! */ 2.347017234428182677427e+2, /* 71! */
2.389783895618343230538e+2, /* 72! */ 2.389783895618343230538e+2, /* 72! */
2.432688490029827141829e+2, /* 73! */ 2.432688490029827141829e+2, /* 73! */
2.475729140961868839366e+2, /* 74! */ 2.475729140961868839366e+2, /* 74! */
2.518904022097231943772e+2, /* 75! */ 2.518904022097231943772e+2, /* 75! */
2.562211355500095254561e+2, /* 76! */ 2.562211355500095254561e+2, /* 76! */
2.605649409718632093053e+2, /* 77! */ 2.605649409718632093053e+2, /* 77! */
2.649216497985528010421e+2, /* 78! */ 2.649216497985528010421e+2, /* 78! */
2.692910976510198225363e+2, /* 79! */ 2.692910976510198225363e+2, /* 79! */
2.736731242856937041486e+2, /* 80! */ 2.736731242856937041486e+2, /* 80! */
2.780675734403661429141e+2, /* 81! */ 2.780675734403661429141e+2, /* 81! */
2.824742926876303960274e+2, /* 82! */ 2.824742926876303960274e+2, /* 82! */
2.868931332954269939509e+2, /* 83! */ 2.868931332954269939509e+2, /* 83! */
2.913239500942703075662e+2, /* 84! */ 2.913239500942703075662e+2, /* 84! */
2.957666013507606240211e+2, /* 85! */ 2.957666013507606240211e+2, /* 85! */
3.002209486470141317540e+2, /* 86! */ 3.002209486470141317540e+2, /* 86! */
3.046868567656687154726e+2, /* 87! */ 3.046868567656687154726e+2, /* 87! */
3.091641935801469219449e+2, /* 88! */ 3.091641935801469219449e+2, /* 88! */
3.136528299498790617832e+2, /* 89! */ 3.136528299498790617832e+2, /* 89! */
3.181526396202093268500e+2, /* 90! */ 3.181526396202093268500e+2, /* 90! */
3.226634991267261768912e+2, /* 91! */ 3.226634991267261768912e+2, /* 91! */
3.271852877037752172008e+2, /* 92! */ 3.271852877037752172008e+2, /* 92! */
3.317178871969284731381e+2, /* 93! */ 3.317178871969284731381e+2, /* 93! */
3.362611819791984770344e+2, /* 94! */ 3.362611819791984770344e+2, /* 94! */
3.408150588707990178690e+2, /* 95! */ 3.408150588707990178690e+2, /* 95! */
3.453794070622668541074e+2, /* 96! */ 3.453794070622668541074e+2, /* 96! */
3.499541180407702369296e+2, /* 97! */ 3.499541180407702369296e+2, /* 97! */
3.545390855194408088492e+2, /* 98! */ 3.545390855194408088492e+2, /* 98! */
3.591342053695753987760e+2, /* 99! */ 3.591342053695753987760e+2, /* 99! */
3.637393755555634901441e+2, /* 100! */ 3.637393755555634901441e+2, /* 100! */
3.683544960724047495950e+2, /* 101! */ 3.683544960724047495950e+2, /* 101! */
3.729794688856890206760e+2, /* 102! */ 3.729794688856890206760e+2, /* 102! */
3.776141978739186564468e+2, /* 103! */ 3.776141978739186564468e+2, /* 103! */
3.822585887730600291111e+2, /* 104! */ 3.822585887730600291111e+2, /* 104! */
3.869125491232175524822e+2, /* 105! */ 3.869125491232175524822e+2, /* 105! */
3.915759882173296196258e+2, /* 106! */ 3.915759882173296196258e+2, /* 106! */
3.962488170517915257991e+2, /* 107! */ 3.962488170517915257991e+2, /* 107! */
4.009309482789157454921e+2, /* 108! */ 4.009309482789157454921e+2, /* 108! */
4.056222961611448891925e+2, /* 109! */ 4.056222961611448891925e+2, /* 109! */
4.103227765269373054205e+2, /* 110! */ 4.103227765269373054205e+2, /* 110! */
4.150323067282496395563e+2, /* 111! */ 4.150323067282496395563e+2, /* 111! */
4.197508055995447340991e+2, /* 112! */ 4.197508055995447340991e+2, /* 112! */
4.244781934182570746677e+2, /* 113! */ 4.244781934182570746677e+2, /* 113! */
4.292143918666515701285e+2, /* 114! */ 4.292143918666515701285e+2, /* 114! */
4.339593239950148201939e+2, /* 115! */ 4.339593239950148201939e+2, /* 115! */
4.387129141861211848399e+2, /* 116! */ 4.387129141861211848399e+2, /* 116! */
4.434750881209189409588e+2, /* 117! */ 4.434750881209189409588e+2, /* 117! */
4.482457727453846057188e+2, /* 118! */ 4.482457727453846057188e+2, /* 118! */
4.530248962384961351041e+2, /* 119! */ 4.530248962384961351041e+2, /* 119! */
4.578123879812781810984e+2, /* 120! */ 4.578123879812781810984e+2, /* 120! */
4.626081785268749221865e+2, /* 121! */ 4.626081785268749221865e+2, /* 121! */
4.674121995716081787447e+2, /* 122! */ 4.674121995716081787447e+2, /* 122! */
4.722243839269805962399e+2, /* 123! */ 4.722243839269805962399e+2, /* 123! */
4.770446654925856331047e+2, /* 124! */ 4.770446654925856331047e+2, /* 124! */
4.818729792298879342285e+2, /* 125! */ 4.818729792298879342285e+2, /* 125! */
4.867092611368394122258e+2, /* 126! */ 4.867092611368394122258e+2, /* 126! */
4.915534482232980034989e+2, /* 127! */ 4.915534482232980034989e+2, /* 127! */
4.964054784872176206648e+2, /* 128! */ 4.964054784872176206648e+2, /* 128! */
5.012652908915792927797e+2, /* 129! */ 5.012652908915792927797e+2, /* 129! */
5.061328253420348751997e+2, /* 130! */ 5.061328253420348751997e+2, /* 130! */
5.110080226652360267439e+2, /* 131! */ 5.110080226652360267439e+2, /* 131! */
5.158908245878223975982e+2, /* 132! */ 5.158908245878223975982e+2, /* 132! */
5.207811737160441513633e+2, /* 133! */ 5.207811737160441513633e+2, /* 133! */
5.256790135159950627324e+2, /* 134! */ 5.256790135159950627324e+2, /* 134! */
5.305842882944334921812e+2, /* 135! */ 5.305842882944334921812e+2, /* 135! */
5.354969431801695441897e+2, /* 136! */ 5.354969431801695441897e+2, /* 136! */
5.404169241059976691050e+2, /* 137! */ 5.404169241059976691050e+2, /* 137! */
5.453441777911548737966e+2, /* 138! */ 5.453441777911548737966e+2, /* 138! */
5.502786517242855655538e+2, /* 139! */ 5.502786517242855655538e+2, /* 139! */
5.552202941468948698523e+2, /* 140! */ 5.552202941468948698523e+2, /* 140! */
5.601690540372730381305e+2, /* 141! */ 5.601690540372730381305e+2, /* 141! */
5.651248810948742988613e+2, /* 142! */ 5.651248810948742988613e+2, /* 142! */
5.700877257251342061414e+2, /* 143! */ 5.700877257251342061414e+2, /* 143! */
5.750575390247102067619e+2, /* 144! */ 5.750575390247102067619e+2, /* 144! */
5.800342727671307811636e+2, /* 145! */ 5.800342727671307811636e+2, /* 145! */
5.850178793888391176022e+2, /* 146! */ 5.850178793888391176022e+2, /* 146! */
5.900083119756178539038e+2, /* 147! */ 5.900083119756178539038e+2, /* 147! */
5.950055242493819689670e+2, /* 148! */ 5.950055242493819689670e+2, /* 148! */
6.000094705553274281080e+2, /* 149! */ 6.000094705553274281080e+2, /* 149! */
6.050201058494236838580e+2, /* 150! */ 6.050201058494236838580e+2, /* 150! */
6.100373856862386081868e+2, /* 151! */ 6.100373856862386081868e+2, /* 151! */
6.150612662070848845750e+2, /* 152! */ 6.150612662070848845750e+2, /* 152! */
6.200917041284773200381e+2, /* 153! */ 6.200917041284773200381e+2, /* 153! */
6.251286567308909491967e+2, /* 154! */ 6.251286567308909491967e+2, /* 154! */
6.301720818478101958172e+2, /* 155! */ 6.301720818478101958172e+2, /* 155! */
6.352219378550597328635e+2, /* 156! */ 6.352219378550597328635e+2, /* 156! */
6.402781836604080409209e+2, /* 157! */ 6.402781836604080409209e+2, /* 157! */
6.453407786934350077245e+2, /* 158! */ 6.453407786934350077245e+2, /* 158! */
6.504096828956552392500e+2, /* 159! */ 6.504096828956552392500e+2, /* 159! */
6.554848567108890661717e+2, /* 160! */ 6.554848567108890661717e+2, /* 160! */
6.605662610758735291676e+2, /* 161! */ 6.605662610758735291676e+2, /* 161! */
6.656538574111059132426e+2, /* 162! */ 6.656538574111059132426e+2, /* 162! */
6.707476076119126755767e+2, /* 163! */ 6.707476076119126755767e+2, /* 163! */
6.758474740397368739994e+2, /* 164! */ 6.758474740397368739994e+2, /* 164! */
6.809534195136374546094e+2, /* 165! */ 6.809534195136374546094e+2, /* 165! */
6.860654073019939978423e+2, /* 166! */ 6.860654073019939978423e+2, /* 166! */
6.911834011144107529496e+2, /* 167! */ 6.911834011144107529496e+2, /* 167! */
6.963073650938140118743e+2, /* 168! */ 6.963073650938140118743e+2, /* 168! */
7.014372638087370853465e+2, /* 169! */ 7.014372638087370853465e+2, /* 169! */
7.065730622457873471107e+2, /* 170! */ 7.065730622457873471107e+2, /* 170! */
7.117147258022900069535e+2, /* 171! */ 7.117147258022900069535e+2, /* 171! */
] ]
) )

View File

@ -73,13 +73,13 @@ fn eval_cf(whole i64, den []i64) Fraction {
// within the default epsilon value (1.0e-4). This means the result will // within the default epsilon value (1.0e-4). This means the result will
// be accurate to 3 places after the decimal. // be accurate to 3 places after the decimal.
pub fn approximate(val f64) Fraction { pub fn approximate(val f64) Fraction {
return approximate_with_eps(val, default_eps) return approximate_with_eps(val, fractions.default_eps)
} }
// approximate_with_eps returns a Fraction // approximate_with_eps returns a Fraction
pub fn approximate_with_eps(val f64, eps f64) Fraction { pub fn approximate_with_eps(val f64, eps f64) Fraction {
if val == 0.0 { if val == 0.0 {
return zero return fractions.zero
} }
if eps < 0.0 { if eps < 0.0 {
panic('Epsilon value cannot be negative.') panic('Epsilon value cannot be negative.')
@ -96,12 +96,12 @@ pub fn approximate_with_eps(val f64, eps f64) Fraction {
return fraction(whole, 1) return fraction(whole, 1)
} }
mut d := []i64{} mut d := []i64{}
mut partial := zero mut partial := fractions.zero
// We must complete the approximation within the maximum number of // We must complete the approximation within the maximum number of
// itertations allowed. If we can't panic. // itertations allowed. If we can't panic.
// Empirically tested: the hardest constant to approximate is the // Empirically tested: the hardest constant to approximate is the
// golden ratio (math.phi) and for f64s, it only needs 38 iterations. // golden ratio (math.phi) and for f64s, it only needs 38 iterations.
for _ in 0 .. max_iterations { for _ in 0 .. fractions.max_iterations {
// We calculate the reciprocal. That's why the numerator is // We calculate the reciprocal. That's why the numerator is
// always 1. // always 1.
frac = 1.0 / frac frac = 1.0 / frac
@ -115,5 +115,5 @@ pub fn approximate_with_eps(val f64, eps f64) Fraction {
} }
frac -= f64(den) frac -= f64(den)
} }
panic("Couldn\'t converge. Please create an issue on https://github.com/vlang/v") panic("Couldn't converge. Please create an issue on https://github.com/vlang/v")
} }

View File

@ -69,27 +69,33 @@ fn test_140710_232() {
} }
fn test_pi_1_digit() { fn test_pi_1_digit() {
assert fractions.approximate_with_eps(math.pi, 5.0e-2).equals(fractions.fraction(22, 7)) assert fractions.approximate_with_eps(math.pi, 5.0e-2).equals(fractions.fraction(22,
7))
} }
fn test_pi_2_digits() { fn test_pi_2_digits() {
assert fractions.approximate_with_eps(math.pi, 5.0e-3).equals(fractions.fraction(22, 7)) assert fractions.approximate_with_eps(math.pi, 5.0e-3).equals(fractions.fraction(22,
7))
} }
fn test_pi_3_digits() { fn test_pi_3_digits() {
assert fractions.approximate_with_eps(math.pi, 5.0e-4).equals(fractions.fraction(333, 106)) assert fractions.approximate_with_eps(math.pi, 5.0e-4).equals(fractions.fraction(333,
106))
} }
fn test_pi_4_digits() { fn test_pi_4_digits() {
assert fractions.approximate_with_eps(math.pi, 5.0e-5).equals(fractions.fraction(355, 113)) assert fractions.approximate_with_eps(math.pi, 5.0e-5).equals(fractions.fraction(355,
113))
} }
fn test_pi_5_digits() { fn test_pi_5_digits() {
assert fractions.approximate_with_eps(math.pi, 5.0e-6).equals(fractions.fraction(355, 113)) assert fractions.approximate_with_eps(math.pi, 5.0e-6).equals(fractions.fraction(355,
113))
} }
fn test_pi_6_digits() { fn test_pi_6_digits() {
assert fractions.approximate_with_eps(math.pi, 5.0e-7).equals(fractions.fraction(355, 113)) assert fractions.approximate_with_eps(math.pi, 5.0e-7).equals(fractions.fraction(355,
113))
} }
fn test_pi_7_digits() { fn test_pi_7_digits() {
@ -123,15 +129,18 @@ fn test_pi_12_digits() {
} }
fn test_phi_1_digit() { fn test_phi_1_digit() {
assert fractions.approximate_with_eps(math.phi, 5.0e-2).equals(fractions.fraction(5, 3)) assert fractions.approximate_with_eps(math.phi, 5.0e-2).equals(fractions.fraction(5,
3))
} }
fn test_phi_2_digits() { fn test_phi_2_digits() {
assert fractions.approximate_with_eps(math.phi, 5.0e-3).equals(fractions.fraction(21, 13)) assert fractions.approximate_with_eps(math.phi, 5.0e-3).equals(fractions.fraction(21,
13))
} }
fn test_phi_3_digits() { fn test_phi_3_digits() {
assert fractions.approximate_with_eps(math.phi, 5.0e-4).equals(fractions.fraction(55, 34)) assert fractions.approximate_with_eps(math.phi, 5.0e-4).equals(fractions.fraction(55,
34))
} }
fn test_phi_4_digits() { fn test_phi_4_digits() {

View File

@ -6,7 +6,10 @@ module math
// TODO : The commented out functions need either a native V implementation, a // TODO : The commented out functions need either a native V implementation, a
// JS specific implementation, or use some other JS math library, such as // JS specific implementation, or use some other JS math library, such as
// https://github.com/josdejong/mathjs // https://github.com/josdejong/mathjs
fn JS.Math.abs(x f64) f64 // Replaces C.fabs
// Replaces C.fabs
fn JS.Math.abs(x f64) f64
fn JS.Math.acos(x f64) f64 fn JS.Math.acos(x f64) f64
fn JS.Math.asin(x f64) f64 fn JS.Math.asin(x f64) f64
fn JS.Math.atan(x f64) f64 fn JS.Math.atan(x f64) f64
@ -15,23 +18,28 @@ fn JS.Math.cbrt(x f64) f64
fn JS.Math.ceil(x f64) f64 fn JS.Math.ceil(x f64) f64
fn JS.Math.cos(x f64) f64 fn JS.Math.cos(x f64) f64
fn JS.Math.cosh(x f64) f64 fn JS.Math.cosh(x f64) f64
//fn JS.Math.erf(x f64) f64 // Not in standard JS Math object
//fn JS.Math.erfc(x f64) f64 // Not in standard JS Math object // fn JS.Math.erf(x f64) f64 // Not in standard JS Math object
// fn JS.Math.erfc(x f64) f64 // Not in standard JS Math object
fn JS.Math.exp(x f64) f64 fn JS.Math.exp(x f64) f64
//fn JS.Math.exp2(x f64) f64 // Not in standard JS Math object
// fn JS.Math.exp2(x f64) f64 // Not in standard JS Math object
fn JS.Math.floor(x f64) f64 fn JS.Math.floor(x f64) f64
//fn JS.Math.fmod(x f64, y f64) f64 // Not in standard JS Math object
//fn JS.Math.hypot(x f64, y f64) f64 // Not in standard JS Math object // fn JS.Math.fmod(x f64, y f64) f64 // Not in standard JS Math object
// fn JS.Math.hypot(x f64, y f64) f64 // Not in standard JS Math object
fn JS.Math.log(x f64) f64 fn JS.Math.log(x f64) f64
//fn JS.Math.log2(x f64) f64 // Not in standard JS Math object
//fn JS.Math.log10(x f64) f64 // Not in standard JS Math object // fn JS.Math.log2(x f64) f64 // Not in standard JS Math object
//fn JS.Math.lgamma(x f64) f64 // Not in standard JS Math object // fn JS.Math.log10(x f64) f64 // Not in standard JS Math object
// fn JS.Math.lgamma(x f64) f64 // Not in standard JS Math object
fn JS.Math.pow(x f64, y f64) f64 fn JS.Math.pow(x f64, y f64) f64
fn JS.Math.round(x f64) f64 fn JS.Math.round(x f64) f64
fn JS.Math.sin(x f64) f64 fn JS.Math.sin(x f64) f64
fn JS.Math.sinh(x f64) f64 fn JS.Math.sinh(x f64) f64
fn JS.Math.sqrt(x f64) f64 fn JS.Math.sqrt(x f64) f64
//fn JS.Math.tgamma(x f64) f64 // Not in standard JS Math object
// fn JS.Math.tgamma(x f64) f64 // Not in standard JS Math object
fn JS.Math.tan(x f64) f64 fn JS.Math.tan(x f64) f64
fn JS.Math.tanh(x f64) f64 fn JS.Math.tanh(x f64) f64
fn JS.Math.trunc(x f64) f64 fn JS.Math.trunc(x f64) f64
@ -66,7 +74,7 @@ pub fn atan(a f64) f64 {
// atan2 calculates inverse tangent with two arguments, returns the angle between the X axis and the point. // atan2 calculates inverse tangent with two arguments, returns the angle between the X axis and the point.
[inline] [inline]
pub fn atan2(a, b f64) f64 { pub fn atan2(a f64, b f64) f64 {
return JS.Math.atan2(a, b) return JS.Math.atan2(a, b)
} }
@ -132,7 +140,7 @@ pub fn floor(a f64) f64 {
// fmod returns the floating-point remainder of number / denom (rounded towards zero): // fmod returns the floating-point remainder of number / denom (rounded towards zero):
[inline] [inline]
pub fn fmod(a, b f64) f64 { pub fn fmod(a f64, b f64) f64 {
return JS.Math.fmod(a, b) return JS.Math.fmod(a, b)
} }
@ -144,7 +152,7 @@ pub fn gamma(a f64) f64 {
// Returns hypotenuse of a right triangle. // Returns hypotenuse of a right triangle.
[inline] [inline]
pub fn hypot(a, b f64) f64 { pub fn hypot(a f64, b f64) f64 {
return JS.Math.hypot(a, b) return JS.Math.hypot(a, b)
} }
@ -174,19 +182,19 @@ pub fn log_gamma(a f64) f64 {
// log_n calculates base-N logarithm of the provided value. // log_n calculates base-N logarithm of the provided value.
[inline] [inline]
pub fn log_n(a, b f64) f64 { pub fn log_n(a f64, b f64) f64 {
return JS.Math.log(a) / JS.Math.log(b) return JS.Math.log(a) / JS.Math.log(b)
} }
// pow returns base raised to the provided power. // pow returns base raised to the provided power.
[inline] [inline]
pub fn pow(a, b f64) f64 { pub fn pow(a f64, b f64) f64 {
return JS.Math.pow(a, b) return JS.Math.pow(a, b)
} }
// powf returns base raised to the provided power. (float32) // powf returns base raised to the provided power. (float32)
[inline] [inline]
pub fn powf(a, b f32) f32 { pub fn powf(a f32, b f32) f32 {
return f32(JS.Math.pow(a, b)) return f32(JS.Math.pow(a, b))
} }

View File

@ -26,7 +26,6 @@ import math
// range - Range of the Array ( max - min ) // range - Range of the Array ( max - min )
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
// Measure of Occurance // Measure of Occurance
// Frequency of a given number // Frequency of a given number
// Based on // Based on
@ -56,7 +55,7 @@ pub fn mean(arr []f64) f64 {
for v in arr { for v in arr {
sum += v sum += v
} }
return sum/f64(arr.len) return sum / f64(arr.len)
} }
// Measure of Central Tendancy // Measure of Central Tendancy
@ -71,7 +70,7 @@ pub fn geometric_mean(arr []f64) f64 {
for v in arr { for v in arr {
sum *= v sum *= v
} }
return math.pow(sum,f64(1)/arr.len) return math.pow(sum, f64(1) / arr.len)
} }
// Measure of Central Tendancy // Measure of Central Tendancy
@ -84,9 +83,9 @@ pub fn harmonic_mean(arr []f64) f64 {
} }
mut sum := f64(0) mut sum := f64(0)
for v in arr { for v in arr {
sum += f64(1)/v sum += f64(1) / v
} }
return f64(arr.len)/sum return f64(arr.len) / sum
} }
// Measure of Central Tendancy // Measure of Central Tendancy
@ -98,11 +97,10 @@ pub fn median(arr []f64) f64 {
return f64(0) return f64(0)
} }
if arr.len % 2 == 0 { if arr.len % 2 == 0 {
mid := (arr.len/2)-1 mid := (arr.len / 2) - 1
return (arr[mid] + arr[mid+1])/f64(2) return (arr[mid] + arr[mid + 1]) / f64(2)
} } else {
else { return arr[((arr.len - 1) / 2)]
return arr[((arr.len-1)/2)]
} }
} }
@ -116,10 +114,10 @@ pub fn mode(arr []f64) f64 {
} }
mut freqs := []int{} mut freqs := []int{}
for v in arr { for v in arr {
freqs<<freq(arr,v) freqs << freq(arr, v)
} }
mut max := 0 mut max := 0
for i in 0..freqs.len { for i in 0 .. freqs.len {
if freqs[i] > freqs[max] { if freqs[i] > freqs[max] {
max = i max = i
} }
@ -136,9 +134,9 @@ pub fn rms(arr []f64) f64 {
} }
mut sum := f64(0) mut sum := f64(0)
for v in arr { for v in arr {
sum += math.pow(v,2) sum += math.pow(v, 2)
} }
return math.sqrt(sum/f64(arr.len)) return math.sqrt(sum / f64(arr.len))
} }
// Measure of Dispersion / Spread // Measure of Dispersion / Spread
@ -152,9 +150,9 @@ pub fn population_variance(arr []f64) f64 {
m := mean(arr) m := mean(arr)
mut sum := f64(0) mut sum := f64(0)
for v in arr { for v in arr {
sum += math.pow(v-m,2) sum += math.pow(v - m, 2)
} }
return sum/f64(arr.len) return sum / f64(arr.len)
} }
// Measure of Dispersion / Spread // Measure of Dispersion / Spread
@ -168,9 +166,9 @@ pub fn sample_variance(arr []f64) f64 {
m := mean(arr) m := mean(arr)
mut sum := f64(0) mut sum := f64(0)
for v in arr { for v in arr {
sum += math.pow(v-m,2) sum += math.pow(v - m, 2)
} }
return sum/f64(arr.len-1) return sum / f64(arr.len - 1)
} }
// Measure of Dispersion / Spread // Measure of Dispersion / Spread
@ -206,9 +204,9 @@ pub fn mean_absdev(arr []f64) f64 {
amean := mean(arr) amean := mean(arr)
mut sum := f64(0) mut sum := f64(0)
for v in arr { for v in arr {
sum += math.abs(v-amean) sum += math.abs(v - amean)
} }
return sum/f64(arr.len) return sum / f64(arr.len)
} }
// Minimum of the given input array // Minimum of the given input array

View File

@ -3,12 +3,12 @@ import math
fn test_freq() { fn test_freq() {
// Tests were also verified on Wolfram Alpha // Tests were also verified on Wolfram Alpha
data := [f64(10.0),f64(10.0),f64(5.9),f64(2.7)] data := [f64(10.0), f64(10.0), f64(5.9), f64(2.7)]
mut o := stats.freq(data,10.0) mut o := stats.freq(data, 10.0)
assert o == 2 assert o == 2
o = stats.freq(data,2.7) o = stats.freq(data, 2.7)
assert o == 1 assert o == 1
o = stats.freq(data,15) o = stats.freq(data, 15)
assert o == 0 assert o == 0
} }
@ -21,15 +21,15 @@ fn tst_res(str1 string, str2 string) bool {
fn test_mean() { fn test_mean() {
// Tests were also verified on Wolfram Alpha // Tests were also verified on Wolfram Alpha
mut data := [f64(10.0),f64(4.45),f64(5.9),f64(2.7)] mut data := [f64(10.0), f64(4.45), f64(5.9), f64(2.7)]
mut o := stats.mean(data) mut o := stats.mean(data)
// Some issue with precision comparison in f64 using == operator hence serializing to string // Some issue with precision comparison in f64 using == operator hence serializing to string
assert tst_res(o.str(), '5.762500') assert tst_res(o.str(), '5.762500')
data = [f64(-3.0),f64(67.31),f64(4.4),f64(1.89)] data = [f64(-3.0), f64(67.31), f64(4.4), f64(1.89)]
o = stats.mean(data) o = stats.mean(data)
// Some issue with precision comparison in f64 using == operator hence serializing to string // Some issue with precision comparison in f64 using == operator hence serializing to string
assert tst_res(o.str(), '17.650000') assert tst_res(o.str(), '17.650000')
data = [f64(12.0),f64(7.88),f64(76.122),f64(54.83)] data = [f64(12.0), f64(7.88), f64(76.122), f64(54.83)]
o = stats.mean(data) o = stats.mean(data)
// Some issue with precision comparison in f64 using == operator hence serializing to string // Some issue with precision comparison in f64 using == operator hence serializing to string
assert tst_res(o.str(), '37.708000') assert tst_res(o.str(), '37.708000')
@ -37,31 +37,32 @@ fn test_mean() {
fn test_geometric_mean() { fn test_geometric_mean() {
// Tests were also verified on Wolfram Alpha // Tests were also verified on Wolfram Alpha
mut data := [f64(10.0),f64(4.45),f64(5.9),f64(2.7)] mut data := [f64(10.0), f64(4.45), f64(5.9), f64(2.7)]
mut o := stats.geometric_mean(data) mut o := stats.geometric_mean(data)
// Some issue with precision comparison in f64 using == operator hence serializing to string // Some issue with precision comparison in f64 using == operator hence serializing to string
assert tst_res(o.str(),'5.15993') assert tst_res(o.str(), '5.15993')
data = [f64(-3.0),f64(67.31),f64(4.4),f64(1.89)] data = [f64(-3.0), f64(67.31), f64(4.4), f64(1.89)]
o = stats.geometric_mean(data) o = stats.geometric_mean(data)
// Some issue with precision comparison in f64 using == operator hence serializing to string // Some issue with precision comparison in f64 using == operator hence serializing to string
assert o.str().eq('nan') || o.str().eq('-nan') || o.str().eq('-1.#IND00') || o == f64(0) || o.str().eq('-nan(ind)') // Because in math it yields a complex number assert o.str().eq('nan') || o.str().eq('-nan') || o.str().eq('-1.#IND00') || o == f64(0)
data = [f64(12.0),f64(7.88),f64(76.122),f64(54.83)] || o.str().eq('-nan(ind)') // Because in math it yields a complex number
data = [f64(12.0), f64(7.88), f64(76.122), f64(54.83)]
o = stats.geometric_mean(data) o = stats.geometric_mean(data)
// Some issue with precision comparison in f64 using == operator hence serializing to string // Some issue with precision comparison in f64 using == operator hence serializing to string
assert tst_res(o.str(),'25.064496') assert tst_res(o.str(), '25.064496')
} }
fn test_harmonic_mean() { fn test_harmonic_mean() {
// Tests were also verified on Wolfram Alpha // Tests were also verified on Wolfram Alpha
mut data := [f64(10.0),f64(4.45),f64(5.9),f64(2.7)] mut data := [f64(10.0), f64(4.45), f64(5.9), f64(2.7)]
mut o := stats.harmonic_mean(data) mut o := stats.harmonic_mean(data)
// Some issue with precision comparison in f64 using == operator hence serializing to string // Some issue with precision comparison in f64 using == operator hence serializing to string
assert tst_res(o.str(), '4.626519') assert tst_res(o.str(), '4.626519')
data = [f64(-3.0),f64(67.31),f64(4.4),f64(1.89)] data = [f64(-3.0), f64(67.31), f64(4.4), f64(1.89)]
o = stats.harmonic_mean(data) o = stats.harmonic_mean(data)
// Some issue with precision comparison in f64 using == operator hence serializing to string // Some issue with precision comparison in f64 using == operator hence serializing to string
assert tst_res(o.str(), '9.134577') assert tst_res(o.str(), '9.134577')
data = [f64(12.0),f64(7.88),f64(76.122),f64(54.83)] data = [f64(12.0), f64(7.88), f64(76.122), f64(54.83)]
o = stats.harmonic_mean(data) o = stats.harmonic_mean(data)
// Some issue with precision comparison in f64 using == operator hence serializing to string // Some issue with precision comparison in f64 using == operator hence serializing to string
assert tst_res(o.str(), '16.555477') assert tst_res(o.str(), '16.555477')
@ -72,56 +73,58 @@ fn test_median() {
// Assumes sorted array // Assumes sorted array
// Even // Even
mut data := [f64(2.7),f64(4.45),f64(5.9),f64(10.0)] mut data := [f64(2.7), f64(4.45), f64(5.9), f64(10.0)]
mut o := stats.median(data) mut o := stats.median(data)
// Some issue with precision comparison in f64 using == operator hence serializing to string // Some issue with precision comparison in f64 using == operator hence serializing to string
assert tst_res(o.str(), '5.175000') assert tst_res(o.str(), '5.175000')
data = [f64(-3.0),f64(1.89),f64(4.4),f64(67.31)] data = [f64(-3.0), f64(1.89), f64(4.4), f64(67.31)]
o = stats.median(data) o = stats.median(data)
// Some issue with precision comparison in f64 using == operator hence serializing to string // Some issue with precision comparison in f64 using == operator hence serializing to string
assert tst_res(o.str(), '3.145000') assert tst_res(o.str(), '3.145000')
data = [f64(7.88),f64(12.0),f64(54.83),f64(76.122)] data = [f64(7.88), f64(12.0), f64(54.83), f64(76.122)]
o = stats.median(data) o = stats.median(data)
// Some issue with precision comparison in f64 using == operator hence serializing to string // Some issue with precision comparison in f64 using == operator hence serializing to string
assert tst_res(o.str(), '33.415000') assert tst_res(o.str(), '33.415000')
// Odd // Odd
data = [f64(2.7),f64(4.45),f64(5.9),f64(10.0),f64(22)] data = [f64(2.7), f64(4.45), f64(5.9), f64(10.0), f64(22)]
o = stats.median(data) o = stats.median(data)
assert o == f64(5.9) assert o == f64(5.9)
data = [f64(-3.0),f64(1.89),f64(4.4),f64(9),f64(67.31)] data = [f64(-3.0), f64(1.89), f64(4.4), f64(9), f64(67.31)]
o = stats.median(data) o = stats.median(data)
assert o == f64(4.4) assert o == f64(4.4)
data = [f64(7.88),f64(3.3),f64(12.0),f64(54.83),f64(76.122)] data = [f64(7.88), f64(3.3), f64(12.0), f64(54.83), f64(76.122)]
o = stats.median(data) o = stats.median(data)
assert o == f64(12.0) assert o == f64(12.0)
} }
fn test_mode() { fn test_mode() {
// Tests were also verified on Wolfram Alpha // Tests were also verified on Wolfram Alpha
mut data := [f64(2.7),f64(2.7),f64(4.45),f64(5.9),f64(10.0)] mut data := [f64(2.7), f64(2.7), f64(4.45), f64(5.9), f64(10.0)]
mut o := stats.mode(data) mut o := stats.mode(data)
assert o == f64(2.7) assert o == f64(2.7)
data = [f64(-3.0),f64(1.89),f64(1.89),f64(1.89),f64(9),f64(4.4),f64(4.4),f64(9),f64(67.31)] data = [f64(-3.0), f64(1.89), f64(1.89), f64(1.89), f64(9), f64(4.4), f64(4.4), f64(9),
f64(67.31),
]
o = stats.mode(data) o = stats.mode(data)
assert o == f64(1.89) assert o == f64(1.89)
// Testing greedy nature // Testing greedy nature
data = [f64(2.0),f64(4.0),f64(2.0),f64(4.0)] data = [f64(2.0), f64(4.0), f64(2.0), f64(4.0)]
o = stats.mode(data) o = stats.mode(data)
assert o == f64(2.0) assert o == f64(2.0)
} }
fn test_rms() { fn test_rms() {
// Tests were also verified on Wolfram Alpha // Tests were also verified on Wolfram Alpha
mut data := [f64(10.0),f64(4.45),f64(5.9),f64(2.7)] mut data := [f64(10.0), f64(4.45), f64(5.9), f64(2.7)]
mut o := stats.rms(data) mut o := stats.rms(data)
// Some issue with precision comparison in f64 using == operator hence serializing to string // Some issue with precision comparison in f64 using == operator hence serializing to string
assert tst_res(o.str(), '6.362046') assert tst_res(o.str(), '6.362046')
data = [f64(-3.0),f64(67.31),f64(4.4),f64(1.89)] data = [f64(-3.0), f64(67.31), f64(4.4), f64(1.89)]
o = stats.rms(data) o = stats.rms(data)
// Some issue with precision comparison in f64 using == operator hence serializing to string // Some issue with precision comparison in f64 using == operator hence serializing to string
assert tst_res(o.str(), '33.773393') assert tst_res(o.str(), '33.773393')
data = [f64(12.0),f64(7.88),f64(76.122),f64(54.83)] data = [f64(12.0), f64(7.88), f64(76.122), f64(54.83)]
o = stats.rms(data) o = stats.rms(data)
// Some issue with precision comparison in f64 using == operator hence serializing to string // Some issue with precision comparison in f64 using == operator hence serializing to string
assert tst_res(o.str(), '47.452561') assert tst_res(o.str(), '47.452561')
@ -129,15 +132,15 @@ fn test_rms() {
fn test_population_variance() { fn test_population_variance() {
// Tests were also verified on Wolfram Alpha // Tests were also verified on Wolfram Alpha
mut data := [f64(10.0),f64(4.45),f64(5.9),f64(2.7)] mut data := [f64(10.0), f64(4.45), f64(5.9), f64(2.7)]
mut o := stats.population_variance(data) mut o := stats.population_variance(data)
// Some issue with precision comparison in f64 using == operator hence serializing to string // Some issue with precision comparison in f64 using == operator hence serializing to string
assert tst_res(o.str(), '7.269219') assert tst_res(o.str(), '7.269219')
data = [f64(-3.0),f64(67.31),f64(4.4),f64(1.89)] data = [f64(-3.0), f64(67.31), f64(4.4), f64(1.89)]
o = stats.population_variance(data) o = stats.population_variance(data)
// Some issue with precision comparison in f64 using == operator hence serializing to string // Some issue with precision comparison in f64 using == operator hence serializing to string
assert tst_res(o.str(), '829.119550') assert tst_res(o.str(), '829.119550')
data = [f64(12.0),f64(7.88),f64(76.122),f64(54.83)] data = [f64(12.0), f64(7.88), f64(76.122), f64(54.83)]
o = stats.population_variance(data) o = stats.population_variance(data)
// Some issue with precision comparison in f64 using == operator hence serializing to string // Some issue with precision comparison in f64 using == operator hence serializing to string
assert tst_res(o.str(), '829.852282') assert tst_res(o.str(), '829.852282')
@ -145,15 +148,15 @@ fn test_population_variance() {
fn test_sample_variance() { fn test_sample_variance() {
// Tests were also verified on Wolfram Alpha // Tests were also verified on Wolfram Alpha
mut data := [f64(10.0),f64(4.45),f64(5.9),f64(2.7)] mut data := [f64(10.0), f64(4.45), f64(5.9), f64(2.7)]
mut o := stats.sample_variance(data) mut o := stats.sample_variance(data)
// Some issue with precision comparison in f64 using == operator hence serializing to string // Some issue with precision comparison in f64 using == operator hence serializing to string
assert tst_res(o.str(), '9.692292') assert tst_res(o.str(), '9.692292')
data = [f64(-3.0),f64(67.31),f64(4.4),f64(1.89)] data = [f64(-3.0), f64(67.31), f64(4.4), f64(1.89)]
o = stats.sample_variance(data) o = stats.sample_variance(data)
// Some issue with precision comparison in f64 using == operator hence serializing to string // Some issue with precision comparison in f64 using == operator hence serializing to string
assert tst_res(o.str(), '1105.492733') assert tst_res(o.str(), '1105.492733')
data = [f64(12.0),f64(7.88),f64(76.122),f64(54.83)] data = [f64(12.0), f64(7.88), f64(76.122), f64(54.83)]
o = stats.sample_variance(data) o = stats.sample_variance(data)
// Some issue with precision comparison in f64 using == operator hence serializing to string // Some issue with precision comparison in f64 using == operator hence serializing to string
assert tst_res(o.str(), '1106.469709') assert tst_res(o.str(), '1106.469709')
@ -161,15 +164,15 @@ fn test_sample_variance() {
fn test_population_stddev() { fn test_population_stddev() {
// Tests were also verified on Wolfram Alpha // Tests were also verified on Wolfram Alpha
mut data := [f64(10.0),f64(4.45),f64(5.9),f64(2.7)] mut data := [f64(10.0), f64(4.45), f64(5.9), f64(2.7)]
mut o := stats.population_stddev(data) mut o := stats.population_stddev(data)
// Some issue with precision comparison in f64 using == operator hence serializing to string // Some issue with precision comparison in f64 using == operator hence serializing to string
assert tst_res(o.str(), '2.696149') assert tst_res(o.str(), '2.696149')
data = [f64(-3.0),f64(67.31),f64(4.4),f64(1.89)] data = [f64(-3.0), f64(67.31), f64(4.4), f64(1.89)]
o = stats.population_stddev(data) o = stats.population_stddev(data)
// Some issue with precision comparison in f64 using == operator hence serializing to string // Some issue with precision comparison in f64 using == operator hence serializing to string
assert tst_res(o.str(), '28.794436') assert tst_res(o.str(), '28.794436')
data = [f64(12.0),f64(7.88),f64(76.122),f64(54.83)] data = [f64(12.0), f64(7.88), f64(76.122), f64(54.83)]
o = stats.population_stddev(data) o = stats.population_stddev(data)
// Some issue with precision comparison in f64 using == operator hence serializing to string // Some issue with precision comparison in f64 using == operator hence serializing to string
assert tst_res(o.str(), '28.807157') assert tst_res(o.str(), '28.807157')
@ -177,15 +180,15 @@ fn test_population_stddev() {
fn test_sample_stddev() { fn test_sample_stddev() {
// Tests were also verified on Wolfram Alpha // Tests were also verified on Wolfram Alpha
mut data := [f64(10.0),f64(4.45),f64(5.9),f64(2.7)] mut data := [f64(10.0), f64(4.45), f64(5.9), f64(2.7)]
mut o := stats.sample_stddev(data) mut o := stats.sample_stddev(data)
// Some issue with precision comparison in f64 using == operator hence serializing to string // Some issue with precision comparison in f64 using == operator hence serializing to string
assert tst_res(o.str(), '3.113245') assert tst_res(o.str(), '3.113245')
data = [f64(-3.0),f64(67.31),f64(4.4),f64(1.89)] data = [f64(-3.0), f64(67.31), f64(4.4), f64(1.89)]
o = stats.sample_stddev(data) o = stats.sample_stddev(data)
// Some issue with precision comparison in f64 using == operator hence serializing to string // Some issue with precision comparison in f64 using == operator hence serializing to string
assert tst_res(o.str(), '33.248951') assert tst_res(o.str(), '33.248951')
data = [f64(12.0),f64(7.88),f64(76.122),f64(54.83)] data = [f64(12.0), f64(7.88), f64(76.122), f64(54.83)]
o = stats.sample_stddev(data) o = stats.sample_stddev(data)
// Some issue with precision comparison in f64 using == operator hence serializing to string // Some issue with precision comparison in f64 using == operator hence serializing to string
assert tst_res(o.str(), '33.263639') assert tst_res(o.str(), '33.263639')
@ -193,15 +196,15 @@ fn test_sample_stddev() {
fn test_mean_absdev() { fn test_mean_absdev() {
// Tests were also verified on Wolfram Alpha // Tests were also verified on Wolfram Alpha
mut data := [f64(10.0),f64(4.45),f64(5.9),f64(2.7)] mut data := [f64(10.0), f64(4.45), f64(5.9), f64(2.7)]
mut o := stats.mean_absdev(data) mut o := stats.mean_absdev(data)
// Some issue with precision comparison in f64 using == operator hence serializing to string // Some issue with precision comparison in f64 using == operator hence serializing to string
assert tst_res(o.str(), '2.187500') assert tst_res(o.str(), '2.187500')
data = [f64(-3.0),f64(67.31),f64(4.4),f64(1.89)] data = [f64(-3.0), f64(67.31), f64(4.4), f64(1.89)]
o = stats.mean_absdev(data) o = stats.mean_absdev(data)
// Some issue with precision comparison in f64 using == operator hence serializing to string // Some issue with precision comparison in f64 using == operator hence serializing to string
assert tst_res(o.str(), '24.830000') assert tst_res(o.str(), '24.830000')
data = [f64(12.0),f64(7.88),f64(76.122),f64(54.83)] data = [f64(12.0), f64(7.88), f64(76.122), f64(54.83)]
o = stats.mean_absdev(data) o = stats.mean_absdev(data)
// Some issue with precision comparison in f64 using == operator hence serializing to string // Some issue with precision comparison in f64 using == operator hence serializing to string
assert tst_res(o.str(), '27.768000') assert tst_res(o.str(), '27.768000')
@ -209,46 +212,46 @@ fn test_mean_absdev() {
fn test_min() { fn test_min() {
// Tests were also verified on Wolfram Alpha // Tests were also verified on Wolfram Alpha
mut data := [f64(10.0),f64(4.45),f64(5.9),f64(2.7)] mut data := [f64(10.0), f64(4.45), f64(5.9), f64(2.7)]
mut o := stats.min(data) mut o := stats.min(data)
assert o == f64(2.7) assert o == f64(2.7)
data = [f64(-3.0),f64(67.31),f64(4.4),f64(1.89)] data = [f64(-3.0), f64(67.31), f64(4.4), f64(1.89)]
o = stats.min(data) o = stats.min(data)
assert o == f64(-3.0) assert o == f64(-3.0)
data = [f64(12.0),f64(7.88),f64(76.122),f64(54.83)] data = [f64(12.0), f64(7.88), f64(76.122), f64(54.83)]
o = stats.min(data) o = stats.min(data)
assert o == f64(7.88) assert o == f64(7.88)
} }
fn test_max() { fn test_max() {
// Tests were also verified on Wolfram Alpha // Tests were also verified on Wolfram Alpha
mut data := [f64(10.0),f64(4.45),f64(5.9),f64(2.7)] mut data := [f64(10.0), f64(4.45), f64(5.9), f64(2.7)]
mut o := stats.max(data) mut o := stats.max(data)
assert o == f64(10.0) assert o == f64(10.0)
data = [f64(-3.0),f64(67.31),f64(4.4),f64(1.89)] data = [f64(-3.0), f64(67.31), f64(4.4), f64(1.89)]
o = stats.max(data) o = stats.max(data)
assert o == f64(67.31) assert o == f64(67.31)
data = [f64(12.0),f64(7.88),f64(76.122),f64(54.83)] data = [f64(12.0), f64(7.88), f64(76.122), f64(54.83)]
o = stats.max(data) o = stats.max(data)
assert o == f64(76.122) assert o == f64(76.122)
} }
fn test_range() { fn test_range() {
// Tests were also verified on Wolfram Alpha // Tests were also verified on Wolfram Alpha
mut data := [f64(10.0),f64(4.45),f64(5.9),f64(2.7)] mut data := [f64(10.0), f64(4.45), f64(5.9), f64(2.7)]
mut o := stats.range(data) mut o := stats.range(data)
assert o == f64(7.3) assert o == f64(7.3)
data = [f64(-3.0),f64(67.31),f64(4.4),f64(1.89)] data = [f64(-3.0), f64(67.31), f64(4.4), f64(1.89)]
o = stats.range(data) o = stats.range(data)
assert o == f64(70.31) assert o == f64(70.31)
data = [f64(12.0),f64(7.88),f64(76.122),f64(54.83)] data = [f64(12.0), f64(7.88), f64(76.122), f64(54.83)]
o = stats.range(data) o = stats.range(data)
assert o == f64(68.242) assert o == f64(68.242)
} }
fn test_passing_empty() { fn test_passing_empty() {
data := []f64{} data := []f64{}
assert stats.freq(data,0) == 0 assert stats.freq(data, 0) == 0
assert stats.mean(data) == f64(0) assert stats.mean(data) == f64(0)
assert stats.geometric_mean(data) == f64(0) assert stats.geometric_mean(data) == f64(0)
assert stats.harmonic_mean(data) == f64(0) assert stats.harmonic_mean(data) == f64(0)

View File

@ -2,11 +2,12 @@
// Use of this source code is governed by an MIT license // Use of this source code is governed by an MIT license
// that can be found in the LICENSE file. // that can be found in the LICENSE file.
module math module math
// f32_bits returns the IEEE 754 binary representation of f, // f32_bits returns the IEEE 754 binary representation of f,
// with the sign bit of f and the result in the same bit position. // with the sign bit of f and the result in the same bit position.
// f32_bits(f32_from_bits(x)) == x. // f32_bits(f32_from_bits(x)) == x.
pub fn f32_bits(f f32) u32 { pub fn f32_bits(f f32) u32 {
p := *unsafe {&u32(&f)} p := *unsafe { &u32(&f) }
return p return p
} }
@ -15,7 +16,7 @@ pub fn f32_bits(f f32) u32 {
// and the result in the same bit position. // and the result in the same bit position.
// f32_from_bits(f32_bits(x)) == x. // f32_from_bits(f32_bits(x)) == x.
pub fn f32_from_bits(b u32) f32 { pub fn f32_from_bits(b u32) f32 {
p := *unsafe {&f32(&b)} p := *unsafe { &f32(&b) }
return p return p
} }
@ -23,7 +24,7 @@ pub fn f32_from_bits(b u32) f32 {
// with the sign bit of f and the result in the same bit position, // with the sign bit of f and the result in the same bit position,
// and f64_bits(f64_from_bits(x)) == x. // and f64_bits(f64_from_bits(x)) == x.
pub fn f64_bits(f f64) u64 { pub fn f64_bits(f f64) u64 {
p := *unsafe {&u64(&f)} p := *unsafe { &u64(&f) }
return p return p
} }
@ -32,6 +33,6 @@ pub fn f64_bits(f f64) u64 {
// and the result in the same bit position. // and the result in the same bit position.
// f64_from_bits(f64_bits(x)) == x. // f64_from_bits(f64_bits(x)) == x.
pub fn f64_from_bits(b u64) f64 { pub fn f64_from_bits(b u64) f64 {
p := *unsafe {&f64(&b)} p := *unsafe { &f64(&b) }
return p return p
} }

View File

@ -10,15 +10,15 @@ struct C.MYSQL_RES {
[typedef] [typedef]
struct C.MYSQL_FIELD { struct C.MYSQL_FIELD {
name byteptr // Name of column name &byte // Name of column
org_name byteptr // Original column name, if an alias org_name &byte // Original column name, if an alias
table byteptr // Table of column if column was a field table &byte // Table of column if column was a field
org_table byteptr // Org table name, if table was an alias org_table &byte // Org table name, if table was an alias
db byteptr // Database for table db &byte // Database for table
catalog byteptr // Catalog for table catalog &byte // Catalog for table
def byteptr // Default value (set by mysql_list_fields) def &byte // Default value (set by mysql_list_fields)
length int // Width of column (create length) length int // Width of column (create length)
max_length int // Max width for selected set max_length int // Max width for selected set
name_length u32 name_length u32
org_name_length u32 org_name_length u32
table_length u32 table_length u32
@ -34,15 +34,15 @@ struct C.MYSQL_FIELD {
fn C.mysql_init(mysql &C.MYSQL) &C.MYSQL fn C.mysql_init(mysql &C.MYSQL) &C.MYSQL
fn C.mysql_real_connect(mysql &C.MYSQL, host charptr, user charptr, passwd charptr, db charptr, port u32, unix_socket charptr, client_flag ConnectionFlag) &C.MYSQL fn C.mysql_real_connect(mysql &C.MYSQL, host &char, user &char, passwd &char, db &char, port u32, unix_socket &char, client_flag ConnectionFlag) &C.MYSQL
fn C.mysql_query(mysql &C.MYSQL, q byteptr) int fn C.mysql_query(mysql &C.MYSQL, q &byte) int
fn C.mysql_real_query(mysql &C.MYSQL, q byteptr, len u32) int fn C.mysql_real_query(mysql &C.MYSQL, q &byte, len u32) int
fn C.mysql_select_db(mysql &C.MYSQL, db byteptr) int fn C.mysql_select_db(mysql &C.MYSQL, db &byte) int
fn C.mysql_change_user(mysql &C.MYSQL, user byteptr, password byteptr, db byteptr) bool fn C.mysql_change_user(mysql &C.MYSQL, user &byte, password &byte, db &byte) bool
fn C.mysql_affected_rows(mysql &C.MYSQL) u64 fn C.mysql_affected_rows(mysql &C.MYSQL) u64
@ -50,7 +50,7 @@ fn C.mysql_options(mysql &C.MYSQL, option int, arg voidptr) int
fn C.mysql_get_option(mysql &C.MYSQL, option int, arg voidptr) int fn C.mysql_get_option(mysql &C.MYSQL, option int, arg voidptr) int
fn C.mysql_list_tables(mysql &C.MYSQL, wild byteptr) &C.MYSQL_RES fn C.mysql_list_tables(mysql &C.MYSQL, wild &byte) &C.MYSQL_RES
fn C.mysql_num_fields(res &C.MYSQL_RES) int fn C.mysql_num_fields(res &C.MYSQL_RES) int
@ -66,34 +66,34 @@ fn C.mysql_ping(mysql &C.MYSQL) int
fn C.mysql_store_result(mysql &C.MYSQL) &C.MYSQL_RES fn C.mysql_store_result(mysql &C.MYSQL) &C.MYSQL_RES
fn C.mysql_fetch_row(res &C.MYSQL_RES) &byteptr fn C.mysql_fetch_row(res &C.MYSQL_RES) &&byte
fn C.mysql_fetch_fields(res &C.MYSQL_RES) &C.MYSQL_FIELD fn C.mysql_fetch_fields(res &C.MYSQL_RES) &C.MYSQL_FIELD
fn C.mysql_free_result(res &C.MYSQL_RES) fn C.mysql_free_result(res &C.MYSQL_RES)
fn C.mysql_real_escape_string_quote(mysql &C.MYSQL, to byteptr, from byteptr, len u64, quote byte) u64 fn C.mysql_real_escape_string_quote(mysql &C.MYSQL, to &byte, from &byte, len u64, quote byte) u64
fn C.mysql_close(sock &C.MYSQL) fn C.mysql_close(sock &C.MYSQL)
// INFO & VERSION // INFO & VERSION
fn C.mysql_info(mysql &C.MYSQL) byteptr fn C.mysql_info(mysql &C.MYSQL) &byte
fn C.mysql_get_host_info(mysql &C.MYSQL) byteptr fn C.mysql_get_host_info(mysql &C.MYSQL) &byte
fn C.mysql_get_server_info(mysql &C.MYSQL) byteptr fn C.mysql_get_server_info(mysql &C.MYSQL) &byte
fn C.mysql_get_server_version(mysql &C.MYSQL) u64 fn C.mysql_get_server_version(mysql &C.MYSQL) u64
fn C.mysql_get_client_version() u64 fn C.mysql_get_client_version() u64
fn C.mysql_get_client_info() byteptr fn C.mysql_get_client_info() &byte
// DEBUG & ERROR INFO // DEBUG & ERROR INFO
fn C.mysql_error(mysql &C.MYSQL) byteptr fn C.mysql_error(mysql &C.MYSQL) &byte
fn C.mysql_errno(mysql &C.MYSQL) int fn C.mysql_errno(mysql &C.MYSQL) int
fn C.mysql_dump_debug_info(mysql &C.MYSQL) int fn C.mysql_dump_debug_info(mysql &C.MYSQL) int
fn C.mysql_debug(debug byteptr) fn C.mysql_debug(debug &byte)

View File

@ -33,7 +33,7 @@ pub struct Field {
} }
// fetch_row - fetches the next row from a result. // fetch_row - fetches the next row from a result.
pub fn (r Result) fetch_row() &byteptr { pub fn (r Result) fetch_row() &&byte {
return C.mysql_fetch_row(r.result) return C.mysql_fetch_row(r.result)
} }
@ -58,7 +58,7 @@ pub fn (r Result) rows() []Row {
if unsafe { rr[i] == 0 } { if unsafe { rr[i] == 0 } {
row.vals << '' row.vals << ''
} else { } else {
row.vals << mystring(unsafe { byteptr(rr[i]) }) row.vals << mystring(unsafe { &byte(rr[i]) })
} }
} }
rows << row rows << row
@ -66,7 +66,7 @@ pub fn (r Result) rows() []Row {
return rows return rows
} }
// maps - returns an array of maps, each containing a set of // maps - returns an array of maps, each containing a set of
// field name: field value pairs. // field name: field value pairs.
pub fn (r Result) maps() []map[string]string { pub fn (r Result) maps() []map[string]string {
mut array_map := []map[string]string{} mut array_map := []map[string]string{}

View File

@ -11,7 +11,7 @@ fn get_errno(conn &C.MYSQL) int {
} }
// resolve_nil_str - returns an empty string if passed value is a nil pointer. // resolve_nil_str - returns an empty string if passed value is a nil pointer.
fn resolve_nil_str(ptr byteptr) string { fn resolve_nil_str(ptr &byte) string {
if isnil(ptr) { if isnil(ptr) {
return '' return ''
} }
@ -19,7 +19,7 @@ fn resolve_nil_str(ptr byteptr) string {
} }
[inline] [inline]
fn mystring(b byteptr) string { fn mystring(b &byte) string {
unsafe { unsafe {
return b.vstring() return b.vstring()
} }

View File

@ -1,2 +1,2 @@
//this keeps vfmt happy // this keeps vfmt happy
module os2 module os2

View File

@ -1,30 +1,26 @@
module os2 module os2
#include <fcntl.h> #include <fcntl.h>
struct File { struct File {
fd int fd int
} }
fn C.perror(charptr) fn C.perror(&char)
fn C.open(&byte, int, int) int
fn C.open(byteptr, int, int) int fn C.write(voidptr, &byte, int) int
fn C.write(voidptr, byteptr, int) int
fn C.close(int) int fn C.close(int) int
pub fn create(path string) ?File { pub fn create(path string) ?File {
fd := C.open(path.str, C.O_CREAT | C.O_TRUNC | C.O_WRONLY, 0644) // 511 fd := C.open(path.str, C.O_CREAT | C.O_TRUNC | C.O_WRONLY, o644) // 511
if fd == -1 { if fd == -1 {
return error('failed to create "$path":') return error('failed to create "$path":')
// os.print_c_errno() // os.print_c_errno()
} }
return File{ return File{fd}
fd}
} }
pub fn (f File) writeln(s string) { pub fn (f File) writeln(s string) {

View File

@ -1,4 +1,4 @@
//import os2 // import os2
fn test_open() { fn test_open() {
/* /*
@ -8,4 +8,4 @@ fn test_open() {
f.close() f.close()
} }
*/ */
} }

View File

@ -36,11 +36,11 @@ pub:
dbname string dbname string
} }
fn C.PQconnectdb(a byteptr) &C.PGconn fn C.PQconnectdb(a &byte) &C.PGconn
fn C.PQerrorMessage(voidptr) byteptr fn C.PQerrorMessage(voidptr) &byte
fn C.PQgetvalue(&C.PGResult, int, int) byteptr fn C.PQgetvalue(&C.PGResult, int, int) &byte
fn C.PQstatus(voidptr) int fn C.PQstatus(voidptr) int
@ -50,20 +50,20 @@ fn C.PQntuples(&C.PGResult) int
fn C.PQnfields(&C.PGResult) int fn C.PQnfields(&C.PGResult) int
fn C.PQexec(voidptr, byteptr) &C.PGResult fn C.PQexec(voidptr, &byte) &C.PGResult
// Params: // Params:
// const Oid *paramTypes // const Oid *paramTypes
// const char *const *paramValues // const char *const *paramValues
// const int *paramLengths // const int *paramLengths
// const int *paramFormats // const int *paramFormats
fn C.PQexecParams(conn voidptr, command byteptr, nParams int, paramTypes int, paramValues byteptr, paramLengths int, paramFormats int, resultFormat int) &C.PGResult fn C.PQexecParams(conn voidptr, command &byte, nParams int, paramTypes int, paramValues &byte, paramLengths int, paramFormats int, resultFormat int) &C.PGResult
fn C.PQputCopyData(conn voidptr, buffer byteptr, nbytes int) int fn C.PQputCopyData(conn voidptr, buffer &byte, nbytes int) int
fn C.PQputCopyEnd(voidptr, &byte) int fn C.PQputCopyEnd(voidptr, &byte) int
fn C.PQgetCopyData(conn voidptr, buffer &byteptr, async int) int fn C.PQgetCopyData(conn voidptr, buffer &&byte, async int) int
fn C.PQclear(&C.PGResult) voidptr fn C.PQclear(&C.PGResult) voidptr
@ -186,7 +186,7 @@ pub fn (db DB) exec_one(query string) ?Row {
// exec_param_many executes a query with the provided parameters // exec_param_many executes a query with the provided parameters
pub fn (db DB) exec_param_many(query string, params []string) ?[]Row { pub fn (db DB) exec_param_many(query string, params []string) ?[]Row {
mut param_vals := []charptr{len: params.len} mut param_vals := []&char{len: params.len}
for i in 0 .. params.len { for i in 0 .. params.len {
param_vals[i] = params[i].str param_vals[i] = params[i].str
} }
@ -252,11 +252,11 @@ pub fn (db DB) copy_expert(query string, file io.ReaderWriter) ?int {
} }
} else if status == C.PGRES_COPY_OUT { } else if status == C.PGRES_COPY_OUT {
for { for {
address := byteptr(0) address := &byte(0)
n_bytes := C.PQgetCopyData(db.conn, &address, 0) n_bytes := C.PQgetCopyData(db.conn, &address, 0)
if n_bytes > 0 { if n_bytes > 0 {
mut local_buf := []byte{len: n_bytes} mut local_buf := []byte{len: n_bytes}
unsafe { C.memcpy(byteptr(local_buf.data), address, n_bytes) } unsafe { C.memcpy(&byte(local_buf.data), address, n_bytes) }
file.write(local_buf) or { file.write(local_buf) or {
C.PQfreemem(address) C.PQfreemem(address)
return err return err

View File

@ -1,9 +1,8 @@
module picohttpparser module picohttpparser
[inline] [inline; unsafe]
[unsafe] fn cpy(dst &byte, src &byte, len int) int {
fn cpy(dst byteptr, src byteptr, len int) int { unsafe { C.memcpy(dst, src, len) }
unsafe {C.memcpy(dst, src, len)}
return len return len
} }
@ -12,10 +11,10 @@ pub fn cmp(dst string, src string) bool {
if dst.len != src.len { if dst.len != src.len {
return false return false
} }
return unsafe {C.memcmp(dst.str, src.str, src.len) == 0} return unsafe { C.memcmp(dst.str, src.str, src.len) == 0 }
} }
[inline] [inline]
pub fn cmpn(dst string, src string, n int) bool { pub fn cmpn(dst string, src string, n int) bool {
return unsafe {C.memcmp(dst.str, src.str, n) == 0} return unsafe { C.memcmp(dst.str, src.str, n) == 0 }
} }

View File

@ -31,5 +31,5 @@ fn C.phr_parse_request_path(buf_start &char, len size_t, method PPchar, method_l
fn C.phr_parse_request_path_pipeline(buf_start &char, len size_t, method PPchar, method_len &size_t, path PPchar, path_len &size_t) int fn C.phr_parse_request_path_pipeline(buf_start &char, len size_t, method PPchar, method_len &size_t, path PPchar, path_len &size_t) int
fn C.get_date() &byte fn C.get_date() &byte
// char * u64toa(uint64_t value, char *buffer) // static inline int u64toa(char* buf, uint64_t value) {
fn C.u64toa(buffer &char, value u64) &char fn C.u64toa(buffer &char, value u64) int

View File

@ -1,12 +1,12 @@
module picohttpparser module picohttpparser
pub struct Response { pub struct Response {
fd int fd int
pub: pub:
date byteptr date &byte = 0
buf_start byteptr buf_start &byte = 0
pub mut: pub mut:
buf byteptr buf &byte = 0
} }
[inline] [inline]

View File

@ -43,7 +43,9 @@ pub interface PRNG {
f64_in_range(min f64, max f64) f64 f64_in_range(min f64, max f64) f64
} }
__global ( default_rng &PRNG ) __global (
default_rng &PRNG
)
// init initializes the default RNG. // init initializes the default RNG.
fn init() { fn init() {
@ -63,7 +65,7 @@ pub fn get_current_rng() &PRNG {
} }
// set_rng changes the default RNG from wyrand.WyRandRNG (or whatever the last RNG was) to the one // set_rng changes the default RNG from wyrand.WyRandRNG (or whatever the last RNG was) to the one
// provided by the user. Note that this new RNG must be seeded manually with a constant seed or the // provided by the user. Note that this new RNG must be seeded manually with a constant seed or the
// `seed.time_seed_array()` method. Also, it is recommended to store the old RNG in a variable and // `seed.time_seed_array()` method. Also, it is recommended to store the old RNG in a variable and
// should be restored if work with the custom RNG is complete. It is not necessary to restore if the // should be restored if work with the custom RNG is complete. It is not necessary to restore if the
// program terminates soon afterwards. // program terminates soon afterwards.

File diff suppressed because it is too large Load Diff

View File

@ -1,17 +1,18 @@
module regex module regex
import strings import strings
// compile_opt compile RE pattern string // compile_opt compile RE pattern string
pub fn (mut re RE) compile_opt(pattern string) ? { pub fn (mut re RE) compile_opt(pattern string) ? {
re_err,err_pos := re.impl_compile(pattern) re_err, err_pos := re.impl_compile(pattern)
if re_err != compile_ok { if re_err != compile_ok {
mut err_msg := strings.new_builder(300) mut err_msg := strings.new_builder(300)
err_msg.write_string("\nquery: $pattern\n") err_msg.write_string('\nquery: $pattern\n')
line := "-".repeat(err_pos) line := '-'.repeat(err_pos)
err_msg.write_string("err : ${line}^\n") err_msg.write_string('err : $line^\n')
err_str := re.get_parse_error_string(re_err) err_str := re.get_parse_error_string(re_err)
err_msg.write_string("ERROR: $err_str\n") err_msg.write_string('ERROR: $err_str\n')
return error_with_code(err_msg.str(), re_err) return error_with_code(err_msg.str(), re_err)
} }
} }
@ -19,15 +20,15 @@ pub fn (mut re RE) compile_opt(pattern string) ? {
// new_regex create a RE of small size, usually sufficient for ordinary use // new_regex create a RE of small size, usually sufficient for ordinary use
pub fn new() RE { pub fn new() RE {
// init regex // init regex
mut re := regex.RE{} mut re := RE{}
re.prog = []Token {len: max_code_len + 1} // max program length, can not be longer then the pattern re.prog = []Token{len: max_code_len + 1} // max program length, can not be longer then the pattern
re.cc = []CharClass{len: max_code_len} // can not be more char class the the length of the pattern re.cc = []CharClass{len: max_code_len} // can not be more char class the the length of the pattern
re.group_csave_flag = false // enable continuos group saving re.group_csave_flag = false // enable continuos group saving
re.group_max_nested = 128 // set max 128 group nested re.group_max_nested = 128 // set max 128 group nested
re.group_max = max_code_len >> 1 // we can't have more groups than the half of the pattern legth re.group_max = max_code_len >> 1 // we can't have more groups than the half of the pattern legth
re.group_stack = []int{len: re.group_max, init: -1} re.group_stack = []int{len: re.group_max, init: -1}
re.group_data = []int{len: re.group_max, init: -1} re.group_data = []int{len: re.group_max, init: -1}
return re return re
} }
@ -35,18 +36,18 @@ pub fn new() RE {
// regex_opt create new RE object from RE pattern string // regex_opt create new RE object from RE pattern string
pub fn regex_opt(pattern string) ?RE { pub fn regex_opt(pattern string) ?RE {
// init regex // init regex
mut re := regex.RE{} mut re := RE{}
re.prog = []Token {len: pattern.len + 1} // max program length, can not be longer then the pattern re.prog = []Token{len: pattern.len + 1} // max program length, can not be longer then the pattern
re.cc = []CharClass{len: pattern.len} // can not be more char class the the length of the pattern re.cc = []CharClass{len: pattern.len} // can not be more char class the the length of the pattern
re.group_csave_flag = false // enable continuos group saving re.group_csave_flag = false // enable continuos group saving
re.group_max_nested = 128 // set max 128 group nested re.group_max_nested = 128 // set max 128 group nested
re.group_max = pattern.len >> 1 // we can't have more groups than the half of the pattern legth re.group_max = pattern.len >> 1 // we can't have more groups than the half of the pattern legth
re.group_stack = []int{len: re.group_max, init: -1} re.group_stack = []int{len: re.group_max, init: -1}
re.group_data = []int{len: re.group_max, init: -1} re.group_data = []int{len: re.group_max, init: -1}
// compile the pattern // compile the pattern
re.compile_opt(pattern)? re.compile_opt(pattern) ?
return re return re
} }

View File

@ -1,13 +1,12 @@
/* /*
regex 1.0 alpha regex 1.0 alpha
Copyright (c) 2019-2021 Dario Deledda. All rights reserved. Copyright (c) 2019-2021 Dario Deledda. All rights reserved.
Use of this source code is governed by an MIT license Use of this source code is governed by an MIT license
that can be found in the LICENSE file. that can be found in the LICENSE file.
*/ */
module regex module regex
import strings import strings
/****************************************************************************** /******************************************************************************
@ -16,19 +15,19 @@ import strings
* *
******************************************************************************/ ******************************************************************************/
// regex create a regex object from the query string, retunr RE object and errors as re_err, err_pos // regex create a regex object from the query string, retunr RE object and errors as re_err, err_pos
pub fn regex_base(pattern string) (RE,int,int){ pub fn regex_base(pattern string) (RE, int, int) {
// init regex // init regex
mut re := regex.RE{} mut re := RE{}
re.prog = []Token {len: pattern.len + 1} // max program length, can not be longer then the pattern re.prog = []Token{len: pattern.len + 1} // max program length, can not be longer then the pattern
re.cc = []CharClass{len: pattern.len} // can not be more char class the the length of the pattern re.cc = []CharClass{len: pattern.len} // can not be more char class the the length of the pattern
re.group_csave_flag = false // enable continuos group saving re.group_csave_flag = false // enable continuos group saving
re.group_max_nested = 128 // set max 128 group nested re.group_max_nested = 128 // set max 128 group nested
re.group_max = pattern.len >> 1 // we can't have more groups than the half of the pattern legth re.group_max = pattern.len >> 1 // we can't have more groups than the half of the pattern legth
re.group_stack = []int{len: re.group_max, init: -1} re.group_stack = []int{len: re.group_max, init: -1}
re.group_data = []int{len: re.group_max, init: -1} re.group_data = []int{len: re.group_max, init: -1}
re_err,err_pos := re.impl_compile(pattern) re_err, err_pos := re.impl_compile(pattern)
return re, re_err, err_pos return re, re_err, err_pos
} }
@ -40,10 +39,10 @@ pub fn regex_base(pattern string) (RE,int,int){
// get_group_bounds_by_name get a group boundaries by its name // get_group_bounds_by_name get a group boundaries by its name
pub fn (re RE) get_group_bounds_by_name(group_name string) (int, int) { pub fn (re RE) get_group_bounds_by_name(group_name string) (int, int) {
if group_name in re.group_map { if group_name in re.group_map {
tmp_index := re.group_map[group_name]-1 tmp_index := re.group_map[group_name] - 1
start := re.groups[tmp_index * 2] start := re.groups[tmp_index * 2]
end := re.groups[tmp_index * 2 + 1] end := re.groups[tmp_index * 2 + 1]
return start,end return start, end
} }
return -1, -1 return -1, -1
} }
@ -51,14 +50,14 @@ pub fn (re RE) get_group_bounds_by_name(group_name string) (int, int) {
// get_group_by_name get a group boundaries by its name // get_group_by_name get a group boundaries by its name
pub fn (re RE) get_group_by_name(in_txt string, group_name string) string { pub fn (re RE) get_group_by_name(in_txt string, group_name string) string {
if group_name in re.group_map { if group_name in re.group_map {
tmp_index := re.group_map[group_name]-1 tmp_index := re.group_map[group_name] - 1
start := re.groups[tmp_index * 2] start := re.groups[tmp_index * 2]
end := re.groups[tmp_index * 2 + 1] end := re.groups[tmp_index * 2 + 1]
if start >= 0 && end > start { if start >= 0 && end > start {
return in_txt[start..end] return in_txt[start..end]
} }
} }
return "" return ''
} }
// get_group_by_id get a group string by its id // get_group_by_id get a group string by its id
@ -66,16 +65,16 @@ pub fn (re RE) get_group_by_id(in_txt string, group_id int) string {
if group_id < (re.groups.len >> 1) { if group_id < (re.groups.len >> 1) {
index := group_id << 1 index := group_id << 1
start := re.groups[index] start := re.groups[index]
end := re.groups[index + 1] end := re.groups[index + 1]
if start >= 0 && end > start { if start >= 0 && end > start {
return in_txt[start..end] return in_txt[start..end]
} }
} }
return "" return ''
} }
// get_group_by_id get a group boundaries by its id // get_group_by_id get a group boundaries by its id
pub fn (re RE) get_group_bounds_by_id(group_id int) (int,int) { pub fn (re RE) get_group_bounds_by_id(group_id int) (int, int) {
if group_id < re.group_count { if group_id < re.group_count {
index := group_id << 1 index := group_id << 1
return re.groups[index], re.groups[index + 1] return re.groups[index], re.groups[index + 1]
@ -83,8 +82,7 @@ pub fn (re RE) get_group_bounds_by_id(group_id int) (int,int) {
return -1, -1 return -1, -1
} }
pub pub struct Re_group {
struct Re_group {
pub: pub:
start int = -1 start int = -1
end int = -1 end int = -1
@ -94,17 +92,20 @@ pub:
pub fn (re RE) get_group_list() []Re_group { pub fn (re RE) get_group_list() []Re_group {
mut res := []Re_group{len: re.groups.len >> 1} mut res := []Re_group{len: re.groups.len >> 1}
mut gi := 0 mut gi := 0
//println("len: ${re.groups.len} groups: ${re.groups}") // println("len: ${re.groups.len} groups: ${re.groups}")
for gi < re.groups.len { for gi < re.groups.len {
if re.groups[gi] >= 0 { if re.groups[gi] >= 0 {
txt_st := re.groups[gi] txt_st := re.groups[gi]
txt_en := re.groups[gi+1] txt_en := re.groups[gi + 1]
//println("#${gi/2} start: ${re.groups[gi]} end: ${re.groups[gi + 1]} ") // println("#${gi/2} start: ${re.groups[gi]} end: ${re.groups[gi + 1]} ")
if txt_st >= 0 && txt_en > txt_st { if txt_st >= 0 && txt_en > txt_st {
tmp := Re_group{ start: re.groups[gi], end: re.groups[gi + 1]} tmp := Re_group{
//println(tmp) start: re.groups[gi]
end: re.groups[gi + 1]
}
// println(tmp)
res[gi >> 1] = tmp res[gi >> 1] = tmp
} else { } else {
res[gi >> 1] = Re_group{} res[gi >> 1] = Re_group{}
@ -122,8 +123,7 @@ pub fn (re RE) get_group_list() []Re_group {
******************************************************************************/ ******************************************************************************/
// match_string Match the pattern with the in_txt string // match_string Match the pattern with the in_txt string
[direct_array_access] [direct_array_access]
pub fn (mut re RE) match_string(in_txt string) (int,int) { pub fn (mut re RE) match_string(in_txt string) (int, int) {
start, mut end := re.match_base(in_txt.str, in_txt.len + 1) start, mut end := re.match_base(in_txt.str, in_txt.len + 1)
if end > in_txt.len { if end > in_txt.len {
end = in_txt.len end = in_txt.len
@ -144,7 +144,6 @@ pub fn (mut re RE) match_string(in_txt string) (int,int) {
return start, end return start, end
} }
/****************************************************************************** /******************************************************************************
* *
* Finders * Finders
@ -173,9 +172,9 @@ fn (mut re RE) find_imp(in_txt string) (int,int) {
// find try to find the first match in the input string // find try to find the first match in the input string
[direct_array_access] [direct_array_access]
pub fn (mut re RE) find(in_txt string) (int,int) { pub fn (mut re RE) find(in_txt string) (int, int) {
//old_flag := re.flag // old_flag := re.flag
//re.flag |= f_src // enable search mode // re.flag |= f_src // enable search mode
mut i := 0 mut i := 0
for i < in_txt.len { for i < in_txt.len {
@ -183,30 +182,29 @@ pub fn (mut re RE) find(in_txt string) (int,int) {
mut s := -1 mut s := -1
mut e := -1 mut e := -1
unsafe { unsafe {
tmp_str := tos(in_txt.str+i, in_txt.len-i) tmp_str := tos(in_txt.str + i, in_txt.len - i)
s,e = re.match_string(tmp_str) s, e = re.match_string(tmp_str)
} }
//------------------------ //------------------------
//s,e := re.find_imp(in_txt[i..]) // s,e := re.find_imp(in_txt[i..])
//------------------------ //------------------------
if s >= 0 && e > s { if s >= 0 && e > s {
//println("find match in: ${i+s},${i+e} [${in_txt[i+s..i+e]}]") // println("find match in: ${i+s},${i+e} [${in_txt[i+s..i+e]}]")
//re.flag = old_flag // re.flag = old_flag
return i+s, i+e return i + s, i + e
} else { } else {
i++ i++
} }
} }
//re.flag = old_flag // re.flag = old_flag
return -1, -1 return -1, -1
} }
// find try to find the first match in the input string strarting from start index // find try to find the first match in the input string strarting from start index
[direct_array_access] [direct_array_access]
pub fn (mut re RE) find_from(in_txt string, start int) (int,int) { pub fn (mut re RE) find_from(in_txt string, start int) (int, int) {
old_flag := re.flag old_flag := re.flag
re.flag |= f_src // enable search mode re.flag |= f_src // enable search mode
mut i := start mut i := start
if i < 0 { if i < 0 {
@ -214,25 +212,24 @@ pub fn (mut re RE) find_from(in_txt string, start int) (int,int) {
} }
for i < in_txt.len { for i < in_txt.len {
//--- speed references --- //--- speed references ---
mut s := -1 mut s := -1
mut e := -1 mut e := -1
unsafe { unsafe {
tmp_str := tos(in_txt.str+i, in_txt.len-i) tmp_str := tos(in_txt.str + i, in_txt.len - i)
s,e = re.match_string(tmp_str) s, e = re.match_string(tmp_str)
} }
//------------------------ //------------------------
//s,e = re.find_imp(in_txt[i..]) // s,e = re.find_imp(in_txt[i..])
//------------------------ //------------------------
if s >= 0 && e > s { if s >= 0 && e > s {
//println("find match in: ${i+s},${i+e} [${in_txt[i+s..i+e]}]") // println("find match in: ${i+s},${i+e} [${in_txt[i+s..i+e]}]")
re.flag = old_flag re.flag = old_flag
return i+s, i+e return i + s, i + e
} else { } else {
i++ i++
} }
} }
re.flag = old_flag re.flag = old_flag
return -1, -1 return -1, -1
@ -241,8 +238,8 @@ pub fn (mut re RE) find_from(in_txt string, start int) (int,int) {
// find_all find all the non overlapping occurrences of the match pattern // find_all find all the non overlapping occurrences of the match pattern
[direct_array_access] [direct_array_access]
pub fn (mut re RE) find_all(in_txt string) []int { pub fn (mut re RE) find_all(in_txt string) []int {
//old_flag := re.flag // old_flag := re.flag
//re.flag |= f_src // enable search mode // re.flag |= f_src // enable search mode
mut i := 0 mut i := 0
mut res := []int{} mut res := []int{}
@ -253,25 +250,24 @@ pub fn (mut re RE) find_all(in_txt string) []int {
mut s := -1 mut s := -1
mut e := -1 mut e := -1
unsafe { unsafe {
tmp_str := tos(in_txt.str+i, in_txt.len-i) tmp_str := tos(in_txt.str + i, in_txt.len - i)
s,e = re.match_string(tmp_str) s, e = re.match_string(tmp_str)
} }
//------------------------ //------------------------
//s,e := re.find_imp(in_txt[i..]) // s,e := re.find_imp(in_txt[i..])
//------------------------ //------------------------
if s >= 0 && e > s && i+s > ls { if s >= 0 && e > s && i + s > ls {
//println("find match in: ${i+s},${i+e} [${in_txt[i+s..i+e]}] ls:$ls") // println("find match in: ${i+s},${i+e} [${in_txt[i+s..i+e]}] ls:$ls")
res << i+s res << i + s
res << i+e res << i + e
ls = i+s ls = i + s
i = i+e i = i + e
continue continue
} else { } else {
i++ i++
} }
} }
//re.flag = old_flag // re.flag = old_flag
return res return res
} }
@ -287,25 +283,25 @@ pub fn (mut re RE) find_all_str(in_txt string) []string {
mut s := -1 mut s := -1
mut e := -1 mut e := -1
unsafe { unsafe {
tmp_str := tos(in_txt.str+i, in_txt.len-i) tmp_str := tos(in_txt.str + i, in_txt.len - i)
s,e = re.find(tmp_str) s, e = re.find(tmp_str)
} }
//------------------------ //------------------------
//s,e := re.find(in_txt[i..]) // s,e := re.find(in_txt[i..])
//------------------------ //------------------------
if s >= 0 && e > s && i+s > ls { if s >= 0 && e > s && i + s > ls {
//println("find match in: ${i+s},${i+e} [${in_txt[i+s..i+e]}] ls:$ls") // println("find match in: ${i+s},${i+e} [${in_txt[i+s..i+e]}] ls:$ls")
res << in_txt[i+s..i+e] res << in_txt[i + s..i + e]
ls = i+s ls = i + s
i = i+e i = i + e
continue continue
} else { } else {
i++ i++
} }
} }
return res return res
} }
/****************************************************************************** /******************************************************************************
* *
* Replacers * Replacers
@ -316,7 +312,7 @@ pub fn (mut re RE) replace_simple(in_txt string, repl string) string {
pos := re.find_all(in_txt) pos := re.find_all(in_txt)
if pos.len > 0 { if pos.len > 0 {
mut res := "" mut res := ''
mut i := 0 mut i := 0
mut s1 := 0 mut s1 := 0
@ -325,7 +321,7 @@ pub fn (mut re RE) replace_simple(in_txt string, repl string) string {
for i < pos.len { for i < pos.len {
e1 = pos[i] e1 = pos[i]
res += in_txt[s1..e1] + repl res += in_txt[s1..e1] + repl
s1 = pos[i+1] s1 = pos[i + 1]
i += 2 i += 2
} }
@ -335,7 +331,6 @@ pub fn (mut re RE) replace_simple(in_txt string, repl string) string {
return in_txt return in_txt
} }
// type of function used for custom replace // type of function used for custom replace
// in_txt source text // in_txt source text
// start index of the start of the match in in_txt // start index of the start of the match in in_txt
@ -345,38 +340,38 @@ pub type FnReplace = fn (re RE, in_txt string, start int, end int) string
// replace_by_fn return a string where the matches are replaced with the string from the repl_fn callback function // replace_by_fn return a string where the matches are replaced with the string from the repl_fn callback function
pub fn (mut re RE) replace_by_fn(in_txt string, repl_fn FnReplace) string { pub fn (mut re RE) replace_by_fn(in_txt string, repl_fn FnReplace) string {
mut i := 0 mut i := 0
mut res := strings.new_builder(in_txt.len) mut res := strings.new_builder(in_txt.len)
mut last_end := 0 mut last_end := 0
for i < in_txt.len { for i < in_txt.len {
//println("Find Start. $i [${in_txt[i..]}]") // println("Find Start. $i [${in_txt[i..]}]")
s, e := re.find_from(in_txt,i) s, e := re.find_from(in_txt, i)
//println("Find End.") // println("Find End.")
if s >= 0 && e > s { if s >= 0 && e > s {
//println("find match in: ${s},${e} [${in_txt[s..e]}]") // println("find match in: ${s},${e} [${in_txt[s..e]}]")
if last_end < s { if last_end < s {
res.write_string(in_txt[last_end..s]) res.write_string(in_txt[last_end..s])
} }
for g_i in 0..re.group_count { for g_i in 0 .. re.group_count {
re.groups[g_i << 1 ] += i re.groups[g_i << 1] += i
re.groups[(g_i << 1) + 1] += i re.groups[(g_i << 1) + 1] += i
} }
repl := repl_fn(re, in_txt, s, e) repl := repl_fn(re, in_txt, s, e)
//println("repl res: $repl") // println("repl res: $repl")
res.write_string(repl) res.write_string(repl)
//res.write_string("[[${in_txt[s..e]}]]") // res.write_string("[[${in_txt[s..e]}]]")
last_end = e last_end = e
i = e i = e
} else { } else {
break break
//i++ // i++
} }
//println(i) // println(i)
} }
if last_end >= 0 && last_end < in_txt.len { if last_end >= 0 && last_end < in_txt.len {
res.write_string(in_txt[last_end..]) res.write_string(in_txt[last_end..])
@ -384,66 +379,65 @@ pub fn (mut re RE) replace_by_fn(in_txt string, repl_fn FnReplace) string {
return res.str() return res.str()
} }
fn (re RE) parsed_replace_string(in_txt string, repl string) string { fn (re RE) parsed_replace_string(in_txt string, repl string) string {
str_lst := repl.split("\\") str_lst := repl.split('\\')
mut res := str_lst[0] mut res := str_lst[0]
mut i := 1 mut i := 1
for i < str_lst.len { for i < str_lst.len {
tmp := str_lst[i] tmp := str_lst[i]
//println("tmp: ${tmp}") // println("tmp: ${tmp}")
if tmp.len > 0 && tmp[0] >= `0` && tmp[0] <= `9` { if tmp.len > 0 && tmp[0] >= `0` && tmp[0] <= `9` {
group_id := int(tmp[0] - `0`) group_id := int(tmp[0] - `0`)
group := re.get_group_by_id(in_txt, group_id) group := re.get_group_by_id(in_txt, group_id)
//println("group: $group_id [$group]") // println("group: $group_id [$group]")
res += "${group}${tmp[1..]}" res += '$group${tmp[1..]}'
} else { } else {
res += '\\'+tmp res += '\\' + tmp
} }
i++ i++
} }
return res return res
} }
// replace return a string where the matches are replaced with the repl_str string, // replace return a string where the matches are replaced with the repl_str string,
// this function support use groups in the replace string // this function support use groups in the replace string
pub fn (mut re RE) replace(in_txt string, repl_str string) string { pub fn (mut re RE) replace(in_txt string, repl_str string) string {
mut i := 0 mut i := 0
mut res := strings.new_builder(in_txt.len) mut res := strings.new_builder(in_txt.len)
mut last_end := 0 mut last_end := 0
for i < in_txt.len { for i < in_txt.len {
//println("Find Start. $i [${in_txt[i..]}]") // println("Find Start. $i [${in_txt[i..]}]")
s, e := re.find_from(in_txt,i) s, e := re.find_from(in_txt, i)
//println("Find End.") // println("Find End.")
if s >= 0 && e > s { if s >= 0 && e > s {
//println("find match in: ${s},${e} [${in_txt[s..e]}]") // println("find match in: ${s},${e} [${in_txt[s..e]}]")
if last_end < s { if last_end < s {
res.write_string(in_txt[last_end..s]) res.write_string(in_txt[last_end..s])
} }
for g_i in 0..re.group_count { for g_i in 0 .. re.group_count {
re.groups[g_i << 1 ] += i re.groups[g_i << 1] += i
re.groups[(g_i << 1) + 1] += i re.groups[(g_i << 1) + 1] += i
} }
//repl := repl_fn(re, in_txt, s, e) // repl := repl_fn(re, in_txt, s, e)
repl := re.parsed_replace_string(in_txt, repl_str) repl := re.parsed_replace_string(in_txt, repl_str)
//println("repl res: $repl") // println("repl res: $repl")
res.write_string(repl) res.write_string(repl)
//res.write_string("[[${in_txt[s..e]}]]") // res.write_string("[[${in_txt[s..e]}]]")
last_end = e last_end = e
i = e i = e
} else { } else {
break break
//i++ // i++
} }
//println(i) // println(i)
} }
if last_end >= 0 && last_end < in_txt.len { if last_end >= 0 && last_end < in_txt.len {
res.write_string(in_txt[last_end..]) res.write_string(in_txt[last_end..])
} }
return res.str() return res.str()
} }

View File

@ -1,11 +1,17 @@
module audio module audio
$if linux {
// provide a nicer error for the user that does not have ALSA installed
#include <alsa/asoundlib.h> # Please install the `libasound2-dev` package
}
#flag -I @VEXEROOT/thirdparty/sokol #flag -I @VEXEROOT/thirdparty/sokol
#define SOKOL_IMPL #define SOKOL_IMPL
#include "sokol_audio.h" #include "sokol_audio.h"
#flag linux -lasound #flag linux -lasound
#flag darwin -framework AudioToolbox #flag darwin -framework AudioToolbox
#flag windows -lole32 #flag windows -lole32
// //
pub type FNStreamingCB = fn (buffer &f32, num_frames int, num_channels int) pub type FNStreamingCB = fn (buffer &f32, num_frames int, num_channels int)

View File

@ -4,7 +4,7 @@ import fontstash
import sokol.c import sokol.c
pub const ( pub const (
used_import = fontstash.used_import + c.used_import used_import = fontstash.used_import + c.used_import
) )
#flag linux -I. #flag linux -I.

View File

@ -1,128 +1,120 @@
module gfx module gfx
pub enum Backend { pub enum Backend {
glcore33 glcore33
gles2 gles2
gles3 gles3
d3d11 d3d11
metal_ios metal_ios
metal_macos metal_macos
metal_simulator metal_simulator
dummy dummy
} }
pub enum PixelFormat { pub enum PixelFormat {
_default /* value 0 reserved for default-init */ _default // value 0 reserved for default-init
@none @none
r8
r8 r8sn
r8sn r8ui
r8ui r8si
r8si r16
r16sn
r16 r16ui
r16sn r16si
r16ui r16f
r16si rg8
r16f rg8sn
rg8 rg8ui
rg8sn rg8si
rg8ui r32ui
rg8si r32si
r32f
r32ui rg16
r32si rg16sn
r32f rg16ui
rg16 rg16si
rg16sn rg16f
rg16ui rgba8
rg16si rgba8sn
rg16f rgba8ui
rgba8 rgba8si
rgba8sn bgra8
rgba8ui rgb10a2
rgba8si rg11b10f
bgra8 rg32ui
rgb10a2 rg32si
rg11b10f rg32f
rgba16
rg32ui rgba16sn
rg32si rgba16ui
rg32f rgba16si
rgba16 rgba16f
rgba16sn rgba32ui
rgba16ui rgba32si
rgba16si rgba32f
rgba16f depth
depth_stencil
rgba32ui bc1_rgba
rgba32si bc2_rgba
rgba32f bc3_rgba
bc4_r
depth bc4_rsn
depth_stencil bc5_rg
bc5_rgsn
bc1_rgba bc6h_rgbf
bc2_rgba bc6h_rgbuf
bc3_rgba bc7_rgba
bc4_r pvrtc_rgb_2bpp
bc4_rsn pvrtc_rgb_4bpp
bc5_rg pvrtc_rgba_2bpp
bc5_rgsn pvrtc_rgba_4bpp
bc6h_rgbf etc2_rgb8
bc6h_rgbuf etc2_rgb8a1
bc7_rgba etc2_rgba8
pvrtc_rgb_2bpp etc2_rg11
pvrtc_rgb_4bpp etc2_rg11sn
pvrtc_rgba_2bpp _num
pvrtc_rgba_4bpp
etc2_rgb8
etc2_rgb8a1
etc2_rgba8
etc2_rg11
etc2_rg11sn
_num
} }
pub enum ResourceState { pub enum ResourceState {
initial initial
alloc alloc
valid valid
failed failed
invalid invalid
} }
pub enum Usage { pub enum Usage {
_default /* value 0 reserved for default-init */ _default // value 0 reserved for default-init
immutable immutable
dynamic dynamic
stream stream
_num _num
} }
pub enum BufferType { pub enum BufferType {
_default /* value 0 reserved for default-init */ _default // value 0 reserved for default-init
vertexbuffer vertexbuffer
indexbuffer indexbuffer
_num _num
} }
pub enum IndexType { pub enum IndexType {
_default /* value 0 reserved for default-init */ _default // value 0 reserved for default-init
@none @none
uint16 uint16
uint32 uint32
_num _num
} }
pub enum ImageType { pub enum ImageType {
_default /* value 0 reserved for default-init */ _default // value 0 reserved for default-init
_2d _2d
cube cube
_3d _3d
array array
_num _num
} }
pub enum CubeFace { pub enum CubeFace {
@ -142,164 +134,164 @@ pub enum ShaderStage {
} }
pub enum PrimitiveType { pub enum PrimitiveType {
_default /* value 0 reserved for default-init */ _default // value 0 reserved for default-init
points points
lines lines
line_strip line_strip
triangles triangles
triangle_strip triangle_strip
_num _num
} }
pub enum Filter { pub enum Filter {
_default /* value 0 reserved for default-init */ _default // value 0 reserved for default-init
nearest nearest
linear linear
nearest_mipmap_nearest nearest_mipmap_nearest
nearest_mipmap_linear nearest_mipmap_linear
linear_mipmap_nearest linear_mipmap_nearest
linear_mipmap_linear linear_mipmap_linear
_num _num
} }
pub enum Wrap { pub enum Wrap {
_default /* value 0 reserved for default-init */ _default // value 0 reserved for default-init
repeat repeat
clamp_to_edge clamp_to_edge
clamp_to_border clamp_to_border
mirrored_repeat mirrored_repeat
_num _num
} }
pub enum BorderColor { pub enum BorderColor {
_default /* value 0 reserved for default-init */ _default // value 0 reserved for default-init
transparent_black transparent_black
opaque_black opaque_black
opaque_white opaque_white
_num _num
} }
pub enum VertexFormat { pub enum VertexFormat {
invalid invalid
float float
float2 float2
float3 float3
float4 float4
byte4 byte4
byte4n byte4n
ubyte4 ubyte4
ubyte4n ubyte4n
short2 short2
short2n short2n
ushort2n ushort2n
short4 short4
short4n short4n
ushort4n ushort4n
uint10_n2 uint10_n2
_num _num
} }
pub enum VertexStep { pub enum VertexStep {
_default /* value 0 reserved for default-init */ _default // value 0 reserved for default-init
per_vertex per_vertex
per_instance per_instance
_num _num
} }
pub enum UniformType { pub enum UniformType {
invalid invalid
float float
float2 float2
float3 float3
float4 float4
mat4 mat4
_num _num
} }
pub enum CullMode { pub enum CullMode {
_default /* value 0 reserved for default-init */ _default // value 0 reserved for default-init
@none @none
front front
back back
_num _num
} }
pub enum FaceWinding { pub enum FaceWinding {
_facewinding_default /* value 0 reserved for default-init */ _facewinding_default // value 0 reserved for default-init
facewinding_ccw facewinding_ccw
facewinding_cw facewinding_cw
_facewinding_num _facewinding_num
} }
pub enum CompareFunc { pub enum CompareFunc {
_default /* value 0 reserved for default-init */ _default // value 0 reserved for default-init
never never
less less
equal equal
less_equal less_equal
greater greater
not_equal not_equal
greater_equal greater_equal
always always
_num _num
} }
pub enum StencilOp { pub enum StencilOp {
_default /* value 0 reserved for default-init */ _default // value 0 reserved for default-init
keep keep
zero zero
replace replace
incr_clamp incr_clamp
decr_clamp decr_clamp
invert invert
incr_wrap incr_wrap
decr_wrap decr_wrap
_num _num
} }
pub enum BlendFactor { pub enum BlendFactor {
_default /* value 0 reserved for default-init */ _default // value 0 reserved for default-init
zero zero
one one
src_color src_color
one_minus_src_color one_minus_src_color
src_alpha src_alpha
one_minus_src_alpha one_minus_src_alpha
dst_color dst_color
one_minus_dst_color one_minus_dst_color
dst_alpha dst_alpha
one_minus_dst_alpha one_minus_dst_alpha
src_alpha_saturated src_alpha_saturated
blend_color blend_color
one_minus_blend_color one_minus_blend_color
blend_alpha blend_alpha
one_minus_blend_alpha one_minus_blend_alpha
_num _num
} }
pub enum BlendOp { pub enum BlendOp {
_default /* value 0 reserved for default-init */ _default // value 0 reserved for default-init
add add
subtract subtract
reverse_subtract reverse_subtract
_num _num
} }
pub enum ColorMask { pub enum ColorMask {
_default = 0 /* value 0 reserved for default-init */ _default = 0 // value 0 reserved for default-init
@none = 0x10 /* special value for 'all channels disabled */ @none = 0x10 // special value for 'all channels disabled
r = 1 r = 1
g = 2 g = 2
b = 4 b = 4
a = 8 a = 8
rgb = 0x7 rgb = 0x7
rgba = 0xF rgba = 0xF
} }
pub enum Action { pub enum Action {
_default _default
clear clear
load load
dontcare dontcare
_num _num
} }

View File

@ -3,7 +3,7 @@ module gfx
import sokol.c import sokol.c
pub const ( pub const (
version = 1 version = 1
used_import = c.used_import used_import = c.used_import
) )
@ -171,7 +171,7 @@ pub fn query_pixelformat(fmt PixelFormat) C.sg_pixelformat_info {
return C.sg_query_pixelformat(fmt) return C.sg_query_pixelformat(fmt)
} }
/* get current state of a resource (INITIAL, ALLOC, VALID, FAILED, INVALID) */ // get current state of a resource (INITIAL, ALLOC, VALID, FAILED, INVALID)
[inline] [inline]
pub fn query_buffer_state(buf C.sg_buffer) C.sg_resource_state { pub fn query_buffer_state(buf C.sg_buffer) C.sg_resource_state {
return C.sg_query_buffer_state(buf) return C.sg_query_buffer_state(buf)
@ -249,7 +249,7 @@ pub fn query_pass_defaults(desc &C.sg_pass) C.sg_pass_desc {
return C.sg_query_pass_defaults(unsafe { &C.sg_pass_desc(desc) }) return C.sg_query_pass_defaults(unsafe { &C.sg_pass_desc(desc) })
} }
/* rendering contexts (optional) */ // rendering contexts (optional)
[inline] [inline]
pub fn setup_context() C.sg_context { pub fn setup_context() C.sg_context {
return C.sg_setup_context() return C.sg_setup_context()

View File

@ -30,6 +30,7 @@ fn C.sg_apply_scissor_rect(x int, y int, width int, height int, origin_top_left
fn C.sg_apply_scissor_rectf(x f32, y f32, width f32, height f32, origin_top_left bool) fn C.sg_apply_scissor_rectf(x f32, y f32, width f32, height f32, origin_top_left bool)
fn C.sg_apply_pipeline(pip C.sg_pipeline) fn C.sg_apply_pipeline(pip C.sg_pipeline)
fn C.sg_apply_bindings(bindings &C.sg_bindings) fn C.sg_apply_bindings(bindings &C.sg_bindings)
// stage == sg_shader_stage // stage == sg_shader_stage
fn C.sg_apply_uniforms(stage int, ub_index int, data &C.sg_range) fn C.sg_apply_uniforms(stage int, ub_index int, data &C.sg_range)
fn C.sg_draw(base_element int, num_elements int, num_instances int) fn C.sg_draw(base_element int, num_elements int, num_instances int)
@ -43,7 +44,7 @@ fn C.sg_query_features() C.sg_features
fn C.sg_query_limits() C.sg_limits fn C.sg_query_limits() C.sg_limits
fn C.sg_query_pixelformat(fmt PixelFormat) C.sg_pixelformat_info fn C.sg_query_pixelformat(fmt PixelFormat) C.sg_pixelformat_info
/* get current state of a resource (INITIAL, ALLOC, VALID, FAILED, INVALID) */ // get current state of a resource (INITIAL, ALLOC, VALID, FAILED, INVALID)
fn C.sg_query_buffer_state(buf C.sg_buffer) C.sg_resource_state fn C.sg_query_buffer_state(buf C.sg_buffer) C.sg_resource_state
fn C.sg_query_image_state(img C.sg_image) C.sg_resource_state fn C.sg_query_image_state(img C.sg_image) C.sg_resource_state
fn C.sg_query_shader_state(shd C.sg_shader) C.sg_resource_state fn C.sg_query_shader_state(shd C.sg_shader) C.sg_resource_state
@ -64,7 +65,7 @@ fn C.sg_query_shader_defaults(desc &C.sg_shader_desc) C.sg_shader_desc
fn C.sg_query_pipeline_defaults(desc &C.sg_pipeline_desc) C.sg_pipeline_desc fn C.sg_query_pipeline_defaults(desc &C.sg_pipeline_desc) C.sg_pipeline_desc
fn C.sg_query_pass_defaults(desc &C.sg_pass_desc) C.sg_pass_desc fn C.sg_query_pass_defaults(desc &C.sg_pass_desc) C.sg_pass_desc
/* rendering contexts (optional) */ // rendering contexts (optional)
fn C.sg_setup_context() C.sg_context fn C.sg_setup_context() C.sg_context
fn C.sg_activate_context(ctx_id C.sg_context) fn C.sg_activate_context(ctx_id C.sg_context)
fn C.sg_discard_context(ctx_id C.sg_context) fn C.sg_discard_context(ctx_id C.sg_context)

View File

@ -2,8 +2,8 @@ module gfx
pub fn create_clear_pass(r f32, g f32, b f32, a f32) C.sg_pass_action { pub fn create_clear_pass(r f32, g f32, b f32, a f32) C.sg_pass_action {
mut color_action := C.sg_color_attachment_action{ mut color_action := C.sg_color_attachment_action{
action: gfx.Action(C.SG_ACTION_CLEAR) action: Action(C.SG_ACTION_CLEAR)
value: C.sg_color { value: C.sg_color{
r: r r: r
g: g g: g
b: b b: b

View File

@ -1,165 +1,165 @@
module sapp module sapp
pub enum EventType { pub enum EventType {
invalid invalid
key_down key_down
key_up key_up
char char
mouse_down mouse_down
mouse_up mouse_up
mouse_scroll mouse_scroll
mouse_move mouse_move
mouse_enter mouse_enter
mouse_leave mouse_leave
touches_began touches_began
touches_moved touches_moved
touches_ended touches_ended
touches_cancelled touches_cancelled
resized resized
iconified iconified
restored restored
suspended suspended
resumed resumed
update_cursor update_cursor
quit_requested quit_requested
clipboard_pasted clipboard_pasted
num num
} }
pub enum MouseButton { pub enum MouseButton {
invalid = -1 invalid = -1
left = 0 left = 0
right = 1 right = 1
middle = 2 middle = 2
} }
pub enum Modifier { pub enum Modifier {
shift = 1 //(1<<0) shift = 1 //(1<<0)
ctrl = 2 //(1<<1) ctrl = 2 //(1<<1)
alt = 4 //(1<<2) alt = 4 //(1<<2)
super = 8 //(1<<3) super = 8 //(1<<3)
} }
pub enum KeyCode { pub enum KeyCode {
invalid = 0 invalid = 0
space = 32 space = 32
apostrophe = 39 /* ' */ apostrophe = 39 //'
comma = 44 /* , */ comma = 44 //,
minus = 45 /* - */ minus = 45 //-
period = 46 /* . */ period = 46 //.
slash = 47 /* / */ slash = 47 ///
_0 = 48 _0 = 48
_1 = 49 _1 = 49
_2 = 50 _2 = 50
_3 = 51 _3 = 51
_4 = 52 _4 = 52
_5 = 53 _5 = 53
_6 = 54 _6 = 54
_7 = 55 _7 = 55
_8 = 56 _8 = 56
_9 = 57 _9 = 57
semicolon = 59 /* ; */ semicolon = 59 //;
equal = 61 /* = */ equal = 61 //=
a = 65 a = 65
b = 66 b = 66
c = 67 c = 67
d = 68 d = 68
e = 69 e = 69
f = 70 f = 70
g = 71 g = 71
h = 72 h = 72
i = 73 i = 73
j = 74 j = 74
k = 75 k = 75
l = 76 l = 76
m = 77 m = 77
n = 78 n = 78
o = 79 o = 79
p = 80 p = 80
q = 81 q = 81
r = 82 r = 82
s = 83 s = 83
t = 84 t = 84
u = 85 u = 85
v = 86 v = 86
w = 87 w = 87
x = 88 x = 88
y = 89 y = 89
z = 90 z = 90
left_bracket = 91 /* [ */ left_bracket = 91 //[
backslash = 92 /* \ */ backslash = 92 //\
right_bracket = 93 /* ] */ right_bracket = 93 //]
grave_accent = 96 /* ` */ grave_accent = 96 //`
world_1 = 161 /* non-us #1 */ world_1 = 161 // non-us #1
world_2 = 162 /* non-us #2 */ world_2 = 162 // non-us #2
escape = 256 escape = 256
enter = 257 enter = 257
tab = 258 tab = 258
backspace = 259 backspace = 259
insert = 260 insert = 260
delete = 261 delete = 261
right = 262 right = 262
left = 263 left = 263
down = 264 down = 264
up = 265 up = 265
page_up = 266 page_up = 266
page_down = 267 page_down = 267
home = 268 home = 268
end = 269 end = 269
caps_lock = 280 caps_lock = 280
scroll_lock = 281 scroll_lock = 281
num_lock = 282 num_lock = 282
print_screen = 283 print_screen = 283
pause = 284 pause = 284
f1 = 290 f1 = 290
f2 = 291 f2 = 291
f3 = 292 f3 = 292
f4 = 293 f4 = 293
f5 = 294 f5 = 294
f6 = 295 f6 = 295
f7 = 296 f7 = 296
f8 = 297 f8 = 297
f9 = 298 f9 = 298
f10 = 299 f10 = 299
f11 = 300 f11 = 300
f12 = 301 f12 = 301
f13 = 302 f13 = 302
f14 = 303 f14 = 303
f15 = 304 f15 = 304
f16 = 305 f16 = 305
f17 = 306 f17 = 306
f18 = 307 f18 = 307
f19 = 308 f19 = 308
f20 = 309 f20 = 309
f21 = 310 f21 = 310
f22 = 311 f22 = 311
f23 = 312 f23 = 312
f24 = 313 f24 = 313
f25 = 314 f25 = 314
kp_0 = 320 kp_0 = 320
kp_1 = 321 kp_1 = 321
kp_2 = 322 kp_2 = 322
kp_3 = 323 kp_3 = 323
kp_4 = 324 kp_4 = 324
kp_5 = 325 kp_5 = 325
kp_6 = 326 kp_6 = 326
kp_7 = 327 kp_7 = 327
kp_8 = 328 kp_8 = 328
kp_9 = 329 kp_9 = 329
kp_decimal = 330 kp_decimal = 330
kp_divide = 331 kp_divide = 331
kp_multiply = 332 kp_multiply = 332
kp_subtract = 333 kp_subtract = 333
kp_add = 334 kp_add = 334
kp_enter = 335 kp_enter = 335
kp_equal = 336 kp_equal = 336
left_shift = 340 left_shift = 340
left_control = 341 left_control = 341
left_alt = 342 left_alt = 342
left_super = 343 left_super = 343
right_shift = 344 right_shift = 344
right_control = 345 right_control = 345
right_alt = 346 right_alt = 346
right_super = 347 right_super = 347
menu = 348 menu = 348
} }

View File

@ -7,7 +7,9 @@ pub const (
) )
// Android needs a global reference to `g_desc` // Android needs a global reference to `g_desc`
__global ( g_desc C.sapp_desc ) __global (
g_desc C.sapp_desc
)
pub fn create_desc() C.sg_desc { pub fn create_desc() C.sg_desc {
metal_desc := C.sg_metal_context_desc{ metal_desc := C.sg_metal_context_desc{

View File

@ -1,73 +1,99 @@
module sapp module sapp
/* returns true after sokol-app has been initialized */ // returns true after sokol-app has been initialized
fn C.sapp_isvalid() bool fn C.sapp_isvalid() bool
/* returns the current framebuffer width in pixels */
// returns the current framebuffer width in pixels
fn C.sapp_width() int fn C.sapp_width() int
fn C.sapp_widthf() f32 fn C.sapp_widthf() f32
/* returns the current framebuffer height in pixels */
// returns the current framebuffer height in pixels
fn C.sapp_height() int fn C.sapp_height() int
fn C.sapp_heightf() f32 fn C.sapp_heightf() f32
/* returns true when high_dpi was requested and actually running in a high-dpi scenario */
fn C.sapp_high_dpi() bool
/* returns the dpi scaling factor (window pixels to framebuffer pixels) */
fn C.sapp_dpi_scale() f32
/* show or hide the mobile device onscreen keyboard */
fn C.sapp_show_keyboard(visible bool)
/* return true if the mobile device onscreen keyboard is currently shown */
fn C.sapp_keyboard_shown() bool
/* show or hide the mouse cursor */
fn C.sapp_show_mouse(visible bool)
/* show or hide the mouse cursor */
fn C.sapp_mouse_shown() bool
/* return the userdata pointer optionally provided in sapp_desc */
fn C.sapp_userdata() voidptr
/* return a copy of the sapp_desc structure */
fn C.sapp_query_desc() C.sapp_desc
/* initiate a "soft quit" (sends SAPP_EVENTTYPE_QUIT_REQUESTED) */
fn C.sapp_request_quit()
/* cancel a pending quit (when SAPP_EVENTTYPE_QUIT_REQUESTED has been received) */
fn C.sapp_cancel_quit()
/* intiate a "hard quit" (quit application without sending SAPP_EVENTTYPE_QUIT_REQUSTED) */
fn C.sapp_quit()
/* call from inside event callback to consume the current event (don't forward to platform) */
fn C.sapp_consume_event()
/* get the current frame counter (for comparison with sapp_event.frame_count) */
fn C.sapp_frame_count() u64
/* write string into clipboard */
fn C.sapp_set_clipboard_string(str byteptr)
/* read string from clipboard (usually during SAPP_EVENTTYPE_CLIPBOARD_PASTED) */
fn C.sapp_get_clipboard_string() byteptr
/* special run-function for SOKOL_NO_ENTRY (in standard mode this is an empty stub) */ // returns true when high_dpi was requested and actually running in a high-dpi scenario
fn C.sapp_high_dpi() bool
// returns the dpi scaling factor (window pixels to framebuffer pixels)
fn C.sapp_dpi_scale() f32
// show or hide the mobile device onscreen keyboard
fn C.sapp_show_keyboard(visible bool)
// return true if the mobile device onscreen keyboard is currently shown
fn C.sapp_keyboard_shown() bool
// show or hide the mouse cursor
fn C.sapp_show_mouse(visible bool)
// show or hide the mouse cursor
fn C.sapp_mouse_shown() bool
// return the userdata pointer optionally provided in sapp_desc
fn C.sapp_userdata() voidptr
// return a copy of the sapp_desc structure
fn C.sapp_query_desc() C.sapp_desc
// initiate a "soft quit" (sends SAPP_EVENTTYPE_QUIT_REQUESTED)
fn C.sapp_request_quit()
// cancel a pending quit (when SAPP_EVENTTYPE_QUIT_REQUESTED has been received)
fn C.sapp_cancel_quit()
// intiate a "hard quit" (quit application without sending SAPP_EVENTTYPE_QUIT_REQUSTED)
fn C.sapp_quit()
// call from inside event callback to consume the current event (don't forward to platform)
fn C.sapp_consume_event()
// get the current frame counter (for comparison with sapp_event.frame_count)
fn C.sapp_frame_count() u64
// write string into clipboard
fn C.sapp_set_clipboard_string(str &byte)
// read string from clipboard (usually during SAPP_EVENTTYPE_CLIPBOARD_PASTED)
fn C.sapp_get_clipboard_string() &byte
// special run-function for SOKOL_NO_ENTRY (in standard mode this is an empty stub)
fn C.sapp_run(desc &C.sapp_desc) int fn C.sapp_run(desc &C.sapp_desc) int
/* GL: return true when GLES2 fallback is active (to detect fallback from GLES3) */ // GL: return true when GLES2 fallback is active (to detect fallback from GLES3)
fn C.sapp_gles2() bool fn C.sapp_gles2() bool
/* HTML5: enable or disable the hardwired "Leave Site?" dialog box */ // HTML5: enable or disable the hardwired "Leave Site?" dialog box
fn C.sapp_html5_ask_leave_site(ask bool) fn C.sapp_html5_ask_leave_site(ask bool)
/* Metal: get ARC-bridged pointer to Metal device object */ // Metal: get ARC-bridged pointer to Metal device object
fn C.sapp_metal_get_device() voidptr fn C.sapp_metal_get_device() voidptr
/* Metal: get ARC-bridged pointer to this frame's renderpass descriptor */
// Metal: get ARC-bridged pointer to this frame's renderpass descriptor
fn C.sapp_metal_get_renderpass_descriptor() voidptr fn C.sapp_metal_get_renderpass_descriptor() voidptr
/* Metal: get ARC-bridged pointer to current drawable */
// Metal: get ARC-bridged pointer to current drawable
fn C.sapp_metal_get_drawable() voidptr fn C.sapp_metal_get_drawable() voidptr
/* macOS: get ARC-bridged pointer to macOS NSWindow */
// macOS: get ARC-bridged pointer to macOS NSWindow
fn C.sapp_macos_get_window() voidptr fn C.sapp_macos_get_window() voidptr
/* iOS: get ARC-bridged pointer to iOS UIWindow */
// iOS: get ARC-bridged pointer to iOS UIWindow
fn C.sapp_ios_get_window() voidptr fn C.sapp_ios_get_window() voidptr
/* D3D11: get pointer to ID3D11Device object */ // D3D11: get pointer to ID3D11Device object
fn C.sapp_d3d11_get_device() voidptr fn C.sapp_d3d11_get_device() voidptr
/* D3D11: get pointer to ID3D11DeviceContext object */
// D3D11: get pointer to ID3D11DeviceContext object
fn C.sapp_d3d11_get_device_context() voidptr fn C.sapp_d3d11_get_device_context() voidptr
/* D3D11: get pointer to ID3D11RenderTargetView object */
// D3D11: get pointer to ID3D11RenderTargetView object
fn C.sapp_d3d11_get_render_target_view() voidptr fn C.sapp_d3d11_get_render_target_view() voidptr
/* D3D11: get pointer to ID3D11DepthStencilView */
// D3D11: get pointer to ID3D11DepthStencilView
fn C.sapp_d3d11_get_depth_stencil_view() voidptr fn C.sapp_d3d11_get_depth_stencil_view() voidptr
/* Win32: get the HWND window handle */
// Win32: get the HWND window handle
fn C.sapp_win32_get_hwnd() voidptr fn C.sapp_win32_get_hwnd() voidptr
/* Android: get native activity handle */
// Android: get native activity handle
fn C.sapp_android_get_native_activity() voidptr fn C.sapp_android_get_native_activity() voidptr

View File

@ -2,46 +2,46 @@ module sapp
pub struct C.sapp_desc { pub struct C.sapp_desc {
pub: pub:
init_cb fn () // these are the user-provided callbacks without user data init_cb fn () // these are the user-provided callbacks without user data
frame_cb fn () frame_cb fn ()
cleanup_cb fn () cleanup_cb fn ()
event_cb fn (&C.sapp_event) //&sapp_event) event_cb fn (&C.sapp_event) //&sapp_event)
fail_cb fn (&byte) fail_cb fn (&byte)
user_data voidptr // these are the user-provided callbacks with user data user_data voidptr // these are the user-provided callbacks with user data
init_userdata_cb fn (voidptr) init_userdata_cb fn (voidptr)
frame_userdata_cb fn (voidptr) frame_userdata_cb fn (voidptr)
cleanup_userdata_cb fn (voidptr) cleanup_userdata_cb fn (voidptr)
event_userdata_cb fn (&C.sapp_event, voidptr) event_userdata_cb fn (&C.sapp_event, voidptr)
fail_userdata_cb fn (&char, voidptr) fail_userdata_cb fn (&char, voidptr)
width int // the preferred width of the window / canvas width int // the preferred width of the window / canvas
height int // the preferred height of the window / canvas height int // the preferred height of the window / canvas
sample_count int // MSAA sample count sample_count int // MSAA sample count
swap_interval int // the preferred swap interval (ignored on some platforms) swap_interval int // the preferred swap interval (ignored on some platforms)
high_dpi bool // whether the rendering canvas is full-resolution on HighDPI displays high_dpi bool // whether the rendering canvas is full-resolution on HighDPI displays
fullscreen bool // whether the window should be created in fullscreen mode fullscreen bool // whether the window should be created in fullscreen mode
alpha bool // whether the framebuffer should have an alpha channel (ignored on some platforms) alpha bool // whether the framebuffer should have an alpha channel (ignored on some platforms)
window_title &char // the window title as UTF-8 encoded string window_title &char // the window title as UTF-8 encoded string
user_cursor bool // if true, user is expected to manage cursor image in SAPP_EVENTTYPE_UPDATE_CURSOR user_cursor bool // if true, user is expected to manage cursor image in SAPP_EVENTTYPE_UPDATE_CURSOR
enable_clipboard bool // enable clipboard access, default is false enable_clipboard bool // enable clipboard access, default is false
clipboard_size int // max size of clipboard content in bytes clipboard_size int // max size of clipboard content in bytes
enable_dragndrop bool // enable file dropping (drag'n'drop), default is false enable_dragndrop bool // enable file dropping (drag'n'drop), default is false
max_dropped_files int // max number of dropped files to process (default: 1) max_dropped_files int // max number of dropped files to process (default: 1)
max_dropped_file_path_length int // max length in bytes of a dropped UTF-8 file path (default: 2048) max_dropped_file_path_length int // max length in bytes of a dropped UTF-8 file path (default: 2048)
/* backend-specific options */ // backend-specific options
gl_force_gles2 bool // if true, setup GLES2/WebGL even if GLES3/WebGL2 is available gl_force_gles2 bool // if true, setup GLES2/WebGL even if GLES3/WebGL2 is available
win32_console_utf8 bool // if true, set the output console codepage to UTF-8 win32_console_utf8 bool // if true, set the output console codepage to UTF-8
win32_console_create bool // if true, attach stdout/stderr to a new console window win32_console_create bool // if true, attach stdout/stderr to a new console window
win32_console_attach bool // if true, attach stdout/stderr to parent process win32_console_attach bool // if true, attach stdout/stderr to parent process
html5_canvas_name &char // the name (id) of the HTML5 canvas element, default is "canvas" html5_canvas_name &char // the name (id) of the HTML5 canvas element, default is "canvas"
html5_canvas_resize bool // if true, the HTML5 canvas size is set to sapp_desc.width/height, otherwise canvas size is tracked html5_canvas_resize bool // if true, the HTML5 canvas size is set to sapp_desc.width/height, otherwise canvas size is tracked
html5_preserve_drawing_buffer bool // HTML5 only: whether to preserve default framebuffer content between frames html5_preserve_drawing_buffer bool // HTML5 only: whether to preserve default framebuffer content between frames
html5_premultiplied_alpha bool // HTML5 only: whether the rendered pixels use premultiplied alpha convention html5_premultiplied_alpha bool // HTML5 only: whether the rendered pixels use premultiplied alpha convention
html5_ask_leave_site bool // initial state of the internal html5_ask_leave_site flag (see sapp_html5_ask_leave_site()) html5_ask_leave_site bool // initial state of the internal html5_ask_leave_site flag (see sapp_html5_ask_leave_site())
ios_keyboard_resizes_canvas bool // if true, showing the iOS keyboard shrinks the canvas ios_keyboard_resizes_canvas bool // if true, showing the iOS keyboard shrinks the canvas
/* V patches */ // V patches
__v_native_render bool // V patch to allow for native rendering __v_native_render bool // V patch to allow for native rendering
} }
pub struct Event { pub struct Event {

View File

@ -26,4 +26,3 @@ pub fn rgba(r byte, g byte, b byte, a byte) u32 {
pub fn flush(ctx &C.FONScontext) { pub fn flush(ctx &C.FONScontext) {
C.sfons_flush(ctx) C.sfons_flush(ctx)
} }

View File

@ -6,7 +6,7 @@ pub const (
version = gfx.version + 1 version = gfx.version + 1
) )
/* setup/shutdown/misc */ // setup/shutdown/misc
[inline] [inline]
pub fn setup(desc &C.sgl_desc_t) { pub fn setup(desc &C.sgl_desc_t) {
C.sgl_setup(desc) C.sgl_setup(desc)
@ -37,7 +37,7 @@ pub fn deg(rad f32) f32 {
return C.sgl_deg(rad) return C.sgl_deg(rad)
} }
/* create and destroy pipeline objects */ // create and destroy pipeline objects
[inline] [inline]
pub fn make_pipeline(desc &C.sg_pipeline_desc) C.sgl_pipeline { pub fn make_pipeline(desc &C.sg_pipeline_desc) C.sgl_pipeline {
return C.sgl_make_pipeline(desc) return C.sgl_make_pipeline(desc)
@ -48,7 +48,7 @@ pub fn destroy_pipeline(pip C.sgl_pipeline) {
C.sgl_destroy_pipeline(pip) C.sgl_destroy_pipeline(pip)
} }
/* render state functions */ // render state functions
[inline] [inline]
pub fn viewport(x int, y int, w int, h int, origin_top_left bool) { pub fn viewport(x int, y int, w int, h int, origin_top_left bool) {
C.sgl_viewport(x, y, w, h, origin_top_left) C.sgl_viewport(x, y, w, h, origin_top_left)
@ -74,7 +74,7 @@ pub fn texture(img C.sg_image) {
C.sgl_texture(img) C.sgl_texture(img)
} }
/* pipeline stack functions */ // pipeline stack functions
[inline] [inline]
pub fn default_pipeline() { pub fn default_pipeline() {
C.sgl_default_pipeline() C.sgl_default_pipeline()
@ -95,7 +95,7 @@ pub fn pop_pipeline() {
C.sgl_pop_pipeline() C.sgl_pop_pipeline()
} }
/* matrix stack functions */ // matrix stack functions
[inline] [inline]
pub fn matrix_mode_modelview() { pub fn matrix_mode_modelview() {
C.sgl_matrix_mode_modelview() C.sgl_matrix_mode_modelview()
@ -181,7 +181,7 @@ pub fn pop_matrix() {
C.sgl_pop_matrix() C.sgl_pop_matrix()
} }
/* these functions only set the internal 'current texcoord / color' (valid inside or outside begin/end) */ // these functions only set the internal 'current texcoord / color' (valid inside or outside begin/end)
[inline] [inline]
pub fn t2f(u f32, v f32) { pub fn t2f(u f32, v f32) {
C.sgl_t2f(u, v) C.sgl_t2f(u, v)
@ -212,7 +212,7 @@ pub fn c1i(rgba u32) {
C.sgl_c1i(rgba) C.sgl_c1i(rgba)
} }
/* define primitives, each begin/end is one draw command */ // define primitives, each begin/end is one draw command
[inline] [inline]
pub fn begin_points() { pub fn begin_points() {
C.sgl_begin_points() C.sgl_begin_points()
@ -368,9 +368,8 @@ pub fn end() {
C.sgl_end() C.sgl_end()
} }
/* render everything */ // render everything
[inline] [inline]
pub fn draw() { pub fn draw() {
C.sgl_draw() C.sgl_draw()
} }

View File

@ -1,6 +1,6 @@
module sgl module sgl
/* setup/shutdown/misc */ // setup/shutdown/misc
fn C.sgl_setup(desc &C.sgl_desc_t) fn C.sgl_setup(desc &C.sgl_desc_t)
fn C.sgl_shutdown() fn C.sgl_shutdown()
fn C.sgl_error() C.sgl_error_t fn C.sgl_error() C.sgl_error_t
@ -8,11 +8,11 @@ fn C.sgl_defaults()
fn C.sgl_rad(deg f32) f32 fn C.sgl_rad(deg f32) f32
fn C.sgl_deg(rad f32) f32 fn C.sgl_deg(rad f32) f32
/* create and destroy pipeline objects */ // create and destroy pipeline objects
fn C.sgl_make_pipeline(desc &C.sg_pipeline_desc) C.sgl_pipeline fn C.sgl_make_pipeline(desc &C.sg_pipeline_desc) C.sgl_pipeline
fn C.sgl_destroy_pipeline(pip C.sgl_pipeline) fn C.sgl_destroy_pipeline(pip C.sgl_pipeline)
/* render state functions */ // render state functions
fn C.sgl_viewport(x int, y int, w int, h int, origin_top_left bool) fn C.sgl_viewport(x int, y int, w int, h int, origin_top_left bool)
fn C.sgl_viewportf(x f32, y f32, w f32, h f32, origin_top_left bool) fn C.sgl_viewportf(x f32, y f32, w f32, h f32, origin_top_left bool)
fn C.sgl_scissor_rect(x int, y int, w int, h int, origin_top_left bool) fn C.sgl_scissor_rect(x int, y int, w int, h int, origin_top_left bool)
@ -21,13 +21,13 @@ fn C.sgl_enable_texture()
fn C.sgl_disable_texture() fn C.sgl_disable_texture()
fn C.sgl_texture(img C.sg_image) fn C.sgl_texture(img C.sg_image)
/* pipeline stack functions */ // pipeline stack functions
fn C.sgl_default_pipeline() fn C.sgl_default_pipeline()
fn C.sgl_load_pipeline(pip C.sgl_pipeline) fn C.sgl_load_pipeline(pip C.sgl_pipeline)
fn C.sgl_push_pipeline() fn C.sgl_push_pipeline()
fn C.sgl_pop_pipeline() fn C.sgl_pop_pipeline()
/* matrix stack functions */ // matrix stack functions
fn C.sgl_matrix_mode_modelview() fn C.sgl_matrix_mode_modelview()
fn C.sgl_matrix_mode_projection() fn C.sgl_matrix_mode_projection()
fn C.sgl_matrix_mode_texture() fn C.sgl_matrix_mode_texture()
@ -46,7 +46,7 @@ fn C.sgl_lookat(eye_x f32, eye_y f32, eye_z f32, center_x f32, center_y f32, cen
fn C.sgl_push_matrix() fn C.sgl_push_matrix()
fn C.sgl_pop_matrix() fn C.sgl_pop_matrix()
/* these functions only set the internal 'current texcoord / color' (valid inside or outside begin/end) */ // these functions only set the internal 'current texcoord / color' (valid inside or outside begin/end)
fn C.sgl_t2f(u f32, v f32) fn C.sgl_t2f(u f32, v f32)
fn C.sgl_c3f(r f32, g f32, b f32) fn C.sgl_c3f(r f32, g f32, b f32)
fn C.sgl_c4f(r f32, g f32, b f32, a f32) fn C.sgl_c4f(r f32, g f32, b f32, a f32)
@ -54,7 +54,7 @@ fn C.sgl_c3b(r byte, g byte, b byte)
fn C.sgl_c4b(r byte, g byte, b byte, a byte) fn C.sgl_c4b(r byte, g byte, b byte, a byte)
fn C.sgl_c1i(rgba u32) fn C.sgl_c1i(rgba u32)
/* define primitives, each begin/end is one draw command */ // define primitives, each begin/end is one draw command
fn C.sgl_begin_points() fn C.sgl_begin_points()
fn C.sgl_begin_lines() fn C.sgl_begin_lines()
fn C.sgl_begin_line_strip() fn C.sgl_begin_line_strip()
@ -87,5 +87,5 @@ fn C.sgl_v3f_t2f_c4b(x f32, y f32, z f32, u f32, v f32, r byte, g byte, b byte,
fn C.sgl_v3f_t2f_c1i(x f32, y f32, z f32, u f32, v f32, rgba u32) fn C.sgl_v3f_t2f_c1i(x f32, y f32, z f32, u f32, v f32, rgba u32)
fn C.sgl_end() fn C.sgl_end()
/* render everything */ // render everything
fn C.sgl_draw() fn C.sgl_draw()

View File

@ -2,7 +2,7 @@ module sgl
// should be in a proper module // should be in a proper module
pub enum SglError { pub enum SglError {
no_error no_error
vertices_full vertices_full
commands_full commands_full
stack_overflow stack_overflow
@ -14,11 +14,11 @@ pub struct C.sgl_pipeline {
} }
pub struct C.sgl_desc_t { pub struct C.sgl_desc_t {
max_vertices int /* size for vertex buffer */ max_vertices int // size for vertex buffer
max_commands int /* size of uniform- and command-buffers */ max_commands int // size of uniform- and command-buffers
pipeline_pool_size int /* size of the internal pipeline pool, default is 64 */ pipeline_pool_size int // size of the internal pipeline pool, default is 64
color_format C.sg_pixel_format color_format C.sg_pixel_format
depth_format C.sg_pixel_format depth_format C.sg_pixel_format
sample_count int sample_count int
face_winding C.sg_face_winding /* default front face winding is CCW */ face_winding C.sg_face_winding // default front face winding is CCW
} }

View File

@ -4,7 +4,7 @@ import sokol.c
import sokol.f import sokol.f
pub const ( pub const (
used_import = c.used_import + f.used_import used_import = c.used_import + f.used_import
) )
/* /*
@ -17,4 +17,3 @@ pub enum Key {
space = C.SAPP_KEYCODE_SPACE space = C.SAPP_KEYCODE_SPACE
} }
*/ */

View File

@ -4,9 +4,7 @@ fn test_sqlite() {
$if !linux { $if !linux {
return return
} }
mut db := sqlite.connect(':memory:') or { mut db := sqlite.connect(':memory:') or { panic(err) }
panic(err)
}
assert db.is_open assert db.is_open
db.exec('drop table if exists users') db.exec('drop table if exists users')
db.exec("create table users (id integer primary key, name text default '');") db.exec("create table users (id integer primary key, name text default '');")
@ -22,12 +20,8 @@ fn test_sqlite() {
assert code == 101 assert code == 101
code = db.exec_none('vacuum') code = db.exec_none('vacuum')
assert code == 101 assert code == 101
user := db.exec_one('select * from users where id = 3') or { user := db.exec_one('select * from users where id = 3') or { panic(err) }
panic(err)
}
assert user.vals.len == 2 assert user.vals.len == 2
db.close() or { db.close() or { panic(err) }
panic(err)
}
assert !db.is_open assert !db.is_open
} }

View File

@ -18,13 +18,13 @@ pub mut:
ext string ext string
} }
fn C.stbi_load(filename charptr, x &int, y &int, channels_in_file &int, desired_channels int) byteptr fn C.stbi_load(filename &char, x &int, y &int, channels_in_file &int, desired_channels int) &byte
fn C.stbi_load_from_file(f voidptr, x &int, y &int, channels_in_file &int, desired_channels int) byteptr fn C.stbi_load_from_file(f voidptr, x &int, y &int, channels_in_file &int, desired_channels int) &byte
fn C.stbi_load_from_memory(buffer byteptr, len int, x &int, y &int, channels_in_file &int, desired_channels int) byteptr fn C.stbi_load_from_memory(buffer &byte, len int, x &int, y &int, channels_in_file &int, desired_channels int) &byte
fn C.stbi_image_free(retval_from_stbi_load byteptr) fn C.stbi_image_free(retval_from_stbi_load &byte)
fn C.stbi_set_flip_vertically_on_load(should_flip int) fn C.stbi_set_flip_vertically_on_load(should_flip int)
@ -41,7 +41,8 @@ pub fn load(path string) ?Image {
} }
// flag := if ext == 'png' { C.STBI_rgb_alpha } else { 0 } // flag := if ext == 'png' { C.STBI_rgb_alpha } else { 0 }
desired_channels := if ext == 'png' { 4 } else { 0 } desired_channels := if ext == 'png' { 4 } else { 0 }
res.data = C.stbi_load(&char(path.str), &res.width, &res.height, &res.nr_channels, desired_channels) res.data = C.stbi_load(&char(path.str), &res.width, &res.height, &res.nr_channels,
desired_channels)
if desired_channels == 4 && res.nr_channels == 3 { if desired_channels == 4 && res.nr_channels == 3 {
// Fix an alpha png bug // Fix an alpha png bug
res.nr_channels = 4 res.nr_channels = 4
@ -52,7 +53,7 @@ pub fn load(path string) ?Image {
return res return res
} }
pub fn load_from_memory(buf byteptr, bufsize int) ?Image { pub fn load_from_memory(buf &byte, bufsize int) ?Image {
mut res := Image{ mut res := Image{
ok: true ok: true
data: 0 data: 0

View File

@ -1,4 +1,4 @@
import atomic2 import sync.atomic2
import sync import sync
const ( const (

View File

@ -7,7 +7,6 @@
// main thread where the total sum is compare to the expected value. // main thread where the total sum is compare to the expected value.
import time import time
import os import os
import sync
fn do_rec(ch chan int, resch chan i64, n int) { fn do_rec(ch chan int, resch chan i64, n int) {
mut sum := i64(0) mut sum := i64(0)

View File

@ -27,8 +27,8 @@ mut:
n_readers int n_readers int
n_writers int n_writers int
// //
pops_wg &sync.WaitGroup pops_wg &sync.WaitGroup
pops []Event pops []Event
// //
pushes_wg &sync.WaitGroup pushes_wg &sync.WaitGroup
pushes []Event pushes []Event

View File

@ -15,5 +15,5 @@ fn test_channel_buffered() {
for _ in 0 .. num_iterations { for _ in 0 .. num_iterations {
sum += <-ch sum += <-ch
} }
assert sum == u64(num_iterations)*(num_iterations-1)/2 assert sum == u64(num_iterations) * (num_iterations - 1) / 2
} }

View File

@ -15,5 +15,5 @@ fn test_channel_unbuffered() {
for _ in 0 .. num_iterations { for _ in 0 .. num_iterations {
sum += <-ch sum += <-ch
} }
assert sum == u64(num_iterations)*(num_iterations-1)/2 assert sum == u64(num_iterations) * (num_iterations - 1) / 2
} }

View File

@ -14,9 +14,7 @@ mut:
// this function gets an array of channels for `St` references // this function gets an array of channels for `St` references
fn do_rec_calc_send(chs []chan mut St) { fn do_rec_calc_send(chs []chan mut St) {
for { for {
mut s := <-chs[0] or { mut s := <-chs[0] or { break }
break
}
s.n++ s.n++
chs[1] <- s chs[1] <- s
} }

View File

@ -3,9 +3,7 @@ import time
fn do_rec(ch chan int, resch chan i64) { fn do_rec(ch chan int, resch chan i64) {
mut sum := i64(0) mut sum := i64(0)
for { for {
a := <-ch or { a := <-ch or { break }
break
}
sum += a sum += a
} }
assert ch.closed == true assert ch.closed == true
@ -32,7 +30,7 @@ fn test_channel_close_buffered_multi() {
go do_send(ch) go do_send(ch)
mut sum := i64(0) mut sum := i64(0)
for _ in 0 .. 4 { for _ in 0 .. 4 {
sum += <- resch sum += <-resch
} }
assert sum == i64(8000) * (8000 - 1) / 2 assert sum == i64(8000) * (8000 - 1) / 2
} }
@ -77,9 +75,8 @@ fn test_channel_send_close_buffered() {
t := go fn (ch chan int) { t := go fn (ch chan int) {
ch <- 31 ch <- 31
mut x := 45 mut x := 45
ch <- 17 or { ch <- 17 or { x = -133 }
x = -133
}
assert x == -133 assert x == -133
}(ch) }(ch)
time.sleep(100 * time.millisecond) time.sleep(100 * time.millisecond)
@ -95,9 +92,8 @@ fn test_channel_send_close_unbuffered() {
ch := chan int{} ch := chan int{}
t := go fn (ch chan int) { t := go fn (ch chan int) {
mut x := 31 mut x := 31
ch <- 177 or { ch <- 177 or { x = -71 }
x = -71
}
assert x == -71 assert x == -71
}(ch) }(ch)
time.sleep(100 * time.millisecond) time.sleep(100 * time.millisecond)

View File

@ -1,7 +1,7 @@
import sync import sync
const ( const (
queue_len = 1000 queue_len = 1000
queue_fill = 763 queue_fill = 763
) )

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