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,8 +112,9 @@ 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 will_compile {
$if solaris { $if solaris {
skip_files << 'examples/gg/gg2.v' skip_files << 'examples/gg/gg2.v'
skip_files << 'examples/pico/pico.v' skip_files << 'examples/pico/pico.v'
@ -146,6 +151,12 @@ pub fn new_test_session(_vargs string) TestSession {
// the ttf_test.v is not interactive, but needs X11 headers to be installed, which is done only on ubuntu-tcc for now // 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' 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'
}
}
vargs := _vargs.replace('-progress', '').replace('-progress', '') vargs := _vargs.replace('-progress', '').replace('-progress', '')
vexe := pref.vexe_path() vexe := pref.vexe_path()
vroot := os.dir(vexe) vroot := os.dir(vexe)
@ -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()
if !testing.hide_skips {
ts.append_message(.skip, tls_bench.step_message_skip(relative_file)) 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,9 +317,11 @@ 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()
if !testing.hide_oks {
ts.append_message(.ok, tls_bench.step_message_ok(relative_file)) ts.append_message(.ok, tls_bench.step_message_ok(relative_file))
} }
} }
}
if os.exists(generated_binary_fpath) { if os.exists(generated_binary_fpath) {
if ts.rm_binaries { if ts.rm_binaries {
os.rm(generated_binary_fpath) or { panic(err) } os.rm(generated_binary_fpath) or { panic(err) }
@ -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,8 +429,10 @@ pub fn building_any_v_binaries_failed() bool {
continue continue
} }
bmark.ok() bmark.ok()
if !testing.hide_oks {
eprintln(bmark.step_message_ok('command: $cmd')) eprintln(bmark.step_message_ok('command: $cmd'))
} }
}
bmark.stop() bmark.stop()
eprintln(term.h_divider('-')) eprintln(term.h_divider('-'))
eprintln(bmark.total_message('building v binaries')) eprintln(bmark.total_message('building v binaries'))

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

@ -12,7 +12,7 @@ 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

@ -11,7 +11,6 @@ const (
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

@ -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

@ -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)
} }
} }
@ -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

@ -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

@ -9,36 +9,36 @@ const (
[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 {
match i {
0...3 { 0...3 {
wymum(wyr3(p, i) ^ seed ^ wyp0, seed ^ wyp1) wymum(wyr3(p, i) ^ seed ^ hash.wyp0, seed ^ hash.wyp1)
} }
4...8 { 4...8 {
wymum(wyr4(p) ^ seed ^ wyp0, wyr4(p + i - 4) ^ seed ^ wyp1) wymum(wyr4(p) ^ seed ^ hash.wyp0, wyr4(p + i - 4) ^ seed ^ hash.wyp1)
} }
9...16 { 9...16 {
wymum(wyr8(p) ^ seed ^ wyp0, wyr8(p + i - 8) ^ seed ^ wyp1) wymum(wyr8(p) ^ seed ^ hash.wyp0, wyr8(p + i - 8) ^ seed ^ hash.wyp1)
} }
17...24 { 17...24 {
wymum(wyr8(p) ^ seed ^ wyp0, wyr8(p + 8) ^ seed ^ wyp1) ^ wymum(wyr8(p + i - 8) ^ seed ^ wyp2, seed ^ wyp3) 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 { 25...32 {
wymum(wyr8(p) ^ seed ^ wyp0, wyr8(p + 8) ^ seed ^ wyp1) ^ wymum(wyr8(p + 16) ^ seed ^ wyp2, wyr8(p + i - 8) ^ seed ^ wyp3) 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 { 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) 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)
}
}
} }
}}
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

@ -11,18 +11,19 @@ const (
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

@ -18,6 +18,7 @@ pub const (
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.
@ -27,6 +28,7 @@ pub const (
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

View File

@ -36,7 +36,7 @@ pub fn log_factorial(n f64) 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)]
} }
@ -61,7 +61,7 @@ fn log_factorial_asymptotic_expansion(n int) f64 {
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]) {

View File

@ -8,7 +8,8 @@ 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)),
@ -20,7 +21,7 @@ const (
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 = [
@ -194,7 +195,7 @@ const (
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 = [

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,13 +10,13 @@ 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
@ -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

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() {
/* /*

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

@ -3,10 +3,10 @@ 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() {

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,8 +20,8 @@ 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
@ -35,8 +36,8 @@ 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
@ -46,7 +47,7 @@ pub fn regex_opt(pattern string) ?RE {
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,10 +15,10 @@ 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
@ -28,7 +27,7 @@ pub fn regex_base(pattern string) (RE,int,int){
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
@ -71,11 +70,11 @@ pub fn (re RE) get_group_by_id(in_txt string, group_id int) string {
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,28 +182,27 @@ 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
@ -219,20 +217,19 @@ pub fn (mut re RE) find_from(in_txt string, start int) (int,int) {
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
@ -350,33 +345,33 @@ pub fn (mut re RE) replace_by_fn(in_txt string, repl_fn FnReplace) string {
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,21 +379,20 @@ 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++
} }
@ -413,34 +407,34 @@ pub fn (mut re RE) replace(in_txt string, repl_str string) string {
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..])

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

@ -12,14 +12,12 @@ pub enum Backend {
} }
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 r16
r16sn r16sn
r16ui r16ui
@ -29,7 +27,6 @@ pub enum PixelFormat {
rg8sn rg8sn
rg8ui rg8ui
rg8si rg8si
r32ui r32ui
r32si r32si
r32f r32f
@ -45,7 +42,6 @@ pub enum PixelFormat {
bgra8 bgra8
rgb10a2 rgb10a2
rg11b10f rg11b10f
rg32ui rg32ui
rg32si rg32si
rg32f rg32f
@ -54,14 +50,11 @@ pub enum PixelFormat {
rgba16ui rgba16ui
rgba16si rgba16si
rgba16f rgba16f
rgba32ui rgba32ui
rgba32si rgba32si
rgba32f rgba32f
depth depth
depth_stencil depth_stencil
bc1_rgba bc1_rgba
bc2_rgba bc2_rgba
bc3_rgba bc3_rgba
@ -81,7 +74,6 @@ pub enum PixelFormat {
etc2_rgba8 etc2_rgba8
etc2_rg11 etc2_rg11
etc2_rg11sn etc2_rg11sn
_num _num
} }
@ -94,7 +86,7 @@ pub enum ResourceState {
} }
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
@ -102,14 +94,14 @@ pub enum Usage {
} }
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
@ -117,7 +109,7 @@ pub enum IndexType {
} }
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
@ -142,7 +134,7 @@ 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
@ -152,7 +144,7 @@ pub enum PrimitiveType {
} }
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
@ -163,7 +155,7 @@ pub enum Filter {
} }
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
@ -172,7 +164,7 @@ pub enum Wrap {
} }
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
@ -200,7 +192,7 @@ pub enum VertexFormat {
} }
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
@ -217,7 +209,7 @@ pub enum UniformType {
} }
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
@ -225,14 +217,14 @@ pub enum CullMode {
} }
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
@ -245,7 +237,7 @@ pub enum CompareFunc {
} }
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
@ -258,7 +250,7 @@ pub enum StencilOp {
} }
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
@ -278,7 +270,7 @@ pub enum BlendFactor {
} }
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
@ -286,8 +278,8 @@ pub enum BlendOp {
} }
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

View File

@ -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

@ -43,11 +43,11 @@ pub enum Modifier {
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
@ -58,8 +58,8 @@ pub enum KeyCode {
_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
@ -86,12 +86,12 @@ pub enum KeyCode {
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

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

@ -29,7 +29,7 @@ pub:
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
@ -40,7 +40,7 @@ pub:
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
} }

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

@ -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

@ -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

@ -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,4 +1,3 @@
// Channel Benchmark // Channel Benchmark
// //
// `nobj` integers are sent thru a channel with queue length`buflen` // `nobj` integers are sent thru a channel with queue length`buflen`

View File

@ -1,4 +1,5 @@
const n = 1000 const n = 1000
const c = 100 const c = 100
fn f(ch chan int) { fn f(ch chan int) {
@ -13,9 +14,8 @@ fn test_push_or_unbuffered() {
go f(ch) go f(ch)
mut j := 0 mut j := 0
for { for {
ch <- j or { ch <- j or { break }
break
}
j++ j++
} }
assert j == n assert j == n
@ -26,9 +26,8 @@ fn test_push_or_buffered() {
go f(ch) go f(ch)
mut j := 0 mut j := 0
for { for {
ch <- j or { ch <- j or { break }
break
}
j++ j++
} }
// we don't know how many elements are in the buffer when the channel // we don't know how many elements are in the buffer when the channel
@ -40,9 +39,8 @@ fn test_push_or_buffered() {
fn g(ch chan int, res chan int) { fn g(ch chan int, res chan int) {
mut j := 0 mut j := 0
for { for {
ch <- j or { ch <- j or { break }
break
}
j++ j++
} }
println('done $j') println('done $j')

View File

@ -19,9 +19,7 @@ fn test_push_propargate() {
go f(ch) go f(ch)
mut s := 1.0 mut s := 1.0
for { for {
s = do_send(ch, s) or { s = do_send(ch, s) or { break }
break
}
} }
assert s == f64(n + 1) assert s == f64(n + 1)
} }

View File

@ -34,10 +34,10 @@ fn test_select() {
expected_sum := i64(30000) * (30000 - 1) / 2 expected_sum := i64(30000) * (30000 - 1) / 2
assert sum == expected_sum assert sum == expected_sum
mut sumrec := <- chsum mut sumrec := <-chsum
// Empty receive buffer // Empty receive buffer
for _ in 0 .. recch.cap { for _ in 0 .. recch.cap {
sumrec += <- recch sumrec += <-recch
} }
assert sumrec == i64(30000 + recch.cap) * (30000 + recch.cap - 1) / 2 assert sumrec == i64(30000 + recch.cap) * (30000 + recch.cap - 1) / 2
} }

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