fmt: remove space in front of ? and ! (#14366)

Daniel Däschle 2022-05-13 05:56:21 +02:00 committed by Jef Roosens
parent 0866c73f4b
commit 54bbc00493
Signed by: Jef Roosens
GPG Key ID: B75D4F293C7052DB
324 changed files with 1865 additions and 1879 deletions

View File

@ -43,7 +43,7 @@ fn main() {
vexe := pref.vexe_path() vexe := pref.vexe_path()
vroot := os.dir(vexe) vroot := os.dir(vexe)
util.set_vroot_folder(vroot) util.set_vroot_folder(vroot)
os.chdir(vroot) ? os.chdir(vroot)?
cmd := diff.find_working_diff_command() or { '' } cmd := diff.find_working_diff_command() or { '' }
mut app := App{ mut app := App{
diff_cmd: cmd diff_cmd: cmd

View File

@ -15,7 +15,7 @@ const vdir = @VEXEROOT
fn main() { fn main() {
dump(fast_dir) dump(fast_dir)
dump(vdir) dump(vdir)
os.chdir(fast_dir) ? os.chdir(fast_dir)?
if !os.exists('$vdir/v') && !os.is_dir('$vdir/vlib') { if !os.exists('$vdir/v') && !os.is_dir('$vdir/vlib') {
println('fast.html generator needs to be located in `v/cmd/tools/fast`') println('fast.html generator needs to be located in `v/cmd/tools/fast`')
} }
@ -32,11 +32,11 @@ fn main() {
// fetch the last commit's hash // fetch the last commit's hash
commit := exec('git rev-parse HEAD')[..8] commit := exec('git rev-parse HEAD')[..8]
if !os.exists('table.html') { if !os.exists('table.html') {
os.create('table.html') ? os.create('table.html')?
} }
mut table := os.read_file('table.html') ? mut table := os.read_file('table.html')?
if os.exists('website/index.html') { if os.exists('website/index.html') {
uploaded_index := os.read_file('website/index.html') ? uploaded_index := os.read_file('website/index.html')?
if uploaded_index.contains('>$commit<') { if uploaded_index.contains('>$commit<') {
println('nothing to benchmark') println('nothing to benchmark')
exit(1) exit(1)
@ -48,7 +48,7 @@ fn main() {
// build an optimized V // build an optimized V
println(' Building vprod...') println(' Building vprod...')
os.chdir(vdir) ? os.chdir(vdir)?
if os.args.contains('-noprod') { if os.args.contains('-noprod') {
exec('./v -o vprod cmd/v') // for faster debugging exec('./v -o vprod cmd/v') // for faster debugging
} else { } else {
@ -82,8 +82,8 @@ fn main() {
commit_date := exec('git log -n1 --pretty="format:%at" $commit') commit_date := exec('git log -n1 --pretty="format:%at" $commit')
date := time.unix(commit_date.int()) date := time.unix(commit_date.int())
os.chdir(fast_dir) ? os.chdir(fast_dir)?
mut out := os.create('table.html') ? mut out := os.create('table.html')?
// place the new row on top // place the new row on top
html_message := message.replace_each(['<', '&lt;', '>', '&gt;']) html_message := message.replace_each(['<', '&lt;', '>', '&gt;'])
@ -105,25 +105,25 @@ fn main() {
<td>${int(f64(vlines) / f64(diff1) * 1000.0)}</td> <td>${int(f64(vlines) / f64(diff1) * 1000.0)}</td>
</tr>\n' + </tr>\n' +
table.trim_space() table.trim_space()
out.writeln(table) ? out.writeln(table)?
out.close() out.close()
// regenerate index.html // regenerate index.html
header := os.read_file('header.html') ? header := os.read_file('header.html')?
footer := os.read_file('footer.html') ? footer := os.read_file('footer.html')?
mut res := os.create('index.html') ? mut res := os.create('index.html')?
res.writeln(header) ? res.writeln(header)?
res.writeln(table) ? res.writeln(table)?
res.writeln(footer) ? res.writeln(footer)?
res.close() res.close()
// upload the result to github pages // upload the result to github pages
if os.args.contains('-upload') { if os.args.contains('-upload') {
println('uploading...') println('uploading...')
os.chdir('website') ? os.chdir('website')?
os.execute_or_exit('git checkout gh-pages') os.execute_or_exit('git checkout gh-pages')
os.cp('../index.html', 'index.html') ? os.cp('../index.html', 'index.html')?
os.rm('../index.html') ? os.rm('../index.html')?
os.system('git commit -am "update benchmark"') os.system('git commit -am "update benchmark"')
os.system('git push origin gh-pages') os.system('git push origin gh-pages')
} }

View File

@ -125,7 +125,7 @@ fn main() {
should_sync := fp.bool('cache-sync', `s`, false, 'Update the local cache') should_sync := fp.bool('cache-sync', `s`, false, 'Update the local cache')
context.is_bisect = fp.bool('bisect', `b`, false, 'Bisect mode. Use the current commit in the repo where oldv is.') context.is_bisect = fp.bool('bisect', `b`, false, 'Bisect mode. Use the current commit in the repo where oldv is.')
if !should_sync && !context.is_bisect { if !should_sync && !context.is_bisect {
fp.limit_free_args(1, 1) ? fp.limit_free_args(1, 1)?
} }
//// ////
context.cleanup = fp.bool('clean', 0, false, 'Clean before running (slower).') context.cleanup = fp.bool('clean', 0, false, 'Clean before running (slower).')

View File

@ -194,7 +194,7 @@ fn main() {
fp.description(tool_description) fp.description(tool_description)
fp.arguments_description('COMMIT_BEFORE [COMMIT_AFTER]') fp.arguments_description('COMMIT_BEFORE [COMMIT_AFTER]')
fp.skip_executable() fp.skip_executable()
fp.limit_free_args(1, 2) ? fp.limit_free_args(1, 2)?
context.vflags = fp.string('vflags', 0, '', 'Additional options to pass to the v commands, for example "-cc tcc"') context.vflags = fp.string('vflags', 0, '', 'Additional options to pass to the v commands, for example "-cc tcc"')
context.hyperfineopts = fp.string('hyperfine_options', 0, '', 'Additional options passed to hyperfine. context.hyperfineopts = fp.string('hyperfine_options', 0, '', 'Additional options passed to hyperfine.
${flag.space}For example on linux, you may want to pass: ${flag.space}For example on linux, you may want to pass:

View File

@ -143,7 +143,7 @@ const (
fn main() { fn main() {
mut context := Context{} mut context := Context{}
context.parse_options() ? context.parse_options()?
context.run() context.run()
context.show_diff_summary() context.show_diff_summary()
} }
@ -155,7 +155,7 @@ fn (mut context Context) parse_options() ? {
fp.description('Repeat command(s) and collect statistics. Note: you have to quote each command, if it contains spaces.') fp.description('Repeat command(s) and collect statistics. Note: you have to quote each command, if it contains spaces.')
fp.arguments_description('CMD1 CMD2 ...') fp.arguments_description('CMD1 CMD2 ...')
fp.skip_executable() fp.skip_executable()
fp.limit_free_args_to_at_least(1) ? fp.limit_free_args_to_at_least(1)?
context.count = fp.int('count', `c`, 10, 'Repetition count.') context.count = fp.int('count', `c`, 10, 'Repetition count.')
context.series = fp.int('series', `s`, 2, 'Series count. `-s 2 -c 4 a b` => aaaabbbbaaaabbbb, while `-s 3 -c 2 a b` => aabbaabbaabb.') context.series = fp.int('series', `s`, 2, 'Series count. `-s 2 -c 4 a b` => aaaabbbbaaaabbbb, while `-s 3 -c 2 a b` => aabbaabbaabb.')
context.warmup = fp.int('warmup', `w`, 2, 'Warmup runs. These are done *only at the start*, and are ignored.') context.warmup = fp.int('warmup', `w`, 2, 'Warmup runs. These are done *only at the start*, and are ignored.')

View File

@ -42,7 +42,7 @@ fn cleanup_tdir() {
fn create_test(tname string, tcontent string) ?string { fn create_test(tname string, tcontent string) ?string {
tpath := os.join_path(tdir, tname) tpath := os.join_path(tdir, tname)
os.write_file(tpath, tcontent) ? os.write_file(tpath, tcontent)?
eprintln('>>>>>>>> tpath: $tpath | tcontent: $tcontent') eprintln('>>>>>>>> tpath: $tpath | tcontent: $tcontent')
return tpath return tpath
} }
@ -52,17 +52,17 @@ fn main() {
os.chdir(os.wd_at_startup) or {} os.chdir(os.wd_at_startup) or {}
} }
println('> vroot: $vroot | vexe: $vexe | tdir: $tdir') println('> vroot: $vroot | vexe: $vexe | tdir: $tdir')
ok_fpath := create_test('a_single_ok_test.v', 'fn test_ok(){ assert true }') ? ok_fpath := create_test('a_single_ok_test.v', 'fn test_ok(){ assert true }')?
check_ok('"$vexe" "$ok_fpath"') check_ok('"$vexe" "$ok_fpath"')
check_ok('"$vexe" test "$ok_fpath"') check_ok('"$vexe" test "$ok_fpath"')
check_ok('"$vexe" test "$tdir"') check_ok('"$vexe" test "$tdir"')
fail_fpath := create_test('a_single_failing_test.v', 'fn test_fail(){ assert 1 == 2 }') ? fail_fpath := create_test('a_single_failing_test.v', 'fn test_fail(){ assert 1 == 2 }')?
check_fail('"$vexe" "$fail_fpath"') check_fail('"$vexe" "$fail_fpath"')
check_fail('"$vexe" test "$fail_fpath"') check_fail('"$vexe" test "$fail_fpath"')
check_fail('"$vexe" test "$tdir"') check_fail('"$vexe" test "$tdir"')
rel_dir := os.join_path(tdir, rand.ulid()) rel_dir := os.join_path(tdir, rand.ulid())
os.mkdir(rel_dir) ? os.mkdir(rel_dir)?
os.chdir(rel_dir) ? os.chdir(rel_dir)?
check_ok('"$vexe" test "..${os.path_separator + os.base(ok_fpath)}"') check_ok('"$vexe" test "..${os.path_separator + os.base(ok_fpath)}"')
println('> all done') println('> all done')
} }

View File

@ -44,7 +44,7 @@ fn main() {
for hf in hfields.split(',') { for hf in hfields.split(',') {
ctx.hide_names[hf] = true ctx.hide_names[hf] = true
} }
fp.limit_free_args_to_at_least(1) ? fp.limit_free_args_to_at_least(1)?
rest_of_args := fp.remaining_parameters() rest_of_args := fp.remaining_parameters()
for vfile in rest_of_args { for vfile in rest_of_args {
file := get_abs_path(vfile) file := get_abs_path(vfile)

View File

@ -130,12 +130,12 @@ fn main() {
} }
max_bname := context.max_bname_len(file_byte_map.keys()) max_bname := context.max_bname_len(file_byte_map.keys())
if context.write_file.len > 0 { if context.write_file.len > 0 {
mut out_file := os.create(context.write_file) ? mut out_file := os.create(context.write_file)?
out_file.write_string(context.header()) ? out_file.write_string(context.header())?
for bname, fbytes in file_byte_map { for bname, fbytes in file_byte_map {
out_file.write_string(context.file2v(bname, fbytes, max_bname)) ? out_file.write_string(context.file2v(bname, fbytes, max_bname))?
} }
out_file.write_string(context.footer()) ? out_file.write_string(context.footer())?
} else { } else {
print(context.header()) print(context.header())
for bname, fbytes in file_byte_map { for bname, fbytes in file_byte_map {

View File

@ -23,7 +23,7 @@ fn main() {
args_string := os.args[1..].join(' ') args_string := os.args[1..].join(' ')
vexe := os.getenv('VEXE') vexe := os.getenv('VEXE')
vroot := os.dir(vexe) vroot := os.dir(vexe)
os.chdir(vroot) ? os.chdir(vroot)?
folder := os.join_path('cmd', 'tools') folder := os.join_path('cmd', 'tools')
tfolder := os.join_path(vroot, 'cmd', 'tools') tfolder := os.join_path(vroot, 'cmd', 'tools')
main_label := 'Building $folder ...' main_label := 'Building $folder ...'
@ -47,7 +47,7 @@ fn main() {
exit(1) exit(1)
} }
// //
mut executables := os.ls(session.vtmp_dir) ? mut executables := os.ls(session.vtmp_dir)?
executables.sort() executables.sort()
for texe in executables { for texe in executables {
tname := texe.replace(os.file_ext(texe), '') tname := texe.replace(os.file_ext(texe), '')

View File

@ -20,7 +20,7 @@ const (
tool_version = \'1.2.1\' tool_version = \'1.2.1\'
version: \'0.2.42\' version: \'0.2.42\'
VERSION = "1.23.8" VERSION = "1.23.8"
Examples: Examples:
Bump the patch version in v.mod if it exists Bump the patch version in v.mod if it exists
v bump --patch v bump --patch

View File

@ -68,21 +68,21 @@ fn run_individual_test(case BumpTestCase) ? {
test_file := os.join_path_single(temp_dir, case.file_name) test_file := os.join_path_single(temp_dir, case.file_name)
os.rm(test_file) or {} os.rm(test_file) or {}
os.write_file(test_file, case.contents) ? os.write_file(test_file, case.contents)?
// //
os.execute_or_exit('${os.quoted_path(vexe)} bump --patch ${os.quoted_path(test_file)}') os.execute_or_exit('${os.quoted_path(vexe)} bump --patch ${os.quoted_path(test_file)}')
patch_lines := os.read_lines(test_file) ? patch_lines := os.read_lines(test_file)?
assert patch_lines[case.line] == case.expected_patch assert patch_lines[case.line] == case.expected_patch
os.execute_or_exit('${os.quoted_path(vexe)} bump --minor ${os.quoted_path(test_file)}') os.execute_or_exit('${os.quoted_path(vexe)} bump --minor ${os.quoted_path(test_file)}')
minor_lines := os.read_lines(test_file) ? minor_lines := os.read_lines(test_file)?
assert minor_lines[case.line] == case.expected_minor assert minor_lines[case.line] == case.expected_minor
os.execute_or_exit('${os.quoted_path(vexe)} bump --major ${os.quoted_path(test_file)}') os.execute_or_exit('${os.quoted_path(vexe)} bump --major ${os.quoted_path(test_file)}')
major_lines := os.read_lines(test_file) ? major_lines := os.read_lines(test_file)?
assert major_lines[case.line] == case.expected_major assert major_lines[case.line] == case.expected_major
// //
os.rm(test_file) ? os.rm(test_file)?
} }
fn test_all_bump_cases() { fn test_all_bump_cases() {

View File

@ -5,7 +5,7 @@ const test_path = 'vcreate_test'
fn init_and_check() ? { fn init_and_check() ? {
os.execute_or_exit('${os.quoted_path(@VEXE)} init') os.execute_or_exit('${os.quoted_path(@VEXE)} init')
assert os.read_file('vcreate_test.v') ? == [ assert os.read_file('vcreate_test.v')? == [
'module main\n', 'module main\n',
'fn main() {', 'fn main() {',
" println('Hello World!')", " println('Hello World!')",
@ -13,7 +13,7 @@ fn init_and_check() ? {
'', '',
].join_lines() ].join_lines()
assert os.read_file('v.mod') ? == [ assert os.read_file('v.mod')? == [
'Module {', 'Module {',
" name: 'vcreate_test'", " name: 'vcreate_test'",
" description: ''", " description: ''",
@ -24,7 +24,7 @@ fn init_and_check() ? {
'', '',
].join_lines() ].join_lines()
assert os.read_file('.gitignore') ? == [ assert os.read_file('.gitignore')? == [
'# Binaries for programs and plugins', '# Binaries for programs and plugins',
'main', 'main',
'vcreate_test', 'vcreate_test',
@ -37,7 +37,7 @@ fn init_and_check() ? {
'', '',
].join_lines() ].join_lines()
assert os.read_file('.gitattributes') ? == [ assert os.read_file('.gitattributes')? == [
'*.v linguist-language=V text=auto eol=lf', '*.v linguist-language=V text=auto eol=lf',
'*.vv linguist-language=V text=auto eol=lf', '*.vv linguist-language=V text=auto eol=lf',
'*.vsh linguist-language=V text=auto eol=lf', '*.vsh linguist-language=V text=auto eol=lf',
@ -45,7 +45,7 @@ fn init_and_check() ? {
'', '',
].join_lines() ].join_lines()
assert os.read_file('.editorconfig') ? == [ assert os.read_file('.editorconfig')? == [
'[*]', '[*]',
'charset = utf-8', 'charset = utf-8',
'end_of_line = lf', 'end_of_line = lf',
@ -66,9 +66,9 @@ fn test_v_init() ? {
defer { defer {
os.rmdir_all(dir) or {} os.rmdir_all(dir) or {}
} }
os.chdir(dir) ? os.chdir(dir)?
init_and_check() ? init_and_check()?
} }
fn test_v_init_in_git_dir() ? { fn test_v_init_in_git_dir() ? {
@ -78,24 +78,24 @@ fn test_v_init_in_git_dir() ? {
defer { defer {
os.rmdir_all(dir) or {} os.rmdir_all(dir) or {}
} }
os.chdir(dir) ? os.chdir(dir)?
os.execute_or_exit('git init .') os.execute_or_exit('git init .')
init_and_check() ? init_and_check()?
} }
fn test_v_init_no_overwrite_gitignore() ? { fn test_v_init_no_overwrite_gitignore() ? {
dir := os.join_path(os.temp_dir(), test_path) dir := os.join_path(os.temp_dir(), test_path)
os.rmdir_all(dir) or {} os.rmdir_all(dir) or {}
os.mkdir(dir) or {} os.mkdir(dir) or {}
os.write_file('$dir/.gitignore', 'blah') ? os.write_file('$dir/.gitignore', 'blah')?
defer { defer {
os.rmdir_all(dir) or {} os.rmdir_all(dir) or {}
} }
os.chdir(dir) ? os.chdir(dir)?
os.execute_or_exit('${os.quoted_path(@VEXE)} init') os.execute_or_exit('${os.quoted_path(@VEXE)} init')
assert os.read_file('.gitignore') ? == 'blah' assert os.read_file('.gitignore')? == 'blah'
} }
fn test_v_init_no_overwrite_gitattributes_and_editorconfig() ? { fn test_v_init_no_overwrite_gitattributes_and_editorconfig() ? {
@ -114,15 +114,15 @@ indent_size = 4
dir := os.join_path(os.temp_dir(), test_path) dir := os.join_path(os.temp_dir(), test_path)
os.rmdir_all(dir) or {} os.rmdir_all(dir) or {}
os.mkdir(dir) or {} os.mkdir(dir) or {}
os.write_file('$dir/.gitattributes', git_attributes_content) ? os.write_file('$dir/.gitattributes', git_attributes_content)?
os.write_file('$dir/.editorconfig', editor_config_content) ? os.write_file('$dir/.editorconfig', editor_config_content)?
defer { defer {
os.rmdir_all(dir) or {} os.rmdir_all(dir) or {}
} }
os.chdir(dir) ? os.chdir(dir)?
os.execute_or_exit('${os.quoted_path(@VEXE)} init') os.execute_or_exit('${os.quoted_path(@VEXE)} init')
assert os.read_file('.gitattributes') ? == git_attributes_content assert os.read_file('.gitattributes')? == git_attributes_content
assert os.read_file('.editorconfig') ? == editor_config_content assert os.read_file('.editorconfig')? == editor_config_content
} }

View File

@ -16,7 +16,7 @@ fn find_diff_cmd() string {
fn test_vet() ? { fn test_vet() ? {
os.setenv('VCOLORS', 'never', true) os.setenv('VCOLORS', 'never', true)
os.chdir(vroot) ? os.chdir(vroot)?
test_dir := 'cmd/tools/vdoc/tests/testdata' test_dir := 'cmd/tools/vdoc/tests/testdata'
main_files := get_main_files_in_dir(test_dir) main_files := get_main_files_in_dir(test_dir)
fails := check_path(vexe, test_dir, main_files) fails := check_path(vexe, test_dir, main_files)

View File

@ -142,11 +142,11 @@ fn main() {
exit(1) exit(1)
} }
opt.config = new_config(opt.root_path, toml_conf) ? opt.config = new_config(opt.root_path, toml_conf)?
gen_in_path := arg_paths[0] gen_in_path := arg_paths[0]
if arg_paths.len >= 1 { if arg_paths.len >= 1 {
generate_screenshots(mut opt, gen_in_path) ? generate_screenshots(mut opt, gen_in_path)?
} }
if arg_paths.len > 1 { if arg_paths.len > 1 {
target_path := arg_paths[1] target_path := arg_paths[1]
@ -199,7 +199,7 @@ fn generate_screenshots(mut opt Options, output_path string) ? {
if opt.verbose { if opt.verbose {
eprintln('Creating output path `$dst_path`') eprintln('Creating output path `$dst_path`')
} }
os.mkdir_all(dst_path) ? os.mkdir_all(dst_path)?
} }
screenshot_path := os.join_path(dst_path, rel_out_path) screenshot_path := os.join_path(dst_path, rel_out_path)
@ -332,7 +332,7 @@ fn take_screenshots(opt Options, app AppConfig) ?[]string {
// ensure_env returns nothing if everything is okay. // ensure_env returns nothing if everything is okay.
fn ensure_env(opt Options) ? { fn ensure_env(opt Options) ? {
if !os.exists(tmp_dir) { if !os.exists(tmp_dir) {
os.mkdir_all(tmp_dir) ? os.mkdir_all(tmp_dir)?
} }
if runtime_os !in supported_hosts { if runtime_os !in supported_hosts {
@ -355,9 +355,9 @@ fn vexe() string {
fn new_config(root_path string, toml_config string) ?Config { fn new_config(root_path string, toml_config string) ?Config {
doc := if os.is_file(toml_config) { doc := if os.is_file(toml_config) {
toml.parse_file(toml_config) ? toml.parse_file(toml_config)?
} else { } else {
toml.parse_text(toml_config) ? toml.parse_text(toml_config)?
} }
path := os.real_path(root_path).trim_right('/') path := os.real_path(root_path).trim_right('/')

View File

@ -12,11 +12,11 @@ fn main() {
fp.version('0.0.1') fp.version('0.0.1')
fp.description('\nScan .v source files, and print the V tokens contained in them.') fp.description('\nScan .v source files, and print the V tokens contained in them.')
fp.arguments_description('PATH [PATH]...') fp.arguments_description('PATH [PATH]...')
fp.limit_free_args_to_at_least(1) ? fp.limit_free_args_to_at_least(1)?
pref := pref.new_preferences() pref := pref.new_preferences()
mut all_paths := fp.remaining_parameters() mut all_paths := fp.remaining_parameters()
for path in all_paths { for path in all_paths {
mut scanner := scanner.new_scanner_file(path, .parse_comments, pref) ? mut scanner := scanner.new_scanner_file(path, .parse_comments, pref)?
mut tok := token.Token{} mut tok := token.Token{}
for tok.kind != .eof { for tok.kind != .eof {
tok = scanner.scan() tok = scanner.scan()

View File

@ -15,7 +15,7 @@ fn main() {
short_v_name := vexe_name.all_before('.') short_v_name := vexe_name.all_before('.')
// //
recompilation.must_be_enabled(vroot, 'Please install V from source, to use `$vexe_name self` .') recompilation.must_be_enabled(vroot, 'Please install V from source, to use `$vexe_name self` .')
os.chdir(vroot) ? os.chdir(vroot)?
os.setenv('VCOLORS', 'always', true) os.setenv('VCOLORS', 'always', true)
args := os.args[1..].filter(it != 'self') args := os.args[1..].filter(it != 'self')
jargs := args.join(' ') jargs := args.join(' ')

View File

@ -11,7 +11,7 @@ fn main() {
$if windows { $if windows {
println('Setup freetype...') println('Setup freetype...')
vroot := os.dir(pref.vexe_path()) vroot := os.dir(pref.vexe_path())
os.chdir(vroot) ? os.chdir(vroot)?
if os.is_dir(freetype_folder) { if os.is_dir(freetype_folder) {
println('Thirdparty "freetype" is already installed.') println('Thirdparty "freetype" is already installed.')
} else { } else {

View File

@ -172,7 +172,7 @@ fn compile_shaders(opt Options, input_path string) ? {
// Currently sokol-shdc allows for multiple --input flags // Currently sokol-shdc allows for multiple --input flags
// - but it's only the last entry that's actually compiled/used // - but it's only the last entry that's actually compiled/used
// Given this fact - we can only compile one '.glsl' file to one C '.h' header // Given this fact - we can only compile one '.glsl' file to one C '.h' header
compile_shader(co, shader_file) ? compile_shader(co, shader_file)?
} }
} }
@ -233,10 +233,10 @@ fn collect(path string, mut list []string) {
// tools can be setup or is already in place. // tools can be setup or is already in place.
fn ensure_external_tools(opt Options) ? { fn ensure_external_tools(opt Options) ? {
if !os.exists(cache_dir) { if !os.exists(cache_dir) {
os.mkdir_all(cache_dir) ? os.mkdir_all(cache_dir)?
} }
if opt.force_update { if opt.force_update {
download_shdc(opt) ? download_shdc(opt)?
return return
} }
@ -250,7 +250,7 @@ fn ensure_external_tools(opt Options) ? {
return return
} }
download_shdc(opt) ? download_shdc(opt)?
} }
// shdc_exe returns an absolute path to the `sokol-shdc` tool. // shdc_exe returns an absolute path to the `sokol-shdc` tool.
@ -277,26 +277,26 @@ fn download_shdc(opt Options) ? {
} }
} }
if os.exists(file) { if os.exists(file) {
os.rm(file) ? os.rm(file)?
} }
mut dtmp_file, dtmp_path := util.temp_file(util.TempFileOptions{ path: os.dir(file) }) ? mut dtmp_file, dtmp_path := util.temp_file(util.TempFileOptions{ path: os.dir(file) })?
dtmp_file.close() dtmp_file.close()
if opt.verbose { if opt.verbose {
eprintln('$tool_name downloading sokol-shdc from $download_url') eprintln('$tool_name downloading sokol-shdc from $download_url')
} }
http.download_file(download_url, dtmp_path) or { http.download_file(download_url, dtmp_path) or {
os.rm(dtmp_path) ? os.rm(dtmp_path)?
return error('$tool_name failed to download sokol-shdc needed for shader compiling: $err') return error('$tool_name failed to download sokol-shdc needed for shader compiling: $err')
} }
// Make it executable // Make it executable
os.chmod(dtmp_path, 0o775) ? os.chmod(dtmp_path, 0o775)?
// Move downloaded file in place // Move downloaded file in place
os.mv(dtmp_path, file) ? os.mv(dtmp_path, file)?
if runtime_os in ['linux', 'macos'] { if runtime_os in ['linux', 'macos'] {
// Use the .exe file ending to minimize platform friction. // Use the .exe file ending to minimize platform friction.
os.mv(file, shdc) ? os.mv(file, shdc)?
} }
// Update internal version file // Update internal version file
os.write_file(shdc_version_file, update_to_shdc_version) ? os.write_file(shdc_version_file, update_to_shdc_version)?
} }

View File

@ -54,7 +54,7 @@ fn main() {
context.pref = &pref.Preferences{ context.pref = &pref.Preferences{
output_mode: .silent output_mode: .silent
} }
mut source := os.read_file(context.path) ? mut source := os.read_file(context.path)?
source = source[..context.cut_index] source = source[..context.cut_index]
go fn (ms int) { go fn (ms int) {

View File

@ -6,7 +6,7 @@ import v.pref
fn main() { fn main() {
vexe := pref.vexe_path() vexe := pref.vexe_path()
vroot := os.dir(vexe) vroot := os.dir(vexe)
os.chdir(vroot) ? os.chdir(vroot)?
os.setenv('VCOLORS', 'always', true) os.setenv('VCOLORS', 'always', true)
self_idx := os.args.index('tracev') self_idx := os.args.index('tracev')
args := os.args[1..self_idx] args := os.args[1..self_idx]

View File

@ -26,7 +26,7 @@ fn new_app() App {
fn main() { fn main() {
app := new_app() app := new_app()
recompilation.must_be_enabled(app.vroot, 'Please install V from source, to use `v up` .') recompilation.must_be_enabled(app.vroot, 'Please install V from source, to use `v up` .')
os.chdir(app.vroot) ? os.chdir(app.vroot)?
println('Updating V...') println('Updating V...')
app.update_from_master() app.update_from_master()
v_hash := version.githash(false) v_hash := version.githash(false)

View File

@ -14,7 +14,7 @@ fn find_diff_cmd() string {
fn test_vet() ? { fn test_vet() ? {
vexe := os.getenv('VEXE') vexe := os.getenv('VEXE')
vroot := os.dir(vexe) vroot := os.dir(vexe)
os.chdir(vroot) ? os.chdir(vroot)?
test_dir := 'cmd/tools/vvet/tests' test_dir := 'cmd/tools/vvet/tests'
tests := get_tests_in_dir(test_dir) tests := get_tests_in_dir(test_dir)
fails := check_path(vexe, test_dir, tests) fails := check_path(vexe, test_dir, tests)

View File

@ -313,7 +313,7 @@ fn main() {
fp.description('Collect all .v files needed for a compilation, then re-run the compilation when any of the source changes.') fp.description('Collect all .v files needed for a compilation, then re-run the compilation when any of the source changes.')
fp.arguments_description('[--silent] [--clear] [--ignore .db] [--add /path/to/a/file.v] [run] program.v') fp.arguments_description('[--silent] [--clear] [--ignore .db] [--add /path/to/a/file.v] [run] program.v')
fp.allow_unknown_args() fp.allow_unknown_args()
fp.limit_free_args_to_at_least(1) ? fp.limit_free_args_to_at_least(1)?
context.is_worker = fp.bool('vwatchworker', 0, false, 'Internal flag. Used to distinguish vwatch manager and worker processes.') context.is_worker = fp.bool('vwatchworker', 0, false, 'Internal flag. Used to distinguish vwatch manager and worker processes.')
context.silent = fp.bool('silent', `s`, false, 'Be more silent; do not print the watch timestamp before each re-run.') context.silent = fp.bool('silent', `s`, false, 'Be more silent; do not print the watch timestamp before each re-run.')
context.clear_terminal = fp.bool('clear', `c`, false, 'Clears the terminal before each re-run.') context.clear_terminal = fp.bool('clear', `c`, false, 'Clears the terminal before each re-run.')

View File

@ -1303,7 +1303,7 @@ large_index := 999
val := arr[large_index] or { panic('out of bounds') } val := arr[large_index] or { panic('out of bounds') }
println(val) println(val)
// you can also do this, if you want to *propagate* the access error: // you can also do this, if you want to *propagate* the access error:
val2 := arr[333] ? val2 := arr[333]?
println(val2) println(val2)
``` ```
@ -1893,7 +1893,7 @@ enum State {
// write log file and return number of bytes written // write log file and return number of bytes written
fn write_log(s State) ?int { fn write_log(s State) ?int {
mut f := os.create('log.txt') ? mut f := os.create('log.txt')?
defer { defer {
f.close() f.close()
} }
@ -3419,7 +3419,7 @@ propagate the error:
import net.http import net.http
fn f(url string) ?string { fn f(url string) ?string {
resp := http.get(url) ? resp := http.get(url)?
return resp.text return resp.text
} }
``` ```
@ -3937,7 +3937,7 @@ println(user.last_name)
println(user.age) println(user.age)
// You can also decode JSON arrays: // You can also decode JSON arrays:
sfoos := '[{"x":123},{"x":456}]' sfoos := '[{"x":123},{"x":456}]'
foos := json.decode([]Foo, sfoos) ? foos := json.decode([]Foo, sfoos)?
println(foos[0].x) println(foos[0].x)
println(foos[1].x) println(foos[1].x)
``` ```
@ -4042,8 +4042,8 @@ If a test function has an error return type, any propagated errors will fail the
import strconv import strconv
fn test_atoi() ? { fn test_atoi() ? {
assert strconv.atoi('1') ? == 1 assert strconv.atoi('1')? == 1
assert strconv.atoi('one') ? == 1 // test will fail assert strconv.atoi('one')? == 1 // test will fail
} }
``` ```
@ -4435,7 +4435,7 @@ struct Customer {
country string [nonull] country string [nonull]
} }
db := sqlite.connect('customers.db') ? db := sqlite.connect('customers.db')?
// you can create tables: // you can create tables:
// CREATE TABLE IF NOT EXISTS `Customer` ( // CREATE TABLE IF NOT EXISTS `Customer` (
@ -5356,7 +5356,7 @@ Full list of builtin options:
import os import os
fn main() { fn main() {
embedded_file := $embed_file('v.png') embedded_file := $embed_file('v.png')
os.write_file('exported.png', embedded_file.to_string()) ? os.write_file('exported.png', embedded_file.to_string())?
} }
``` ```
@ -5380,7 +5380,7 @@ Currently only one compression type is supported: `zlib`
import os import os
fn main() { fn main() {
embedded_file := $embed_file('v.png', .zlib) // compressed using zlib embedded_file := $embed_file('v.png', .zlib) // compressed using zlib
os.write_file('exported.png', embedded_file.to_string()) ? os.write_file('exported.png', embedded_file.to_string())?
} }
``` ```
@ -5833,7 +5833,7 @@ fn sh(cmd string){
rmdir_all('build') or { } rmdir_all('build') or { }
// Create build/, never fails as build/ does not exist // Create build/, never fails as build/ does not exist
mkdir('build') ? mkdir('build')?
// Move *.v files to build/ // Move *.v files to build/
result := execute('mv *.v build/') result := execute('mv *.v build/')
@ -5844,7 +5844,7 @@ if result.exit_code != 0 {
sh('ls') sh('ls')
// Similar to: // Similar to:
// files := ls('.') ? // files := ls('.')?
// mut count := 0 // mut count := 0
// if files.len > 0 { // if files.len > 0 {
// for file in files { // for file in files {

View File

@ -5,9 +5,9 @@ import io
fn main() { fn main() {
// Make a new connection // Make a new connection
mut conn := net.dial_tcp('google.com:80') ? mut conn := net.dial_tcp('google.com:80')?
// Simple http HEAD request for a file // Simple http HEAD request for a file
conn.write_string('GET /index.html HTTP/1.0\r\n\r\n') ? conn.write_string('GET /index.html HTTP/1.0\r\n\r\n')?
// Wrap in a buffered reader // Wrap in a buffered reader
mut r := io.new_buffered_reader(reader: conn) mut r := io.new_buffered_reader(reader: conn)
for { for {

View File

@ -4,7 +4,7 @@ import time
fn vlang_time(mut wg sync.WaitGroup) ?string { fn vlang_time(mut wg sync.WaitGroup) ?string {
start := time.ticks() start := time.ticks()
data := http.get('https://vlang.io/utc_now') ? data := http.get('https://vlang.io/utc_now')?
finish := time.ticks() finish := time.ticks()
println('Finish getting time ${finish - start} ms') println('Finish getting time ${finish - start} ms')
println(data.text) println(data.text)
@ -14,7 +14,7 @@ fn vlang_time(mut wg sync.WaitGroup) ?string {
fn remote_ip(mut wg sync.WaitGroup) ?string { fn remote_ip(mut wg sync.WaitGroup) ?string {
start := time.ticks() start := time.ticks()
data := http.get('https://api.ipify.org') ? data := http.get('https://api.ipify.org')?
finish := time.ticks() finish := time.ticks()
println('Finish getting ip ${finish - start} ms') println('Finish getting ip ${finish - start} ms')
println(data.text) println(data.text)

View File

@ -8,8 +8,8 @@ fn main() {
password: '' password: ''
dbname: 'mysql' dbname: 'mysql'
} }
conn.connect() ? conn.connect()?
res := conn.query('show tables') ? res := conn.query('show tables')?
for row in res.rows() { for row in res.rows() {
println(row.vals.join(', ')) println(row.vals.join(', '))
} }

View File

@ -1,7 +1,7 @@
import sqlite import sqlite
fn main() { fn main() {
db := sqlite.connect(':memory:') ? db := sqlite.connect(':memory:')?
db.exec("create table users (id integer primary key, name text default '');") db.exec("create table users (id integer primary key, name text default '');")
db.exec("insert into users (name) values ('Sam')") db.exec("insert into users (name) values ('Sam')")

View File

@ -7,9 +7,9 @@ type FNAdder = fn (int, int) int
fn main() { fn main() {
library_file_path := os.join_path(os.getwd(), dl.get_libname('library')) library_file_path := os.join_path(os.getwd(), dl.get_libname('library'))
handle := dl.open_opt(library_file_path, dl.rtld_lazy) ? handle := dl.open_opt(library_file_path, dl.rtld_lazy)?
eprintln('handle: ${ptr_str(handle)}') eprintln('handle: ${ptr_str(handle)}')
f := FNAdder(dl.sym_opt(handle, 'add_1') ?) f := FNAdder(dl.sym_opt(handle, 'add_1')?)
eprintln('f: ${ptr_str(f)}') eprintln('f: ${ptr_str(f)}')
res := f(1, 2) res := f(1, 2)
eprintln('res: $res') eprintln('res: $res')

View File

@ -34,5 +34,5 @@ fn main() {
mut server := Server{ mut server := Server{
handler: ExampleHandler{} handler: ExampleHandler{}
} }
server.listen_and_serve() ? server.listen_and_serve()?
} }

View File

@ -348,19 +348,19 @@ fn animate(mut state State, time f64) {
fn main() { fn main() {
canvas, gl := get_webgl() canvas, gl := get_webgl()
vertex_buffer := gl.createBuffer() ? vertex_buffer := gl.createBuffer()?
gl.bindBuffer(dom.gl_array_buffer(), vertex_buffer) gl.bindBuffer(dom.gl_array_buffer(), vertex_buffer)
gl.bufferData(dom.gl_array_buffer(), float32_array(vertices), dom.gl_static_draw()) gl.bufferData(dom.gl_array_buffer(), float32_array(vertices), dom.gl_static_draw())
color_buffer := gl.createBuffer() ? color_buffer := gl.createBuffer()?
gl.bindBuffer(dom.gl_array_buffer(), color_buffer) gl.bindBuffer(dom.gl_array_buffer(), color_buffer)
gl.bufferData(dom.gl_array_buffer(), float32_array(colors), dom.gl_static_draw()) gl.bufferData(dom.gl_array_buffer(), float32_array(colors), dom.gl_static_draw())
index_buffer := gl.createBuffer() ? index_buffer := gl.createBuffer()?
gl.bindBuffer(dom.gl_element_array_buffer(), index_buffer) gl.bindBuffer(dom.gl_element_array_buffer(), index_buffer)
gl.bufferData(dom.gl_element_array_buffer(), uint16_array(indices), dom.gl_static_draw()) gl.bufferData(dom.gl_element_array_buffer(), uint16_array(indices), dom.gl_static_draw())
vert_shader := gl.createShader(dom.gl_vertex_shader()) ? vert_shader := gl.createShader(dom.gl_vertex_shader())?
gl.shaderSource(vert_shader, vert_code.str) gl.shaderSource(vert_shader, vert_code.str)
gl.compileShader(vert_shader) gl.compileShader(vert_shader)
@ -368,14 +368,14 @@ fn main() {
panic('An error occurred when compiling vertex shader: ${string(gl.getShaderInfoLog(vert_shader))}') panic('An error occurred when compiling vertex shader: ${string(gl.getShaderInfoLog(vert_shader))}')
} }
frag_shader := gl.createShader(dom.gl_fragment_shader()) ? frag_shader := gl.createShader(dom.gl_fragment_shader())?
gl.shaderSource(frag_shader, frag_code.str) gl.shaderSource(frag_shader, frag_code.str)
gl.compileShader(frag_shader) gl.compileShader(frag_shader)
if !bool(JS.Boolean(gl.getShaderParameter(frag_shader, dom.gl_compile_status()))) { if !bool(JS.Boolean(gl.getShaderParameter(frag_shader, dom.gl_compile_status()))) {
panic('An error occurred when compiling fragment shader: ${string(gl.getShaderInfoLog(frag_shader))}') panic('An error occurred when compiling fragment shader: ${string(gl.getShaderInfoLog(frag_shader))}')
} }
shader_program := gl.createProgram() ? shader_program := gl.createProgram()?
gl.attachShader(shader_program, vert_shader) gl.attachShader(shader_program, vert_shader)
gl.attachShader(shader_program, frag_shader) gl.attachShader(shader_program, frag_shader)
gl.linkProgram(shader_program) gl.linkProgram(shader_program)
@ -384,9 +384,9 @@ fn main() {
panic('unable to initialize the shader program: ${string(gl.getProgramInfoLog(shader_program))}') panic('unable to initialize the shader program: ${string(gl.getProgramInfoLog(shader_program))}')
} }
pmatrix := gl.getUniformLocation(shader_program, 'Pmatrix'.str) ? pmatrix := gl.getUniformLocation(shader_program, 'Pmatrix'.str)?
vmatrix := gl.getUniformLocation(shader_program, 'Vmatrix'.str) ? vmatrix := gl.getUniformLocation(shader_program, 'Vmatrix'.str)?
mmatrix := gl.getUniformLocation(shader_program, 'Mmatrix'.str) ? mmatrix := gl.getUniformLocation(shader_program, 'Mmatrix'.str)?
gl.bindBuffer(dom.gl_array_buffer(), vertex_buffer) gl.bindBuffer(dom.gl_array_buffer(), vertex_buffer)
position := gl.getAttribLocation(shader_program, 'position'.str) position := gl.getAttribLocation(shader_program, 'position'.str)

View File

@ -32,10 +32,10 @@ mut:
fn main() { fn main() {
window := dom.window() window := dom.window()
document := dom.document document := dom.document
clear_btn := document.getElementById('clearButton'.str) ? clear_btn := document.getElementById('clearButton'.str)?
canvas_elem := document.getElementById('canvas'.str) ? canvas_elem := document.getElementById('canvas'.str)?
canvas := get_canvas(canvas_elem) canvas := get_canvas(canvas_elem)
ctx := canvas.getContext('2d'.str, js_undefined()) ? ctx := canvas.getContext('2d'.str, js_undefined())?
context := match ctx { context := match ctx {
JS.CanvasRenderingContext2D { JS.CanvasRenderingContext2D {
ctx ctx

View File

@ -1,5 +1,5 @@
import net import net
conn := net.dial_tcp('google.com:80') ? conn := net.dial_tcp('google.com:80')?
peer_addr := conn.peer_addr() ? peer_addr := conn.peer_addr()?
println('$peer_addr') println('$peer_addr')

View File

@ -3,18 +3,18 @@ import io
fn main() { fn main() {
// Make a new connection // Make a new connection
mut conn := net.dial_tcp('google.com:80') ? mut conn := net.dial_tcp('google.com:80')?
defer { defer {
conn.close() or {} conn.close() or {}
} }
println(' peer: ${conn.peer_addr() ?}') println(' peer: ${conn.peer_addr()?}')
println('local: ${conn.addr() ?}') println('local: ${conn.addr()?}')
// Simple http HEAD request for a file // Simple http HEAD request for a file
conn.write_string('HEAD /index.html HTTP/1.0\r\n\r\n') ? conn.write_string('HEAD /index.html HTTP/1.0\r\n\r\n')?
// Read all the data that is waiting // Read all the data that is waiting
result := io.read_all(reader: conn) ? result := io.read_all(reader: conn)?
// Cast to string and print result // Cast to string and print result
println(result.bytestr()) println(result.bytestr())
} }

View File

@ -4,7 +4,7 @@ import time
fn send_request(mut wg sync.WaitGroup) ?string { fn send_request(mut wg sync.WaitGroup) ?string {
start := time.ticks() start := time.ticks()
data := http.get('https://google.com') ? data := http.get('https://google.com')?
finish := time.ticks() finish := time.ticks()
println('Finish getting time ${finish - start} ms') println('Finish getting time ${finish - start} ms')
wg.done() wg.done()

View File

@ -12,7 +12,7 @@ fn main() {
mut buf := []u8{len: 100} mut buf := []u8{len: 100}
if is_server { if is_server {
println('UDP echo server, listening for udp packets on port: $port') println('UDP echo server, listening for udp packets on port: $port')
mut c := net.listen_udp(':$port') ? mut c := net.listen_udp(':$port')?
for { for {
read, addr := c.read(mut buf) or { continue } read, addr := c.read(mut buf) or { continue }
println('received $read bytes from $addr') println('received $read bytes from $addr')
@ -23,7 +23,7 @@ fn main() {
} }
} else { } else {
println('UDP client, sending packets to port: ${port}.\nType `exit` to exit.') println('UDP client, sending packets to port: ${port}.\nType `exit` to exit.')
mut c := net.dial_udp('localhost:$port') ? mut c := net.dial_udp('localhost:$port')?
for { for {
mut line := os.input('client > ') mut line := os.input('client > ')
match line { match line {
@ -36,8 +36,8 @@ fn main() {
} }
else {} else {}
} }
c.write_string(line) ? c.write_string(line)?
read, _ := c.read(mut buf) ? read, _ := c.read(mut buf)?
println('server : ' + buf[0..read].bytestr()) println('server : ' + buf[0..read].bytestr())
} }
} }

View File

@ -6,7 +6,7 @@ import sim.anim
import sim.args as simargs import sim.args as simargs
fn main() { fn main() {
args := simargs.parse_args(extra_workers: 1) ? as simargs.ParallelArgs args := simargs.parse_args(extra_workers: 1)? as simargs.ParallelArgs
mut app := anim.new_app(args) mut app := anim.new_app(args)
mut workers := []thread{cap: args.workers} mut workers := []thread{cap: args.workers}

View File

@ -7,11 +7,11 @@ import sim.args as simargs
import sim.img import sim.img
fn main() { fn main() {
args := simargs.parse_args(extra_workers: 2) ? as simargs.ParallelArgs args := simargs.parse_args(extra_workers: 2)? as simargs.ParallelArgs
img_settings := img.image_settings_from_grid(args.grid) img_settings := img.image_settings_from_grid(args.grid)
mut writer := img.ppm_writer_for_fname(args.filename, img_settings) ? mut writer := img.ppm_writer_for_fname(args.filename, img_settings)?
mut app := anim.new_app(args) mut app := anim.new_app(args)
mut workers := []thread{cap: args.workers + 1} mut workers := []thread{cap: args.workers + 1}

View File

@ -33,10 +33,10 @@ pub type SimArgs = ParallelArgs | SequentialArgs
pub fn parse_args(config ParserSettings) ?SimArgs { pub fn parse_args(config ParserSettings) ?SimArgs {
if config.sequential { if config.sequential {
args := parse_sequential_args() ? args := parse_sequential_args()?
return SimArgs(args) return SimArgs(args)
} else { } else {
args := parse_parallel_args(config.extra_workers) ? args := parse_parallel_args(config.extra_workers)?
return SimArgs(args) return SimArgs(args)
} }
} }
@ -45,7 +45,7 @@ fn parse_sequential_args() ?SequentialArgs {
mut fp := flag.new_flag_parser(os.args) mut fp := flag.new_flag_parser(os.args)
fp.application('vps') fp.application('vps')
fp.version('v0.1.0') fp.version('v0.1.0')
fp.limit_free_args(0, 0) ? fp.limit_free_args(0, 0)?
fp.description('This is a pendulum simulation written in pure V') fp.description('This is a pendulum simulation written in pure V')
fp.skip_executable() fp.skip_executable()
@ -96,7 +96,7 @@ fn parse_parallel_args(extra_workers int) ?ParallelArgs {
mut fp := flag.new_flag_parser(os.args) mut fp := flag.new_flag_parser(os.args)
fp.application('vps') fp.application('vps')
fp.version('v0.1.0') fp.version('v0.1.0')
fp.limit_free_args(0, 0) ? fp.limit_free_args(0, 0)?
fp.description('This is a pendulum simulation written in pure V') fp.description('This is a pendulum simulation written in pure V')
fp.skip_executable() fp.skip_executable()

View File

@ -44,19 +44,19 @@ pub fn ppm_writer_for_fname(fname string, settings ImageSettings) ?&PPMWriter {
cache_size: settings.cache_size cache_size: settings.cache_size
cache: []u8{cap: settings.cache_size} cache: []u8{cap: settings.cache_size}
} }
writer.start_for_file(fname, settings) ? writer.start_for_file(fname, settings)?
return writer return writer
} }
pub fn (mut writer PPMWriter) start_for_file(fname string, settings ImageSettings) ? { pub fn (mut writer PPMWriter) start_for_file(fname string, settings ImageSettings) ? {
writer.file = os.create(fname) ? writer.file = os.create(fname)?
writer.file.writeln('P6 $settings.width $settings.height 255') ? writer.file.writeln('P6 $settings.width $settings.height 255')?
} }
pub fn (mut writer PPMWriter) handle_pixel(p gx.Color) ? { pub fn (mut writer PPMWriter) handle_pixel(p gx.Color) ? {
if writer.cache.len >= writer.cache_size { if writer.cache.len >= writer.cache_size {
writer.write() ? writer.write()?
writer.flush() ? writer.flush()?
} }
writer.cache << [p.r, p.g, p.b] writer.cache << [p.r, p.g, p.b]
} }
@ -66,7 +66,7 @@ pub fn (mut writer PPMWriter) flush() ? {
} }
pub fn (mut writer PPMWriter) write() ? { pub fn (mut writer PPMWriter) write() ? {
writer.file.write(writer.cache) ? writer.file.write(writer.cache)?
} }
pub fn (mut writer PPMWriter) close() { pub fn (mut writer PPMWriter) close() {

View File

@ -6,7 +6,7 @@ import sim.args as simargs
import sim.img import sim.img
fn main() { fn main() {
args := simargs.parse_args() ? as simargs.ParallelArgs args := simargs.parse_args()? as simargs.ParallelArgs
img_settings := img.image_settings_from_grid(args.grid) img_settings := img.image_settings_from_grid(args.grid)
@ -17,7 +17,7 @@ fn main() {
request_chan := chan &sim.SimRequest{cap: args.workers} request_chan := chan &sim.SimRequest{cap: args.workers}
result_chan := chan &sim.SimResult{cap: args.workers} result_chan := chan &sim.SimResult{cap: args.workers}
mut writer := img.ppm_writer_for_fname(args.filename, img_settings) ? mut writer := img.ppm_writer_for_fname(args.filename, img_settings)?
mut image_writer := img.new_image_writer(mut writer, img_settings) mut image_writer := img.new_image_writer(mut writer, img_settings)
mut workers := []thread{cap: args.workers} mut workers := []thread{cap: args.workers}

View File

@ -6,14 +6,14 @@ import sim.args as simargs
import sim.img import sim.img
fn main() { fn main() {
args := simargs.parse_args(extra_workers: 1) ? as simargs.ParallelArgs args := simargs.parse_args(extra_workers: 1)? as simargs.ParallelArgs
img_settings := img.image_settings_from_grid(args.grid) img_settings := img.image_settings_from_grid(args.grid)
request_chan := chan &sim.SimRequest{cap: args.workers} request_chan := chan &sim.SimRequest{cap: args.workers}
result_chan := chan &sim.SimResult{cap: args.workers} result_chan := chan &sim.SimResult{cap: args.workers}
mut writer := img.ppm_writer_for_fname(args.filename, img_settings) ? mut writer := img.ppm_writer_for_fname(args.filename, img_settings)?
mut workers := []thread{cap: args.workers + 1} mut workers := []thread{cap: args.workers + 1}
mut bmark := benchmark.start() mut bmark := benchmark.start()

View File

@ -6,14 +6,14 @@ import sim.args as simargs
import sim.img import sim.img
fn main() { fn main() {
args := simargs.parse_args(sequential: true) ? as simargs.SequentialArgs args := simargs.parse_args(sequential: true)? as simargs.SequentialArgs
mut bmark := benchmark.start() mut bmark := benchmark.start()
defer { defer {
bmark.measure(@FN) bmark.measure(@FN)
} }
mut writer := img.ppm_writer_for_fname(args.filename, img.image_settings_from_grid(args.grid)) ? mut writer := img.ppm_writer_for_fname(args.filename, img.image_settings_from_grid(args.grid))?
defer { defer {
writer.close() writer.close()
} }
@ -26,5 +26,5 @@ fn main() {
sim.run(args.params, grid: args.grid, on_request: sim.SimRequestHandler(handle_request)) sim.run(args.params, grid: args.grid, on_request: sim.SimRequestHandler(handle_request))
writer.write() ? writer.write()?
} }

View File

@ -2,6 +2,6 @@ import rand
fn main() { fn main() {
for _ in 0 .. 10 { for _ in 0 .. 10 {
println('${rand.intn(255) ?}.${rand.intn(255) ?}.${rand.intn(255) ?}.${rand.intn(255) ?}') println('${rand.intn(255)?}.${rand.intn(255)?}.${rand.intn(255)?}.${rand.intn(255)?}')
} }
} }

View File

@ -12,10 +12,10 @@ mut:
fn main() { fn main() {
if os.args.len < 2 { if os.args.len < 2 {
eprintln('Usage: play_wav file1.wav file2.wav ...') eprintln('Usage: play_wav file1.wav file2.wav ...')
play_sounds([os.resource_abs_path('uhoh.wav')]) ? play_sounds([os.resource_abs_path('uhoh.wav')])?
exit(1) exit(1)
} }
play_sounds(os.args[1..]) ? play_sounds(os.args[1..])?
} }
fn play_sounds(files []string) ? { fn play_sounds(files []string) ? {
@ -31,7 +31,7 @@ fn play_sounds(files []string) ? {
eprintln('skipping "$f" (not a .wav file)') eprintln('skipping "$f" (not a .wav file)')
continue continue
} }
player.play_wav_file(f) ? player.play_wav_file(f)?
} }
player.stop() player.stop()
} }
@ -67,7 +67,7 @@ fn (mut p Player) stop() {
fn (mut p Player) play_wav_file(fpath string) ? { fn (mut p Player) play_wav_file(fpath string) ? {
println('> play_wav_file: $fpath') println('> play_wav_file: $fpath')
samples := read_wav_file_samples(fpath) ? samples := read_wav_file_samples(fpath)?
p.finished = true p.finished = true
p.samples << samples p.samples << samples
p.finished = false p.finished = false
@ -119,7 +119,7 @@ struct RIFFFormat {
fn read_wav_file_samples(fpath string) ?[]f32 { fn read_wav_file_samples(fpath string) ?[]f32 {
mut res := []f32{} mut res := []f32{}
// eprintln('> read_wav_file_samples: $fpath -------------------------------------------------') // eprintln('> read_wav_file_samples: $fpath -------------------------------------------------')
mut bytes := os.read_bytes(fpath) ? mut bytes := os.read_bytes(fpath)?
mut pbytes := &u8(bytes.data) mut pbytes := &u8(bytes.data)
mut offset := u32(0) mut offset := u32(0)
rh := unsafe { &RIFFHeader(pbytes) } rh := unsafe { &RIFFHeader(pbytes) }

View File

@ -9,11 +9,11 @@ import net
// telnet 127.0.0.1 12345 // telnet 127.0.0.1 12345
fn main() { fn main() {
mut server := net.listen_tcp(.ip6, ':12345') ? mut server := net.listen_tcp(.ip6, ':12345')?
laddr := server.addr() ? laddr := server.addr()?
eprintln('Listen on $laddr ...') eprintln('Listen on $laddr ...')
for { for {
mut socket := server.accept() ? mut socket := server.accept()?
go handle_client(mut socket) go handle_client(mut socket)
} }
} }

View File

@ -14,21 +14,21 @@ fn main() {
} }
// create TCP listener // create TCP listener
mut listener := net.listen_tcp(.ip, 'localhost:9001') ? mut listener := net.listen_tcp(.ip, 'localhost:9001')?
defer { defer {
listener.close() or {} listener.close() or {}
} }
addr := listener.addr() ? addr := listener.addr()?
eprintln('Listening on $addr') eprintln('Listening on $addr')
eprintln('Type `stop` to stop the server') eprintln('Type `stop` to stop the server')
// create file descriptor notifier // create file descriptor notifier
mut notifier := notify.new() ? mut notifier := notify.new()?
defer { defer {
notifier.close() or {} notifier.close() or {}
} }
notifier.add(os.stdin().fd, .read) ? notifier.add(os.stdin().fd, .read)?
notifier.add(listener.sock.handle, .read) ? notifier.add(listener.sock.handle, .read)?
for { for {
for event in notifier.wait(time.infinite) { for event in notifier.wait(time.infinite) {

View File

@ -96,5 +96,5 @@ fn main() {
event_fn: event event_fn: event
hide_cursor: true hide_cursor: true
) )
app.tui.run() ? app.tui.run()?
} }

View File

@ -43,5 +43,5 @@ fn main() {
use_alternate_buffer: false use_alternate_buffer: false
) )
println('V term.ui event viewer (press `esc` to exit)\n\n') println('V term.ui event viewer (press `esc` to exit)\n\n')
app.tui.run() ? app.tui.run()?
} }

View File

@ -495,5 +495,5 @@ fn main() {
hide_cursor: true hide_cursor: true
frame_rate: 60 frame_rate: 60
) )
app.tui.run() ? app.tui.run()?
} }

View File

@ -93,5 +93,5 @@ fn main() {
hide_cursor: true hide_cursor: true
frame_rate: 60 frame_rate: 60
) )
app.tui.run() ? app.tui.run()?
} }

View File

@ -125,7 +125,7 @@ fn main() {
app.mouse_pos.x = 40 app.mouse_pos.x = 40
app.mouse_pos.y = 15 app.mouse_pos.y = 15
app.ui.clear() app.ui.clear()
app.ui.run() ? app.ui.run()?
} }
fn frame(x voidptr) { fn frame(x voidptr) {

View File

@ -649,5 +649,5 @@ fn main() {
event_fn: event event_fn: event
capture_events: true capture_events: true
) )
a.tui.run() ? a.tui.run()?
} }

View File

@ -471,5 +471,5 @@ fn main() {
hide_cursor: true hide_cursor: true
frame_rate: 10 frame_rate: 10
) )
app.termui.run() ? app.termui.run()?
} }

View File

@ -9,24 +9,24 @@ for _ in 0 .. 3 {
} }
println('\nMaking dir "v_script_dir".') println('\nMaking dir "v_script_dir".')
mkdir('v_script_dir') ? mkdir('v_script_dir')?
println("\nEntering into v_script_dir and listing it's files.") println("\nEntering into v_script_dir and listing it's files.")
chdir('v_script_dir') ? chdir('v_script_dir')?
files := ls('.') or { panic(err) } files := ls('.') or { panic(err) }
println(files) println(files)
println('\nCreating foo.txt') println('\nCreating foo.txt')
create('foo.txt') ? create('foo.txt')?
println('\nFiles:') println('\nFiles:')
again_ls := ls('.') or { panic(err) } again_ls := ls('.') or { panic(err) }
println(again_ls) println(again_ls)
println('\nRemoving foo.txt and v_script_dir') println('\nRemoving foo.txt and v_script_dir')
rm('foo.txt') ? rm('foo.txt')?
chdir('../') ? chdir('../')?
rmdir('v_script_dir') ? rmdir('v_script_dir')?
print('\nDoes v_script_dir still exist? ') print('\nDoes v_script_dir still exist? ')
println(exists('v_script_dir')) println(exists('v_script_dir'))

View File

@ -153,7 +153,7 @@ fn (item_list Item_list) get_file_path() string {
fn (mut item_list Item_list) scan_folder(path string, in_index int) ? { fn (mut item_list Item_list) scan_folder(path string, in_index int) ? {
println('Scanning [$path]') println('Scanning [$path]')
mut folder_list := []string{} mut folder_list := []string{}
lst := os.ls(path) ? lst := os.ls(path)?
// manage the single files // manage the single files
for c, x in lst { for c, x in lst {
@ -171,7 +171,7 @@ fn (mut item_list Item_list) scan_folder(path string, in_index int) ? {
if ext == .zip { if ext == .zip {
item.i_type = .zip item.i_type = .zip
item_list.lst << item item_list.lst << item
item_list.scan_zip(pt, item_list.lst.len - 1) ? item_list.scan_zip(pt, item_list.lst.len - 1)?
continue continue
} }
if is_image(ext) == true { if is_image(ext) == true {
@ -194,7 +194,7 @@ fn (mut item_list Item_list) scan_folder(path string, in_index int) ? {
i_type: .folder i_type: .folder
} }
item_list.lst << item item_list.lst << item
item_list.scan_folder(pt, item_list.lst.len - 1) ? item_list.scan_folder(pt, item_list.lst.len - 1)?
} }
// println(item_list.lst.len) // println(item_list.lst.len)
// println("==================================") // println("==================================")

View File

@ -13,12 +13,12 @@ import szip
fn (mut il Item_list) scan_zip(path string, in_index int) ? { fn (mut il Item_list) scan_zip(path string, in_index int) ? {
println('Scanning ZIP [$path]') println('Scanning ZIP [$path]')
mut zp := szip.open(path, szip.CompressionLevel.no_compression, szip.OpenMode.read_only) ? mut zp := szip.open(path, szip.CompressionLevel.no_compression, szip.OpenMode.read_only)?
n_entries := zp.total() ? n_entries := zp.total()?
// println(n_entries) // println(n_entries)
for index in 0 .. n_entries { for index in 0 .. n_entries {
zp.open_entry_by_index(index) ? zp.open_entry_by_index(index)?
is_dir := zp.is_dir() ? is_dir := zp.is_dir()?
name := zp.name() name := zp.name()
size := zp.size() size := zp.size()
// println("$index ${name} ${size:10} $is_dir") // println("$index ${name} ${size:10} $is_dir")
@ -58,15 +58,15 @@ fn (mut app App) load_texture_from_zip() ?(gfx.Image, int, int) {
} }
app.zip_index = item.container_index app.zip_index = item.container_index
// println("Opening the zip [${item.path}]") // println("Opening the zip [${item.path}]")
app.zip = szip.open(item.path, szip.CompressionLevel.no_compression, szip.OpenMode.read_only) ? app.zip = szip.open(item.path, szip.CompressionLevel.no_compression, szip.OpenMode.read_only)?
} }
// println("Now get the image") // println("Now get the image")
app.zip.open_entry_by_index(item.container_item_index) ? app.zip.open_entry_by_index(item.container_item_index)?
zip_entry_size := int(item.size) zip_entry_size := int(item.size)
app.resize_buf_if_needed(zip_entry_size) app.resize_buf_if_needed(zip_entry_size)
app.zip.read_entry_buf(app.mem_buf, app.mem_buf_size) ? app.zip.read_entry_buf(app.mem_buf, app.mem_buf_size)?
app.zip.close_entry() app.zip.close_entry()
return app.load_texture_from_buffer(app.mem_buf, zip_entry_size) return app.load_texture_from_buffer(app.mem_buf, zip_entry_size)
} }

View File

@ -10,7 +10,7 @@ fn main() {
for _ in 0 .. repeats { for _ in 0 .. repeats {
mut sb := strings.new_builder(blocksize) mut sb := strings.new_builder(blocksize)
for { for {
x := rand.read(blocksize) ? x := rand.read(blocksize)?
for c in x { for c in x {
if c >= `0` && c <= `~` { if c >= `0` && c <= `~` {
sb.write_u8(c) sb.write_u8(c)

View File

@ -17,7 +17,7 @@ fn main() {
mut app := &App{} mut app := &App{}
app.serve_static('/favicon.ico', 'favicon.ico') app.serve_static('/favicon.ico', 'favicon.ico')
// Automatically make available known static mime types found in given directory. // Automatically make available known static mime types found in given directory.
os.chdir(os.dir(os.executable())) ? os.chdir(os.dir(os.executable()))?
app.handle_static('assets', true) app.handle_static('assets', true)
vweb.run(app, port) vweb.run(app, port)
} }

View File

@ -8,7 +8,7 @@ import term
// it connects to the server who will broadcast your messages // it connects to the server who will broadcast your messages
// to all other connected clients // to all other connected clients
fn main() { fn main() {
mut ws := start_client() ? mut ws := start_client()?
println(term.green('client $ws.id ready')) println(term.green('client $ws.id ready'))
println('Write message and enter to send...') println('Write message and enter to send...')
for { for {
@ -16,7 +16,7 @@ fn main() {
if line == '' { if line == '' {
break break
} }
ws.write_string(line) ? ws.write_string(line)?
} }
ws.close(1000, 'normal') or { println(term.red('panicing $err')) } ws.close(1000, 'normal') or { println(term.red('panicing $err')) }
unsafe { unsafe {
@ -25,7 +25,7 @@ fn main() {
} }
fn start_client() ?&websocket.Client { fn start_client() ?&websocket.Client {
mut ws := websocket.new_client('ws://localhost:30000') ? mut ws := websocket.new_client('ws://localhost:30000')?
// mut ws := websocket.new_client('wss://echo.websocket.org:443')? // mut ws := websocket.new_client('wss://echo.websocket.org:443')?
// use on_open_ref if you want to send any reference object // use on_open_ref if you want to send any reference object
ws.on_open(fn (mut ws websocket.Client) ? { ws.on_open(fn (mut ws websocket.Client) ? {

View File

@ -6,7 +6,7 @@ import term
// this server accepts client connections and broadcast all messages to other connected clients // this server accepts client connections and broadcast all messages to other connected clients
fn main() { fn main() {
println('press ctrl-c to quit...') println('press ctrl-c to quit...')
start_server() ? start_server()?
} }
fn start_server() ? { fn start_server() ? {
@ -20,7 +20,7 @@ fn start_server() ? {
return false return false
} }
return true return true
}) ? })?
// on_message_ref, broadcast all incoming messages to all clients except the one sent it // on_message_ref, broadcast all incoming messages to all clients except the one sent it
s.on_message_ref(fn (mut ws websocket.Client, msg &websocket.Message, mut m websocket.Server) ? { s.on_message_ref(fn (mut ws websocket.Client, msg &websocket.Message, mut m websocket.Server) ? {

View File

@ -25,7 +25,7 @@ fn start_server() ? {
return false return false
} }
return true return true
}) ? })?
s.on_message(fn (mut ws websocket.Client, msg &websocket.Message) ? { s.on_message(fn (mut ws websocket.Client, msg &websocket.Message) ? {
ws.write(msg.payload, msg.opcode) or { panic(err) } ws.write(msg.payload, msg.opcode) or { panic(err) }
}) })
@ -41,7 +41,7 @@ fn start_server() ? {
// start_client starts the websocket client, it writes a message to // start_client starts the websocket client, it writes a message to
// the server and prints all the messages received // the server and prints all the messages received
fn start_client() ? { fn start_client() ? {
mut ws := websocket.new_client('ws://localhost:30000') ? mut ws := websocket.new_client('ws://localhost:30000')?
// mut ws := websocket.new_client('wss://echo.websocket.org:443')? // mut ws := websocket.new_client('wss://echo.websocket.org:443')?
// use on_open_ref if you want to send any reference object // use on_open_ref if you want to send any reference object
ws.on_open(fn (mut ws websocket.Client) ? { ws.on_open(fn (mut ws websocket.Client) ? {
@ -64,7 +64,7 @@ fn start_client() ? {
}) })
// you can add any pointer reference to use in callback // you can add any pointer reference to use in callback
// t := TestRef{count: 10} // t := TestRef{count: 10}
// ws.on_message_ref(fn (mut ws websocket.Client, msg &websocket.Message, r &SomeRef)? { // ws.on_message_ref(fn (mut ws websocket.Client, msg &websocket.Message, r &SomeRef) ? {
// // println('type: $msg.opcode payload:\n$msg.payload ref: $r') // // println('type: $msg.opcode payload:\n$msg.payload ref: $r')
// }, &r) // }, &r)
ws.connect() or { println('error on connect: $err') } ws.connect() or { println('error on connect: $err') }

View File

@ -85,15 +85,15 @@ fn find_file(search_paths []string, file string) ?string {
} }
fn patch_atomic(outfile string, infile string) ? { fn patch_atomic(outfile string, infile string) ? {
lines := os.read_file(infile) ?.split('\n') lines := os.read_file(infile)?.split('\n')
outlines := lines.filter(!it.contains('atomic(const atomic&) = delete;')) outlines := lines.filter(!it.contains('atomic(const atomic&) = delete;'))
outtext := outlines.join('\n').replace('#include <bits/atomic_base.h>', '#include "bitsatomicbase.h"') outtext := outlines.join('\n').replace('#include <bits/atomic_base.h>', '#include "bitsatomicbase.h"')
os.write_file(outfile, outtext) ? os.write_file(outfile, outtext)?
} }
fn patch_bitsatomicbase(outfile string, infile string) ? { fn patch_bitsatomicbase(outfile string, infile string) ? {
lines := os.read_file(infile) ?.split('\n') lines := os.read_file(infile)?.split('\n')
outlines := lines.filter(!it.contains('__atomic_base(const __atomic_base&) = delete;')) outlines := lines.filter(!it.contains('__atomic_base(const __atomic_base&) = delete;'))
outtext := outlines.join('\n').replace('#include <bits/atomic_base.h>', '#include "bitsatomicbase.h"') outtext := outlines.join('\n').replace('#include <bits/atomic_base.h>', '#include "bitsatomicbase.h"')
os.write_file(outfile, outtext) ? os.write_file(outfile, outtext)?
} }

View File

@ -5,21 +5,21 @@ Hello,
In this guide, we'll build a simple web blog in V. In this guide, we'll build a simple web blog in V.
The benefits of using V for web: The benefits of using V for web:
- A safe, fast, language with the development agility of Python or Ruby and - A safe, fast, language with the development agility of Python or Ruby and
the performance of C. the performance of C.
- Zero dependencies: everything you need for web development comes with the language - Zero dependencies: everything you need for web development comes with the language
in a 1 MB package. in a 1 MB package.
- Very small resulting binaries: the blog we'll create in this tutorial is about 150 KB. - Very small resulting binaries: the blog we'll create in this tutorial is about 150 KB.
- Easy deployments: a single binary file that even includes the precompiled templates. - Easy deployments: a single binary file that even includes the precompiled templates.
- Runs on the cheapest hardware with minimum footprint: for most apps a $3 instance - Runs on the cheapest hardware with minimum footprint: for most apps a $3 instance
is enough. is enough.
- Fast development without any boilerplate. - Fast development without any boilerplate.
*Please note that V and Vweb are at a very early stage and are changing rapidly.* _Please note that V and Vweb are at a very early stage and are changing rapidly._
The code is available <a href='https://github.com/vlang/v/tree/master/tutorials/code/blog'>here</a>. The code is available <a href='https://github.com/vlang/v/tree/master/tutorials/code/blog'>here</a>.
### Installing V ### Installing V
``` ```
@ -32,17 +32,15 @@ sudo ./v symlink
Now V should be globally available on your system. Now V should be globally available on your system.
> On macOS use `v_macos.zip`, on Windows - `v_windows.zip`. > On macOS use `v_macos.zip`, on Windows - `v_windows.zip`.
If you use a BSD system, Solaris, Android, or simply want to install V > If you use a BSD system, Solaris, Android, or simply want to install V
from source, follow the simple instructions here: > from source, follow the simple instructions here:
https://github.com/vlang/v#installing-v-from-source > https://github.com/vlang/v#installing-v-from-source
### Install SQLite development dependency ### Install SQLite development dependency
If you don't have it already installed, look at the If you don't have it already installed, look at the
[`sqlite` README](../../vlib/sqlite/README.md) for instructions. [`sqlite` README](../../vlib/sqlite/README.md) for instructions.
### Creating a new Vweb project ### Creating a new Vweb project
V projects can be created anywhere and don't need to have a certain structure: V projects can be created anywhere and don't need to have a certain structure:
@ -94,7 +92,6 @@ with an MVC web framework, you can think of it as a controller. (Vweb is
not an MVC framework however.) It embeds the vweb Context object, that's why we get access not an MVC framework however.) It embeds the vweb Context object, that's why we get access
to methods like `.text()`. to methods like `.text()`.
As you can see, there are no routing rules. The `index()` action handles the `/` request by default. As you can see, there are no routing rules. The `index()` action handles the `/` request by default.
Vweb often uses convention over configuration and adding a new action requires Vweb often uses convention over configuration and adding a new action requires
no routing rules either: no routing rules either:
@ -109,29 +106,27 @@ fn (mut app App) time() vweb.Result {
} }
``` ```
<img width=662 src="https://github.com/vlang/v/blob/master/tutorials/building_a_simple_web_blog_with_vweb/img/time.png?raw=true"> <img width=662 src="https://github.com/vlang/v/blob/master/tutorials/building_a_simple_web_blog_with_vweb/img/time.png?raw=true">
>TIP: run the following command to live-reload the server: `v watch run blog.v` > TIP: run the following command to live-reload the server: `v watch run blog.v`
The `.text(string)` method returns a plain text document with the provided The `.text(string)` method returns a plain text document with the provided
text, which isn't frequently used in websites. text, which isn't frequently used in websites.
### HTML View ### HTML View
Let's return an HTML view instead. Create `index.html` in the same directory: Let's return an HTML view instead. Create `index.html` in the same directory:
```html ```html
<html> <html>
<head> <head>
<title>V Blog</title> <title>V Blog</title>
</head> </head>
<body> <body>
<b>@message</b> <b>@message</b>
<br> <br />
<img src='https://vlang.io/img/v-logo.png' width=100> <img src="https://vlang.io/img/v-logo.png" width="100" />
</body> </body>
</html> </html>
``` ```
@ -169,14 +164,13 @@ that's done by the `$vweb.html()` line.
(`$` always means compile time actions in V.) offering the following benefits: (`$` always means compile time actions in V.) offering the following benefits:
- Great performance, since the templates don't need to be compiled - Great performance, since the templates don't need to be compiled
on every request, like in almost every major web framework. on every request, like in almost every major web framework.
- Easier deployment, since all your HTML templates are compiled - Easier deployment, since all your HTML templates are compiled
into a single binary file together with the web application itself. into a single binary file together with the web application itself.
- All errors in the templates are guaranteed to be caught during compilation. - All errors in the templates are guaranteed to be caught during compilation.
### Fetching data with V ORM ### Fetching data with V ORM
Now let's display some articles! Now let's display some articles!
@ -184,7 +178,6 @@ Now let's display some articles!
We'll be using V's builtin ORM and a SQLite database. We'll be using V's builtin ORM and a SQLite database.
(V ORM will also support MySQL, Postgre, and SQL Server soon.) (V ORM will also support MySQL, Postgre, and SQL Server soon.)
Add a SQLite handle to `App`: Add a SQLite handle to `App`:
```v oksyntax ```v oksyntax
@ -199,14 +192,11 @@ pub mut:
} }
``` ```
In `fn main()` we'll connect to a database. In `fn main()` we'll connect to a database.
Code in the `main()` function is run only once during app's startup, so we are going Code in the `main()` function is run only once during app's startup, so we are going
to have one DB connection for all requests. This improves the performance of the web application, to have one DB connection for all requests. This improves the performance of the web application,
since a DB connection doesn't have to be set up for each request. since a DB connection doesn't have to be set up for each request.
```v oksyntax ```v oksyntax
// blog.v // blog.v
fn main() { fn main() {
@ -268,17 +258,16 @@ pub fn (app &App) index() vweb.Result {
} }
``` ```
Finally, let's update our view: Finally, let's update our view:
```html ```html
<body> <body>
@for article in articles @for article in articles
<div> <div>
<b>@article.title</b> <br> <b>@article.title</b> <br />
@article.text @article.text
</div> </div>
@end @end
</body> </body>
``` ```
@ -323,23 +312,22 @@ article := app.retrieve_article(10) or {
} }
``` ```
### Adding new articles ### Adding new articles
Create `new.html`: Create `new.html`:
```html ```html
<html> <html>
<head> <head>
<title>V Blog</title> <title>V Blog</title>
</head> </head>
<body> <body>
<form action='/new_article' method='post'> <form action="/new_article" method="post">
<input type='text' placeholder='Title' name='title'> <br> <input type="text" placeholder="Title" name="title" /> <br />
<textarea placeholder='Text' name='text'></textarea> <textarea placeholder="Text" name="text"></textarea>
<input type='submit'> <input type="submit" />
</form> </form>
</body> </body>
</html> </html>
``` ```
@ -373,7 +361,7 @@ not necessary).
We need to update `index.html` to add a link to the "new article" page: We need to update `index.html` to add a link to the "new article" page:
```html ```html
<a href='/new'>New article</a> <a href="/new">New article</a>
``` ```
Next we need to add the HTML endpoint to our code like we did with `index.html`: Next we need to add the HTML endpoint to our code like we did with `index.html`:
@ -387,7 +375,6 @@ pub fn (mut app App) new() vweb.Result {
Re-running this code will now allow us to add new posts to our blog endpoint Re-running this code will now allow us to add new posts to our blog endpoint
### JSON endpoints ### JSON endpoints
This tutorial used the traditional server-side rendering. If you prefer This tutorial used the traditional server-side rendering. If you prefer
@ -406,10 +393,10 @@ pub fn (mut app App) articles() vweb.Result {
} }
``` ```
<img width=662 src="https://github.com/vlang/v/blob/master/tutorials/building_a_simple_web_blog_with_vweb/img/articles_json.png?raw=true"> <img width=662 src="https://github.com/vlang/v/blob/master/tutorials/building_a_simple_web_blog_with_vweb/img/articles_json.png?raw=true">
### Persistent data ### Persistent data
If one wants to persist data they need to use a file instead of memory SQLite Database. If one wants to persist data they need to use a file instead of memory SQLite Database.
Replace the db setup code with this instead: Replace the db setup code with this instead:
@ -422,7 +409,6 @@ If the database file doesn't exist it will create it. The second command will
create the table `Article` if none exists already. Now every time the create the table `Article` if none exists already. Now every time the
app is run you will see the articles created from the previous executions app is run you will see the articles created from the previous executions
To be continued... To be continued...
For an example of a more sophisticated web app written in V, check out Vorum: https://github.com/vlang/vorum For an example of a more sophisticated web app written in V, check out Vorum: https://github.com/vlang/vorum

View File

@ -9,8 +9,8 @@ import arrays
fn main() { fn main() {
a := [1, 5, 7, 0, 9] a := [1, 5, 7, 0, 9]
assert arrays.min(a) ? == 0 assert arrays.min(a)? == 0
assert arrays.max(a) ? == 9 assert arrays.max(a)? == 9
assert arrays.idx_min(a) ? == 3 assert arrays.idx_min(a)? == 3
} }
``` ```

View File

@ -369,7 +369,7 @@ pub fn upper_bound<T>(arr []T, val T) ?T {
// binary search, requires `arr` to be sorted, returns index of found item or error. // binary search, requires `arr` to be sorted, returns index of found item or error.
// Binary searches on sorted lists can be faster than other array searches because at maximum // Binary searches on sorted lists can be faster than other array searches because at maximum
// the algorithm only has to traverse log N elements // the algorithm only has to traverse log N elements
// Example: arrays.binary_search([1, 2, 3, 4], 4) ? // => 3 // Example: arrays.binary_search([1, 2, 3, 4], 4)? // => 3
pub fn binary_search<T>(arr []T, target T) ?int { pub fn binary_search<T>(arr []T, target T) ?int {
mut left := 0 mut left := 0
mut right := arr.len - 1 mut right := arr.len - 1

View File

@ -2,61 +2,61 @@ module arrays
fn test_min() ? { fn test_min() ? {
a := [8, 2, 6, 4] a := [8, 2, 6, 4]
mut ri := min(a) ? mut ri := min(a)?
assert ri == 2 assert ri == 2
ri = min(a[2..]) ? ri = min(a[2..])?
assert ri == 4 assert ri == 4
b := [f32(5.1), 3.1, 1.1, 9.1] b := [f32(5.1), 3.1, 1.1, 9.1]
mut rf := min(b) ? mut rf := min(b)?
assert rf == f32(1.1) assert rf == f32(1.1)
rf = min(b[..2]) ? rf = min(b[..2])?
assert rf == f32(3.1) assert rf == f32(3.1)
c := [u8(4), 9, 3, 1] c := [u8(4), 9, 3, 1]
mut rb := min(c) ? mut rb := min(c)?
assert rb == u8(1) assert rb == u8(1)
rb = min(c[..3]) ? rb = min(c[..3])?
assert rb == u8(3) assert rb == u8(3)
} }
fn test_max() ? { fn test_max() ? {
a := [8, 2, 6, 4] a := [8, 2, 6, 4]
mut ri := max(a) ? mut ri := max(a)?
assert ri == 8 assert ri == 8
ri = max(a[1..]) ? ri = max(a[1..])?
assert ri == 6 assert ri == 6
b := [f32(5.1), 3.1, 1.1, 9.1] b := [f32(5.1), 3.1, 1.1, 9.1]
mut rf := max(b) ? mut rf := max(b)?
assert rf == f32(9.1) assert rf == f32(9.1)
rf = max(b[..3]) ? rf = max(b[..3])?
assert rf == f32(5.1) assert rf == f32(5.1)
c := [u8(4), 9, 3, 1] c := [u8(4), 9, 3, 1]
mut rb := max(c) ? mut rb := max(c)?
assert rb == u8(9) assert rb == u8(9)
rb = max(c[2..]) ? rb = max(c[2..])?
assert rb == u8(3) assert rb == u8(3)
} }
fn test_idx_min() ? { fn test_idx_min() ? {
a := [8, 2, 6, 4] a := [8, 2, 6, 4]
ri := idx_min(a) ? ri := idx_min(a)?
assert ri == 1 assert ri == 1
b := [f32(5.1), 3.1, 1.1, 9.1] b := [f32(5.1), 3.1, 1.1, 9.1]
rf := idx_min(b) ? rf := idx_min(b)?
assert rf == 2 assert rf == 2
c := [u8(4), 9, 3, 1] c := [u8(4), 9, 3, 1]
rb := idx_min(c) ? rb := idx_min(c)?
assert rb == 3 assert rb == 3
} }
fn test_idx_max() ? { fn test_idx_max() ? {
a := [8, 2, 6, 4] a := [8, 2, 6, 4]
ri := idx_max(a) ? ri := idx_max(a)?
assert ri == 0 assert ri == 0
b := [f32(5.1), 3.1, 1.1, 9.1] b := [f32(5.1), 3.1, 1.1, 9.1]
rf := idx_max(b) ? rf := idx_max(b)?
assert rf == 3 assert rf == 3
c := [u8(4), 9, 3, 1] c := [u8(4), 9, 3, 1]
rb := idx_max(c) ? rb := idx_max(c)?
assert rb == 1 assert rb == 1
} }
@ -197,7 +197,7 @@ fn test_concat_string() {
fn test_binary_search() ? { fn test_binary_search() ? {
a := [1, 3, 3, 4, 5, 6, 7, 8, 10] a := [1, 3, 3, 4, 5, 6, 7, 8, 10]
assert binary_search(a, 3) ? == 1 assert binary_search(a, 3)? == 1
assert (binary_search(a, 0) or { -1 }) == -1 assert (binary_search(a, 0) or { -1 }) == -1
} }
@ -205,18 +205,18 @@ fn test_lower_bound() ? {
a := [1, 3, 3, 4, 5, 6, 7, 8, 10] a := [1, 3, 3, 4, 5, 6, 7, 8, 10]
b := []int{} b := []int{}
c := [1, 2, 3] c := [1, 2, 3]
assert lower_bound(a, 2) ? == 3 assert lower_bound(a, 2)? == 3
assert (lower_bound(b, 4) or { -1 }) == -1 assert (lower_bound(b, 4) or { -1 }) == -1
assert lower_bound(c, 3) ? == 3 assert lower_bound(c, 3)? == 3
} }
fn test_upper_bound() ? { fn test_upper_bound() ? {
a := [1, 3, 3, 4, 5, 6, 7, 8, 10] a := [1, 3, 3, 4, 5, 6, 7, 8, 10]
b := []int{} b := []int{}
c := [1, 2, 3] c := [1, 2, 3]
assert upper_bound(a, 9) ? == 8 assert upper_bound(a, 9)? == 8
assert (upper_bound(b, 4) or { -1 }) == -1 assert (upper_bound(b, 4) or { -1 }) == -1
assert upper_bound(c, 2) ? == 2 assert upper_bound(c, 2)? == 2
} }
fn test_rotate_right() { fn test_rotate_right() {

View File

@ -556,7 +556,7 @@ pub fn (b []u8) bytestr() string {
// it will produce an error if there are more than // it will produce an error if there are more than
// four bytes in the array. // four bytes in the array.
pub fn (b []u8) byterune() ?rune { pub fn (b []u8) byterune() ?rune {
r := b.utf8_to_utf32() ? r := b.utf8_to_utf32()?
return rune(r) return rune(r)
} }

View File

@ -40,7 +40,7 @@ fn JS.moveBy(int, int)
fn JS.moveTo(int, int) fn JS.moveTo(int, int)
fn JS.msWriteProfilerMark(string) fn JS.msWriteProfilerMark(string)
// fn JS.open(string, string, string, bool) ?Window // fn JS.open(string, string, string, bool)?Window
// fn JS.postMessage(any, string, []Transferable) // fn JS.postMessage(any, string, []Transferable)
fn JS.print() fn JS.print()
fn JS.prompt(string, string) ?string fn JS.prompt(string, string) ?string

View File

@ -145,15 +145,15 @@ fn test_ranges() {
} }
fn ranges_propagate_first(s string) ?string { fn ranges_propagate_first(s string) ?string {
return s[10..] ? return s[10..]?
} }
fn ranges_propagate_last(s string) ?string { fn ranges_propagate_last(s string) ?string {
return s[..20] ? return s[..20]?
} }
fn ranges_propagate_both(s string) ?string { fn ranges_propagate_both(s string) ?string {
return s[1..20] ? return s[1..20]?
} }
fn test_split_nth() { fn test_split_nth() {

View File

@ -52,7 +52,7 @@ fn test_if_command_has_default_version_subcommand_if_version_is_set() {
} }
fn flag_should_be_set(cmd cli.Command) ? { fn flag_should_be_set(cmd cli.Command) ? {
flag := cmd.flags.get_string('flag') ? flag := cmd.flags.get_string('flag')?
assert flag == 'value' assert flag == 'value'
} }
@ -96,9 +96,9 @@ fn test_if_flag_gets_set_with_long_arg() {
} }
fn flag_should_have_value_of_42(cmd cli.Command) ? { fn flag_should_have_value_of_42(cmd cli.Command) ? {
flag := cmd.flags.get_string('flag') ? flag := cmd.flags.get_string('flag')?
assert flag == 'value' assert flag == 'value'
value := cmd.flags.get_int('value') ? value := cmd.flags.get_int('value')?
assert value == 42 assert value == 42
} }

View File

@ -55,7 +55,7 @@ pub fn (flag Flag) get_bool() ?bool {
// get_bool returns `true` if the flag specified in `name` is set. // get_bool returns `true` if the flag specified in `name` is set.
// get_bool returns an error if the `FlagType` is not boolean. // get_bool returns an error if the `FlagType` is not boolean.
pub fn (flags []Flag) get_bool(name string) ?bool { pub fn (flags []Flag) get_bool(name string) ?bool {
flag := flags.get(name) ? flag := flags.get(name)?
return flag.get_bool() return flag.get_bool()
} }
@ -100,14 +100,14 @@ pub fn (flag Flag) get_ints() ?[]int {
// get_int returns the `int` value argument of the flag specified in `name`. // get_int returns the `int` value argument of the flag specified in `name`.
// get_int returns an error if the `FlagType` is not integer. // get_int returns an error if the `FlagType` is not integer.
pub fn (flags []Flag) get_int(name string) ?int { pub fn (flags []Flag) get_int(name string) ?int {
flag := flags.get(name) ? flag := flags.get(name)?
return flag.get_int() return flag.get_int()
} }
// get_ints returns the array of `int` value argument of the flag specified in `name`. // get_ints returns the array of `int` value argument of the flag specified in `name`.
// get_ints returns an error if the `FlagType` is not integer. // get_ints returns an error if the `FlagType` is not integer.
pub fn (flags []Flag) get_ints(name string) ?[]int { pub fn (flags []Flag) get_ints(name string) ?[]int {
flag := flags.get(name) ? flag := flags.get(name)?
return flag.get_ints() return flag.get_ints()
} }
@ -152,14 +152,14 @@ pub fn (flag Flag) get_floats() ?[]f64 {
// get_float returns the `f64` value argument of the flag specified in `name`. // get_float returns the `f64` value argument of the flag specified in `name`.
// get_float returns an error if the `FlagType` is not floating point. // get_float returns an error if the `FlagType` is not floating point.
pub fn (flags []Flag) get_float(name string) ?f64 { pub fn (flags []Flag) get_float(name string) ?f64 {
flag := flags.get(name) ? flag := flags.get(name)?
return flag.get_float() return flag.get_float()
} }
// get_floats returns the array of `f64` value argument of the flag specified in `name`. // get_floats returns the array of `f64` value argument of the flag specified in `name`.
// get_floats returns an error if the `FlagType` is not floating point. // get_floats returns an error if the `FlagType` is not floating point.
pub fn (flags []Flag) get_floats(name string) ?[]f64 { pub fn (flags []Flag) get_floats(name string) ?[]f64 {
flag := flags.get(name) ? flag := flags.get(name)?
return flag.get_floats() return flag.get_floats()
} }
@ -198,14 +198,14 @@ pub fn (flag Flag) get_strings() ?[]string {
// get_string returns the `string` value argument of the flag specified in `name`. // get_string returns the `string` value argument of the flag specified in `name`.
// get_string returns an error if the `FlagType` is not string. // get_string returns an error if the `FlagType` is not string.
pub fn (flags []Flag) get_string(name string) ?string { pub fn (flags []Flag) get_string(name string) ?string {
flag := flags.get(name) ? flag := flags.get(name)?
return flag.get_string() return flag.get_string()
} }
// get_strings returns the `string` value argument of the flag specified in `name`. // get_strings returns the `string` value argument of the flag specified in `name`.
// get_strings returns an error if the `FlagType` is not string. // get_strings returns an error if the `FlagType` is not string.
pub fn (flags []Flag) get_strings(name string) ?[]string { pub fn (flags []Flag) get_strings(name string) ?[]string {
flag := flags.get(name) ? flag := flags.get(name)?
return flag.get_strings() return flag.get_strings()
} }
@ -214,7 +214,7 @@ pub fn (flags []Flag) get_strings(name string) ?[]string {
fn (mut flag Flag) parse(args []string, posix_mode bool) ?[]string { fn (mut flag Flag) parse(args []string, posix_mode bool) ?[]string {
if flag.matches(args, posix_mode) { if flag.matches(args, posix_mode) {
if flag.flag == .bool { if flag.flag == .bool {
new_args := flag.parse_bool(args) ? new_args := flag.parse_bool(args)?
return new_args return new_args
} else { } else {
if flag.value.len > 0 && flag.flag != .int_array && flag.flag != .float_array if flag.value.len > 0 && flag.flag != .int_array && flag.flag != .float_array
@ -222,7 +222,7 @@ fn (mut flag Flag) parse(args []string, posix_mode bool) ?[]string {
return error('The argument `$flag.name` accept only one value!') return error('The argument `$flag.name` accept only one value!')
} }
new_args := flag.parse_raw(args) ? new_args := flag.parse_raw(args)?
return new_args return new_args
} }
} else { } else {

View File

@ -10,8 +10,8 @@ import compress.zlib
fn main() { fn main() {
uncompressed := 'Hello world!' uncompressed := 'Hello world!'
compressed := zlib.compress(uncompressed.bytes()) ? compressed := zlib.compress(uncompressed.bytes())?
decompressed := zlib.decompress(compressed) ? decompressed := zlib.decompress(compressed)?
assert decompressed == uncompressed.bytes() assert decompressed == uncompressed.bytes()
} }
``` ```

View File

@ -9,7 +9,7 @@ fn C.tdefl_compress_mem_to_heap(source_buf voidptr, source_buf_len usize, out_le
fn C.tinfl_decompress_mem_to_heap(source_buf voidptr, source_buf_len usize, out_len &usize, flags int) voidptr fn C.tinfl_decompress_mem_to_heap(source_buf voidptr, source_buf_len usize, out_len &usize, flags int) voidptr
// compresses an array of bytes using zlib and returns the compressed bytes in a new array // compresses an array of bytes using zlib and returns the compressed bytes in a new array
// Example: compressed := zlib.compress(b) ? // Example: compressed := zlib.compress(b)?
[manualfree] [manualfree]
pub fn compress(data []u8) ?[]u8 { pub fn compress(data []u8) ?[]u8 {
if u64(data.len) > zlib.max_size { if u64(data.len) > zlib.max_size {
@ -36,7 +36,7 @@ pub fn compress(data []u8) ?[]u8 {
} }
// decompresses an array of bytes using zlib and returns the decompressed bytes in a new array // decompresses an array of bytes using zlib and returns the decompressed bytes in a new array
// Example: decompressed := zlib.decompress(b) ? // Example: decompressed := zlib.decompress(b)?
[manualfree] [manualfree]
pub fn decompress(data []u8) ?[]u8 { pub fn decompress(data []u8) ?[]u8 {
mut out_len := usize(0) mut out_len := usize(0)

View File

@ -2,7 +2,7 @@ module zlib
fn test_zlib() ? { fn test_zlib() ? {
uncompressed := 'Hello world!' uncompressed := 'Hello world!'
compressed := compress(uncompressed.bytes()) ? compressed := compress(uncompressed.bytes())?
decompressed := decompress(compressed) ? decompressed := decompress(compressed)?
assert decompressed == uncompressed.bytes() assert decompressed == uncompressed.bytes()
} }

View File

@ -171,7 +171,7 @@ fn parent_cancel_context(mut parent Context) ?&CancelContext {
if done.closed { if done.closed {
return none return none
} }
mut p := parent.value(cancel_context_key) ? mut p := parent.value(cancel_context_key)?
match mut p { match mut p {
CancelContext { CancelContext {
pdone := p.done() pdone := p.done()

View File

@ -21,7 +21,7 @@ import crypto.rand
fn main() { fn main() {
// remember to save this key somewhere if you ever want to decrypt your data // remember to save this key somewhere if you ever want to decrypt your data
key := rand.bytes(32) ? key := rand.bytes(32)?
println('KEY: $key') println('KEY: $key')
// this data is one block (16 bytes) big // this data is one block (16 bytes) big

View File

@ -62,7 +62,7 @@ pub fn (priv PrivateKey) sign(message []u8) ?[]u8 {
// sign`signs the message with privatekey and returns a signature // sign`signs the message with privatekey and returns a signature
pub fn sign(privatekey PrivateKey, message []u8) ?[]u8 { pub fn sign(privatekey PrivateKey, message []u8) ?[]u8 {
mut signature := []u8{len: ed25519.signature_size} mut signature := []u8{len: ed25519.signature_size}
sign_generic(mut signature, privatekey, message) ? sign_generic(mut signature, privatekey, message)?
return signature return signature
} }
@ -74,31 +74,31 @@ fn sign_generic(mut signature []u8, privatekey []u8, message []u8) ? {
mut h := sha512.sum512(seed) mut h := sha512.sum512(seed)
mut s := edwards25519.new_scalar() mut s := edwards25519.new_scalar()
s.set_bytes_with_clamping(h[..32]) ? s.set_bytes_with_clamping(h[..32])?
mut prefix := h[32..] mut prefix := h[32..]
mut mh := sha512.new() mut mh := sha512.new()
mh.write(prefix) ? mh.write(prefix)?
mh.write(message) ? mh.write(message)?
mut msg_digest := []u8{cap: sha512.size} mut msg_digest := []u8{cap: sha512.size}
msg_digest = mh.sum(msg_digest) msg_digest = mh.sum(msg_digest)
mut r := edwards25519.new_scalar() mut r := edwards25519.new_scalar()
r.set_uniform_bytes(msg_digest) ? r.set_uniform_bytes(msg_digest)?
mut rr := edwards25519.Point{} mut rr := edwards25519.Point{}
rr.scalar_base_mult(mut r) rr.scalar_base_mult(mut r)
mut kh := sha512.new() mut kh := sha512.new()
kh.write(rr.bytes()) ? kh.write(rr.bytes())?
kh.write(publickey) ? kh.write(publickey)?
kh.write(message) ? kh.write(message)?
mut hram_digest := []u8{cap: sha512.size} mut hram_digest := []u8{cap: sha512.size}
hram_digest = kh.sum(hram_digest) hram_digest = kh.sum(hram_digest)
mut k := edwards25519.new_scalar() mut k := edwards25519.new_scalar()
k.set_uniform_bytes(hram_digest) ? k.set_uniform_bytes(hram_digest)?
mut ss := edwards25519.new_scalar() mut ss := edwards25519.new_scalar()
ss.multiply_add(k, s, r) ss.multiply_add(k, s, r)
@ -118,21 +118,21 @@ pub fn verify(publickey PublicKey, message []u8, sig []u8) ?bool {
} }
mut aa := edwards25519.Point{} mut aa := edwards25519.Point{}
aa.set_bytes(publickey) ? aa.set_bytes(publickey)?
mut kh := sha512.new() mut kh := sha512.new()
kh.write(sig[..32]) ? kh.write(sig[..32])?
kh.write(publickey) ? kh.write(publickey)?
kh.write(message) ? kh.write(message)?
mut hram_digest := []u8{cap: sha512.size} mut hram_digest := []u8{cap: sha512.size}
hram_digest = kh.sum(hram_digest) hram_digest = kh.sum(hram_digest)
mut k := edwards25519.new_scalar() mut k := edwards25519.new_scalar()
k.set_uniform_bytes(hram_digest) ? k.set_uniform_bytes(hram_digest)?
mut ss := edwards25519.new_scalar() mut ss := edwards25519.new_scalar()
ss.set_canonical_bytes(sig[32..]) ? ss.set_canonical_bytes(sig[32..])?
// [S]B = R + [k]A --> [k](-A) + [S]B = R // [S]B = R + [k]A --> [k](-A) + [S]B = R
mut minus_a := edwards25519.Point{} mut minus_a := edwards25519.Point{}
@ -145,7 +145,7 @@ pub fn verify(publickey PublicKey, message []u8, sig []u8) ?bool {
// generate_key generates a public/private key pair entropy using `crypto.rand`. // generate_key generates a public/private key pair entropy using `crypto.rand`.
pub fn generate_key() ?(PublicKey, PrivateKey) { pub fn generate_key() ?(PublicKey, PrivateKey) {
mut seed := rand.bytes(ed25519.seed_size) ? mut seed := rand.bytes(ed25519.seed_size)?
privatekey := new_key_from_seed(seed) privatekey := new_key_from_seed(seed)
mut publickey := []u8{len: ed25519.public_key_size} mut publickey := []u8{len: ed25519.public_key_size}

View File

@ -8,11 +8,11 @@ import crypto.ed25519
fn main() { fn main() {
msg := 'Hello Girl' msg := 'Hello Girl'
publ, priv := ed25519.generate_key() ? publ, priv := ed25519.generate_key()?
m := msg.bytes() m := msg.bytes()
sig := ed25519.sign(priv, m) ? sig := ed25519.sign(priv, m)?
println('=== Message ===') println('=== Message ===')
println('Msg: $msg \nHash: $m') println('Msg: $msg \nHash: $m')
@ -31,7 +31,7 @@ fn main() {
println('signature: R=${sig[0..32].hex()} s=${sig[32..64].hex()}') println('signature: R=${sig[0..32].hex()} s=${sig[32..64].hex()}')
println(' signature (Base64)=${base64.encode(sig)}') println(' signature (Base64)=${base64.encode(sig)}')
rtn := ed25519.verify(publ, m, sig) ? rtn := ed25519.verify(publ, m, sig)?
if rtn { if rtn {
println('Signature verified :$rtn') println('Signature verified :$rtn')

View File

@ -29,20 +29,20 @@ fn (z ZeroReader) read(mut buf []u8) ?int {
fn test_sign_verify() ? { fn test_sign_verify() ? {
// mut zero := ZeroReader{} // mut zero := ZeroReader{}
public, private := ed25519.generate_key() ? public, private := ed25519.generate_key()?
message := 'test message'.bytes() message := 'test message'.bytes()
sig := ed25519.sign(private, message) ? sig := ed25519.sign(private, message)?
res := ed25519.verify(public, message, sig) or { false } res := ed25519.verify(public, message, sig) or { false }
assert res == true assert res == true
wrongmessage := 'wrong message'.bytes() wrongmessage := 'wrong message'.bytes()
res2 := ed25519.verify(public, wrongmessage, sig) ? res2 := ed25519.verify(public, wrongmessage, sig)?
assert res2 == false assert res2 == false
} }
fn test_equal() ? { fn test_equal() ? {
public, private := ed25519.generate_key() ? public, private := ed25519.generate_key()?
assert public.equal(public) == true assert public.equal(public) == true
@ -53,7 +53,7 @@ fn test_equal() ? {
}*/ }*/
assert private.equal(private) == true assert private.equal(private) == true
otherpub, otherpriv := ed25519.generate_key() ? otherpub, otherpriv := ed25519.generate_key()?
assert public.equal(otherpub) == false assert public.equal(otherpub) == false
assert private.equal(otherpriv) == false assert private.equal(otherpriv) == false
@ -174,10 +174,10 @@ fn test_input_from_djb_ed25519_crypto_sign_input_without_syncpool() ? {
lg.fatal('not contains len 5') lg.fatal('not contains len 5')
}*/ }*/
assert parts.len == 5 assert parts.len == 5
privbytes := hex.decode(parts[0]) ? privbytes := hex.decode(parts[0])?
pubkey := hex.decode(parts[1]) ? pubkey := hex.decode(parts[1])?
msg := hex.decode(parts[2]) ? msg := hex.decode(parts[2])?
mut sig := hex.decode(parts[3]) ? mut sig := hex.decode(parts[3])?
assert pubkey.len == public_key_size assert pubkey.len == public_key_size
sig = sig[..signature_size] sig = sig[..signature_size]
@ -185,10 +185,10 @@ fn test_input_from_djb_ed25519_crypto_sign_input_without_syncpool() ? {
copy(mut priv[..], privbytes) copy(mut priv[..], privbytes)
copy(mut priv[32..], pubkey) copy(mut priv[32..], pubkey)
sig2 := ed25519.sign(priv[..], msg) ? sig2 := ed25519.sign(priv[..], msg)?
assert sig == sig2[..] assert sig == sig2[..]
res := ed25519.verify(pubkey, msg, sig2) ? res := ed25519.verify(pubkey, msg, sig2)?
assert res == true assert res == true
priv2 := new_key_from_seed(priv[..32]) priv2 := new_key_from_seed(priv[..32])

View File

@ -188,9 +188,9 @@ fn test_sqrt_ratio() ? {
mut elw := Element{} mut elw := Element{}
mut elg := Element{} mut elg := Element{}
u := elu.set_bytes(hex.decode(tt.u) ?) ? u := elu.set_bytes(hex.decode(tt.u)?)?
v := elv.set_bytes(hex.decode(tt.v) ?) ? v := elv.set_bytes(hex.decode(tt.v)?)?
want := elw.set_bytes(hex.decode(tt.r) ?) ? want := elw.set_bytes(hex.decode(tt.r)?)?
mut got, was_square := elg.sqrt_ratio(u, v) mut got, was_square := elg.sqrt_ratio(u, v)
assert got.equal(want) != 0 assert got.equal(want) != 0
@ -204,9 +204,9 @@ fn test_sqrt_ratio() ? {
fn test_set_bytes_normal() ? { fn test_set_bytes_normal() ? {
for i in 0 .. 15 { for i in 0 .. 15 {
mut el := Element{} mut el := Element{}
mut random_inp := rand.bytes(32) ? mut random_inp := rand.bytes(32)?
el = el.set_bytes(random_inp.clone()) ? el = el.set_bytes(random_inp.clone())?
random_inp[random_inp.len - 1] &= (1 << 7) - 1 random_inp[random_inp.len - 1] &= (1 << 7) - 1
// assert f1(random_inp, el) == true // assert f1(random_inp, el) == true
@ -249,7 +249,7 @@ fn test_set_bytes_from_dalek_test_vectors() ? {
for _, mut tt in tests { for _, mut tt in tests {
b := tt.fe.bytes() b := tt.fe.bytes()
mut el := Element{} mut el := Element{}
mut fe := el.set_bytes(tt.b) ? mut fe := el.set_bytes(tt.b)?
assert b == tt.b assert b == tt.b
assert fe.equal(tt.fe) == 1 assert fe.equal(tt.fe) == 1
@ -280,7 +280,7 @@ fn test_invert() ? {
assert one == r assert one == r
bytes := rand.bytes(32) or { return err } bytes := rand.bytes(32) or { return err }
x.set_bytes(bytes) ? x.set_bytes(bytes)?
xinv.invert(x) xinv.invert(x)
r.multiply(x, xinv) r.multiply(x, xinv)
@ -369,20 +369,20 @@ fn (mut v Element) from_big_integer(n big.Integer) ?Element {
} }
mut bytes, _ := n.bytes() mut bytes, _ := n.bytes()
swap_endianness(mut bytes) // SHOULD I SWAP IT? swap_endianness(mut bytes) // SHOULD I SWAP IT?
v.set_bytes(bytes) ? v.set_bytes(bytes)?
return v return v
} }
fn (mut v Element) from_decimal_string(s string) ?Element { fn (mut v Element) from_decimal_string(s string) ?Element {
num := big.integer_from_string(s) ? num := big.integer_from_string(s)?
v = v.from_big_integer(num) ? v = v.from_big_integer(num)?
return v return v
} }
fn test_bytes_big_equivalence() ? { fn test_bytes_big_equivalence() ? {
mut inp := rand.bytes(32) ? mut inp := rand.bytes(32)?
el := Element{} el := Element{}
mut fe := el.generate_element() mut fe := el.generate_element()
mut fe1 := el.generate_element() mut fe1 := el.generate_element()
@ -407,12 +407,12 @@ fn test_bytes_big_equivalence() ? {
fn test_decimal_constants() ? { fn test_decimal_constants() ? {
sqrtm1string := '19681161376707505956807079304988542015446066515923890162744021073123829784752' sqrtm1string := '19681161376707505956807079304988542015446066515923890162744021073123829784752'
mut el := Element{} mut el := Element{}
mut exp := el.from_decimal_string(sqrtm1string) ? mut exp := el.from_decimal_string(sqrtm1string)?
assert sqrt_m1.equal(exp) == 1 assert sqrt_m1.equal(exp) == 1
dstring := '37095705934669439343138083508754565189542113879843219016388785533085940283555' dstring := '37095705934669439343138083508754565189542113879843219016388785533085940283555'
exp = el.from_decimal_string(dstring) ? exp = el.from_decimal_string(dstring)?
mut d := d_const mut d := d_const
assert d.equal(exp) == 1 assert d.equal(exp) == 1

View File

@ -49,7 +49,7 @@ fn test_bytes_montgomery_sodium() ? {
// crypto_sign_keypair().pubkey // crypto_sign_keypair().pubkey
pubkey := '3bf918ffc2c955dc895bf145f566fb96623c1cadbe040091175764b5fde322c0' pubkey := '3bf918ffc2c955dc895bf145f566fb96623c1cadbe040091175764b5fde322c0'
mut p := Point{} mut p := Point{}
p.set_bytes(hex.decode(pubkey) ?) ? p.set_bytes(hex.decode(pubkey)?)?
// crypto_sign_ed25519_pk_to_curve25519(pubkey) // crypto_sign_ed25519_pk_to_curve25519(pubkey)
want := 'efc6c9d0738e9ea18d738ad4a2653631558931b0f1fde4dd58c436d19686dc28' want := 'efc6c9d0738e9ea18d738ad4a2653631558931b0f1fde4dd58c436d19686dc28'
@ -115,7 +115,7 @@ fn fn_cofactor(mut data []u8) bool {
fn test_mult_by_cofactor() ? { fn test_mult_by_cofactor() ? {
mut loworder := Point{} mut loworder := Point{}
mut data := rand.bytes(64) ? mut data := rand.bytes(64)?
assert fn_cofactor(mut data) == true assert fn_cofactor(mut data) == true
} }

View File

@ -20,7 +20,7 @@ const (
fn d_const_generate() ?Element { fn d_const_generate() ?Element {
mut v := Element{} mut v := Element{}
v.set_bytes(edwards25519.d_bytes) ? v.set_bytes(edwards25519.d_bytes)?
return v return v
} }
@ -33,7 +33,7 @@ fn d2_const_generate() ?Element {
// id_point_generate is the point at infinity. // id_point_generate is the point at infinity.
fn id_point_generate() ?Point { fn id_point_generate() ?Point {
mut p := Point{} mut p := Point{}
p.set_bytes(edwards25519.id_bytes) ? p.set_bytes(edwards25519.id_bytes)?
return p return p
} }
@ -41,7 +41,7 @@ fn id_point_generate() ?Point {
// correspondence of this encoding with the values in RFC 8032. // correspondence of this encoding with the values in RFC 8032.
fn generator() ?Point { fn generator() ?Point {
mut p := Point{} mut p := Point{}
p.set_bytes(edwards25519.gen_bytes) ? p.set_bytes(edwards25519.gen_bytes)?
return p return p
} }

View File

@ -96,11 +96,11 @@ fn test_non_canonical_points() ? {
// t.Run(tt.name, func(t *testing.T) { // t.Run(tt.name, func(t *testing.T) {
// p1, err := new(Point).SetBytes(decodeHex(tt.encoding)) // p1, err := new(Point).SetBytes(decodeHex(tt.encoding))
mut p1 := Point{} mut p1 := Point{}
p1.set_bytes(hex.decode(tt.encoding) ?) ? p1.set_bytes(hex.decode(tt.encoding)?)?
// p2, err := new(Point).SetBytes(decodeHex(tt.canonical)) // p2, err := new(Point).SetBytes(decodeHex(tt.canonical))
mut p2 := Point{} mut p2 := Point{}
p2.set_bytes(hex.decode(tt.canonical) ?) ? p2.set_bytes(hex.decode(tt.canonical)?)?
assert p1.equal(p2) == 1 assert p1.equal(p2) == 1
assert p1.bytes() == p2.bytes() assert p1.bytes() == p2.bytes()

View File

@ -1115,7 +1115,7 @@ fn generate_scalar(size int) ?Scalar {
// rand.Read(s.s[:16]) // read random bytes and fill buf // rand.Read(s.s[:16]) // read random bytes and fill buf
// using builtin rand.read([]buf) // using builtin rand.read([]buf)
rand.read(mut s.s[..16]) rand.read(mut s.s[..16])
// buf := rand.read(s.s[..16].len) ? // buf := rand.read(s.s[..16].len)?
// copy(mut s.s[..16], buf) // copy(mut s.s[..16], buf)
/* /*
@ -1132,7 +1132,7 @@ fn generate_scalar(size int) ?Scalar {
// Read generates len(p) random bytes and writes them into p // Read generates len(p) random bytes and writes them into p
// rand.Read(s.s[:16]) // rand.Read(s.s[:16])
rand.read(mut s.s[..16]) rand.read(mut s.s[..16])
// buf := rand.read(s.s[..16].len) ? // buf := rand.read(s.s[..16].len)?
// copy(mut s.s[..16], buf) // copy(mut s.s[..16], buf)
/* /*
@ -1148,7 +1148,7 @@ fn generate_scalar(size int) ?Scalar {
// of being out of the latter range). // of being out of the latter range).
// rand.Read(s.s[:]) // rand.Read(s.s[:])
rand.read(mut s.s[..]) rand.read(mut s.s[..])
// buf := crand.read(s.s.len) ? // buf := crand.read(s.s.len)?
// copy(mut s.s[..], buf) // copy(mut s.s[..], buf)
/* /*
@ -1167,7 +1167,7 @@ type NotZeroScalar = Scalar
fn generate_notzero_scalar(size int) ?NotZeroScalar { fn generate_notzero_scalar(size int) ?NotZeroScalar {
mut s := Scalar{} mut s := Scalar{}
for s == edwards25519.sc_zero { for s == edwards25519.sc_zero {
s = generate_scalar(size) ? s = generate_scalar(size)?
} }
return NotZeroScalar(s) return NotZeroScalar(s)
} }

View File

@ -25,8 +25,8 @@ fn negate_aliasing(mut v Scalar, x Scalar) Scalar {
} }
fn test_check_aliasing_oneargs() ? { fn test_check_aliasing_oneargs() ? {
x := generate_notzero_scalar(10) ? x := generate_notzero_scalar(10)?
mut v := generate_notzero_scalar(10) ? mut v := generate_notzero_scalar(10)?
out := check_aliasing_onearg(negate_aliasing, mut v, x) out := check_aliasing_onearg(negate_aliasing, mut v, x)
assert out == true assert out == true
} }
@ -46,9 +46,9 @@ fn subtract_aliasing(mut v Scalar, x Scalar, y Scalar) Scalar {
fn test_check_aliasing_twoargs() ? { fn test_check_aliasing_twoargs() ? {
fn_with_twoargs := [add_aliasing, multiply_aliasing, subtract_aliasing] fn_with_twoargs := [add_aliasing, multiply_aliasing, subtract_aliasing]
for f in fn_with_twoargs { for f in fn_with_twoargs {
mut v := generate_notzero_scalar(10) ? mut v := generate_notzero_scalar(10)?
x := generate_notzero_scalar(10) ? x := generate_notzero_scalar(10)?
y := generate_notzero_scalar(10) ? y := generate_notzero_scalar(10)?
out := check_aliasing_twoargs(f, mut v, x, y) out := check_aliasing_twoargs(f, mut v, x, y)
assert out == true assert out == true
} }

View File

@ -91,8 +91,8 @@ fn test_scalar_set_canonical_bytes() ? {
fn test_scalar_set_canonical_bytes_round_trip() ? { fn test_scalar_set_canonical_bytes_round_trip() ? {
for i in 0 .. 10 { for i in 0 .. 10 {
mut sc1 := generate_scalar(2) ? mut sc1 := generate_scalar(2)?
mut sc2 := generate_scalar(6) ? mut sc2 := generate_scalar(6)?
sc2.set_canonical_bytes(sc1.bytes()) or { panic(err) } sc2.set_canonical_bytes(sc1.bytes()) or { panic(err) }
assert sc1 == sc2 assert sc1 == sc2
@ -117,14 +117,14 @@ fn test_scalar_set_canonical_bytes_on_noncanonical_value() ? {
fn test_scalar_set_uniform_bytes() ? { fn test_scalar_set_uniform_bytes() ? {
// mod, _ := new(big.Integer).SetString("27742317777372353535851937790883648493", 10) // mod, _ := new(big.Integer).SetString("27742317777372353535851937790883648493", 10)
mut mod := big.integer_from_string('27742317777372353535851937790883648493') ? mut mod := big.integer_from_string('27742317777372353535851937790883648493')?
// mod.Add(mod, new(big.Integer).Lsh(big.NewInt(1), 252)) // mod.Add(mod, new(big.Integer).Lsh(big.NewInt(1), 252))
mod = mod + big.integer_from_i64(1).lshift(252) mod = mod + big.integer_from_i64(1).lshift(252)
mut sc := generate_scalar(100) ? mut sc := generate_scalar(100)?
inp := rand.bytes(64) ? inp := rand.bytes(64)?
sc.set_uniform_bytes(inp[..]) ? sc.set_uniform_bytes(inp[..])?
assert is_reduced(sc) == true assert is_reduced(sc) == true
scbig := bigint_from_le_bytes(sc.s[..]) scbig := bigint_from_le_bytes(sc.s[..])
@ -190,9 +190,9 @@ fn test_scalar_set_bytes_with_clamping() {
} }
fn test_scalar_multiply_distributes_over_add() ? { fn test_scalar_multiply_distributes_over_add() ? {
x := generate_scalar(100) ? x := generate_scalar(100)?
y := generate_scalar(100) ? y := generate_scalar(100)?
z := generate_scalar(100) ? z := generate_scalar(100)?
// Compute t1 = (x+y)*z // Compute t1 = (x+y)*z
mut t1 := Scalar{} mut t1 := Scalar{}

View File

@ -95,7 +95,7 @@ fn test_scalarmult_non_identity_point() ? {
// Check whether p.ScalarMult and q.ScalaBaseMult give the same, // Check whether p.ScalarMult and q.ScalaBaseMult give the same,
// when p and q are originally set to the base point. // when p and q are originally set to the base point.
mut x := generate_scalar(5000) ? mut x := generate_scalar(5000)?
mut p := Point{} mut p := Point{}
mut q := Point{} mut q := Point{}

View File

@ -1,7 +1,7 @@
import crypto.rand import crypto.rand
fn test_reading() ? { fn test_reading() ? {
a := rand.read(32) ? a := rand.read(32)?
// dump(a.hex()) // dump(a.hex())
assert a.len == 32 assert a.len == 32
mut histogram := [256]int{} mut histogram := [256]int{}

View File

@ -20,7 +20,7 @@ pub fn int_u64(max u64) ?u64 {
} }
mut n := u64(0) mut n := u64(0)
for { for {
mut bytes := read(k) ? mut bytes := read(k)?
bytes[0] &= u8(int(u64(1) << b) - 1) bytes[0] &= u8(int(u64(1) << b) - 1)
x := bytes_to_u64(bytes) x := bytes_to_u64(bytes)
n = x[0] n = x[0]

View File

@ -12,16 +12,16 @@ fn test_len() ? {
assert list.len() == 0 assert list.len() == 0
list.push_back(1) list.push_back(1)
assert list.len() == 1 assert list.len() == 1
list.pop_back() ? list.pop_back()?
assert list.len() == 0 assert list.len() == 0
} }
fn test_first() ? { fn test_first() ? {
mut list := DoublyLinkedList<int>{} mut list := DoublyLinkedList<int>{}
list.push_back(1) list.push_back(1)
assert list.first() ? == 1 assert list.first()? == 1
list.push_back(2) list.push_back(2)
assert list.first() ? == 1 assert list.first()? == 1
list = DoublyLinkedList<int>{} list = DoublyLinkedList<int>{}
list.first() or { return } list.first() or { return }
assert false assert false
@ -30,9 +30,9 @@ fn test_first() ? {
fn test_last() ? { fn test_last() ? {
mut list := DoublyLinkedList<int>{} mut list := DoublyLinkedList<int>{}
list.push_back(1) list.push_back(1)
assert list.last() ? == 1 assert list.last()? == 1
list.push_back(2) list.push_back(2)
assert list.last() ? == 2 assert list.last()? == 2
list = DoublyLinkedList<int>{} list = DoublyLinkedList<int>{}
list.last() or { return } list.last() or { return }
assert false assert false
@ -41,11 +41,11 @@ fn test_last() ? {
fn test_push() ? { fn test_push() ? {
mut list := DoublyLinkedList<int>{} mut list := DoublyLinkedList<int>{}
list.push_back(1) list.push_back(1)
assert list.last() ? == 1 assert list.last()? == 1
list.push_back(2) list.push_back(2)
assert list.last() ? == 2 assert list.last()? == 2
list.push_back(3) list.push_back(3)
assert list.last() ? == 3 assert list.last()? == 3
} }
fn test_pop() ? { fn test_pop() ? {
@ -53,10 +53,10 @@ fn test_pop() ? {
list.push_back(1) list.push_back(1)
list.push_back(2) list.push_back(2)
list.push_back(3) list.push_back(3)
assert list.pop_back() ? == 3 assert list.pop_back()? == 3
list.push_back(4) list.push_back(4)
assert list.pop_back() ? == 4 assert list.pop_back()? == 4
assert list.pop_back() ? == 2 assert list.pop_back()? == 2
list = DoublyLinkedList<int>{} list = DoublyLinkedList<int>{}
list.pop_back() or { return } list.pop_back() or { return }
assert false assert false
@ -67,10 +67,10 @@ fn test_pop_front() ? {
list.push_back(1) list.push_back(1)
list.push_back(2) list.push_back(2)
list.push_back(3) list.push_back(3)
assert list.pop_front() ? == 1 assert list.pop_front()? == 1
list.push_back(4) list.push_back(4)
assert list.pop_front() ? == 2 assert list.pop_front()? == 2
assert list.pop_front() ? == 3 assert list.pop_front()? == 3
list = DoublyLinkedList<int>{} list = DoublyLinkedList<int>{}
list.pop_front() or { return } list.pop_front() or { return }
assert false assert false
@ -82,14 +82,14 @@ fn test_insert() ? {
list.push_back(2) list.push_back(2)
list.push_back(3) list.push_back(3)
// [1, 2, 3] // [1, 2, 3]
list.insert(1, 111) ? list.insert(1, 111)?
// [1, 111, 2, 3] // [1, 111, 2, 3]
list.insert(3, 222) ? list.insert(3, 222)?
// [1, 111, 2, 222, 3] // [1, 111, 2, 222, 3]
assert list.pop_back() ? == 3 assert list.pop_back()? == 3
assert list.pop_back() ? == 222 assert list.pop_back()? == 222
assert list.pop_front() ? == 1 assert list.pop_front()? == 1
assert list.pop_front() ? == 111 assert list.pop_front()? == 111
} }
fn test_push_front() ? { fn test_push_front() ? {
@ -98,7 +98,7 @@ fn test_push_front() ? {
list.push_back(2) list.push_back(2)
list.push_back(3) list.push_back(3)
list.push_front(111) list.push_front(111)
assert list.first() ? == 111 assert list.first()? == 111
} }
fn test_delete() ? { fn test_delete() ? {
@ -107,12 +107,12 @@ fn test_delete() ? {
list.push_back(1) list.push_back(1)
list.push_back(2) list.push_back(2)
list.delete(1) list.delete(1)
assert list.first() ? == 0 assert list.first()? == 0
assert list.last() ? == 2 assert list.last()? == 2
assert list.len() == 2 assert list.len() == 2
list.delete(1) list.delete(1)
assert list.first() ? == 0 assert list.first()? == 0
assert list.last() ? == 0 assert list.last()? == 0
assert list.len() == 1 assert list.len() == 1
list.delete(0) list.delete(0)
assert list.len() == 0 assert list.len() == 0
@ -147,7 +147,7 @@ fn test_index() ? {
} }
for i := 0; i < 10; i++ { for i := 0; i < 10; i++ {
assert list.index(i * 10) ? == i assert list.index(i * 10)? == i
} }
} }

View File

@ -17,7 +17,7 @@ fn default_setup() (MyReceiver, fsm.StateMachine) {
fn test_statemachine_number_of_callbacks_correct_when_single_transition() ? { fn test_statemachine_number_of_callbacks_correct_when_single_transition() ? {
mut receiver, mut s := default_setup() mut receiver, mut s := default_setup()
s.run(receiver) ? s.run(receiver)?
assert receiver.data.len == 3 assert receiver.data.len == 3
} }
@ -25,7 +25,7 @@ fn test_statemachine_number_of_callbacks_correct_when_single_transition() ? {
fn test_statemachine_sequence_works_when_typical() ? { fn test_statemachine_sequence_works_when_typical() ? {
mut receiver, mut s := default_setup() mut receiver, mut s := default_setup()
s.run(receiver) ? s.run(receiver)?
assert receiver.data[0] == 'on_state_exit: A -> B' assert receiver.data[0] == 'on_state_exit: A -> B'
assert receiver.data[1] == 'on_state_entry: A -> B' assert receiver.data[1] == 'on_state_entry: A -> B'
@ -36,7 +36,7 @@ fn test_statemachine_works_when_final_state() ? {
mut receiver, mut s := default_setup() mut receiver, mut s := default_setup()
// current state `A`, with a possible transition to `B`: // current state `A`, with a possible transition to `B`:
s.run(receiver) ? // run should not error here s.run(receiver)? // run should not error here
// Note: run will now return error, because for state `B`, // Note: run will now return error, because for state `B`,
// there are no more transitions: // there are no more transitions:

View File

@ -13,7 +13,7 @@ pub fn read_file(file string) ?[]string {
pub fn extract_transitions(line string) ?string { pub fn extract_transitions(line string) ?string {
mut result := ' ' mut result := ' '
first_comma := line.index(',') ? first_comma := line.index(',')?
second_comma := line.index_after(',', first_comma + 1) second_comma := line.index_after(',', first_comma + 1)
from := line[..first_comma] from := line[..first_comma]
@ -32,11 +32,11 @@ pub fn get_transitions(line string) ?string {
pub fn main() { pub fn main() {
mut fp := flag.new_flag_parser(os.args) mut fp := flag.new_flag_parser(os.args)
file := fp.string('file', `f`, '', 'input V file with transitions to generate graph from.') file := fp.string('file', `f`, '', 'input V file with transitions to generate graph from.')
lines := read_file(file) ? lines := read_file(file)?
println('digraph fsm {') println('digraph fsm {')
for line in lines { for line in lines {
if line.contains('add_transition') { if line.contains('add_transition') {
println(get_transitions(line) ?) println(get_transitions(line)?)
} }
} }

View File

@ -8,11 +8,11 @@ fn test_min_heap() ? {
heap.insert(4) heap.insert(4)
heap.insert(1) heap.insert(1)
assert heap.pop() ? == 0 assert heap.pop()? == 0
assert heap.pop() ? == 1 assert heap.pop()? == 1
assert heap.pop() ? == 2 assert heap.pop()? == 2
assert heap.pop() ? == 4 assert heap.pop()? == 4
assert heap.pop() ? == 8 assert heap.pop()? == 8
if _ := heap.pop() { if _ := heap.pop() {
panic('expected none') panic('expected none')
} }
@ -35,11 +35,11 @@ fn test_min_heap_custom() ? {
heap.insert(Item{'foo', 100}) heap.insert(Item{'foo', 100})
heap.insert(Item{'bar', 80}) heap.insert(Item{'bar', 80})
assert heap.pop() ?.data == 'foo' assert heap.pop()?.data == 'foo'
assert heap.pop() ?.data == 'bar' assert heap.pop()?.data == 'bar'
assert heap.pop() ?.data == 'baz' assert heap.pop()?.data == 'baz'
assert heap.pop() ?.data == 'buz' assert heap.pop()?.data == 'buz'
assert heap.pop() ?.data == 'qux' assert heap.pop()?.data == 'qux'
if _ := heap.pop() { if _ := heap.pop() {
panic('expected none') panic('expected none')
} }
@ -56,12 +56,12 @@ fn test_heap_len() ? {
heap.insert(1) heap.insert(1)
assert heap.len() == 5 assert heap.len() == 5
heap.pop() ? heap.pop()?
heap.pop() ? heap.pop()?
heap.pop() ? heap.pop()?
assert heap.len() == 2 assert heap.len() == 2
heap.pop() ? heap.pop()?
heap.pop() ? heap.pop()?
assert heap.len() == 0 assert heap.len() == 0
heap.pop() or {} heap.pop() or {}
assert heap.len() == 0 assert heap.len() == 0

View File

@ -12,16 +12,16 @@ fn test_len() ? {
assert list.len() == 0 assert list.len() == 0
list.push(1) list.push(1)
assert list.len() == 1 assert list.len() == 1
list.pop() ? list.pop()?
assert list.len() == 0 assert list.len() == 0
} }
fn test_first() ? { fn test_first() ? {
mut list := LinkedList<int>{} mut list := LinkedList<int>{}
list.push(1) list.push(1)
assert list.first() ? == 1 assert list.first()? == 1
list.push(2) list.push(2)
assert list.first() ? == 1 assert list.first()? == 1
list = LinkedList<int>{} list = LinkedList<int>{}
list.first() or { return } list.first() or { return }
assert false assert false
@ -30,9 +30,9 @@ fn test_first() ? {
fn test_last() ? { fn test_last() ? {
mut list := LinkedList<int>{} mut list := LinkedList<int>{}
list.push(1) list.push(1)
assert list.last() ? == 1 assert list.last()? == 1
list.push(2) list.push(2)
assert list.last() ? == 2 assert list.last()? == 2
list = LinkedList<int>{} list = LinkedList<int>{}
list.last() or { return } list.last() or { return }
assert false assert false
@ -41,10 +41,10 @@ fn test_last() ? {
fn test_index() ? { fn test_index() ? {
mut list := LinkedList<int>{} mut list := LinkedList<int>{}
list.push(1) list.push(1)
assert list.index(0) ? == 1 assert list.index(0)? == 1
list.push(2) list.push(2)
assert list.index(1) ? == 2 assert list.index(1)? == 2
list.pop() ? list.pop()?
list.index(1) or { return } list.index(1) or { return }
assert false assert false
} }
@ -52,11 +52,11 @@ fn test_index() ? {
fn test_push() ? { fn test_push() ? {
mut list := LinkedList<int>{} mut list := LinkedList<int>{}
list.push(1) list.push(1)
assert list.last() ? == 1 assert list.last()? == 1
list.push(2) list.push(2)
assert list.last() ? == 2 assert list.last()? == 2
list.push(3) list.push(3)
assert list.last() ? == 3 assert list.last()? == 3
} }
fn test_pop() ? { fn test_pop() ? {
@ -64,10 +64,10 @@ fn test_pop() ? {
list.push(1) list.push(1)
list.push(2) list.push(2)
list.push(3) list.push(3)
assert list.pop() ? == 3 assert list.pop()? == 3
list.push(4) list.push(4)
assert list.pop() ? == 4 assert list.pop()? == 4
assert list.pop() ? == 2 assert list.pop()? == 2
list = LinkedList<int>{} list = LinkedList<int>{}
list.pop() or { return } list.pop() or { return }
assert false assert false
@ -78,10 +78,10 @@ fn test_shift() ? {
list.push(1) list.push(1)
list.push(2) list.push(2)
list.push(3) list.push(3)
assert list.shift() ? == 1 assert list.shift()? == 1
list.push(4) list.push(4)
assert list.shift() ? == 2 assert list.shift()? == 2
assert list.shift() ? == 3 assert list.shift()? == 3
list = LinkedList<int>{} list = LinkedList<int>{}
list.shift() or { return } list.shift() or { return }
assert false assert false
@ -102,7 +102,7 @@ fn test_prepend() ? {
list.push(2) list.push(2)
list.push(3) list.push(3)
list.prepend(111) list.prepend(111)
assert list.first() ? == 111 assert list.first()? == 111
} }
fn test_str() ? { fn test_str() ? {

View File

@ -12,16 +12,16 @@ fn test_len() ? {
assert queue.len() == 0 assert queue.len() == 0
queue.push(1) queue.push(1)
assert queue.len() == 1 assert queue.len() == 1
queue.pop() ? queue.pop()?
assert queue.len() == 0 assert queue.len() == 0
} }
fn test_peek() ? { fn test_peek() ? {
mut queue := Queue<int>{} mut queue := Queue<int>{}
queue.push(1) queue.push(1)
assert queue.peek() ? == 1 assert queue.peek()? == 1
queue.push(2) queue.push(2)
assert queue.peek() ? == 1 assert queue.peek()? == 1
queue = Queue<int>{} queue = Queue<int>{}
queue.peek() or { return } queue.peek() or { return }
assert false assert false
@ -30,9 +30,9 @@ fn test_peek() ? {
fn test_last() ? { fn test_last() ? {
mut queue := Queue<int>{} mut queue := Queue<int>{}
queue.push(1) queue.push(1)
assert queue.last() ? == 1 assert queue.last()? == 1
queue.push(2) queue.push(2)
assert queue.last() ? == 2 assert queue.last()? == 2
queue = Queue<int>{} queue = Queue<int>{}
queue.last() or { return } queue.last() or { return }
assert false assert false
@ -41,10 +41,10 @@ fn test_last() ? {
fn test_index() ? { fn test_index() ? {
mut queue := Queue<int>{} mut queue := Queue<int>{}
queue.push(1) queue.push(1)
assert queue.index(0) ? == 1 assert queue.index(0)? == 1
queue.push(2) queue.push(2)
assert queue.index(1) ? == 2 assert queue.index(1)? == 2
queue.pop() ? queue.pop()?
queue.index(1) or { return } queue.index(1) or { return }
assert false assert false
} }
@ -53,7 +53,7 @@ fn test_push() ? {
mut queue := Queue<int>{} mut queue := Queue<int>{}
queue.push(1) queue.push(1)
queue.push(2) queue.push(2)
assert queue.peek() ? == 1 assert queue.peek()? == 1
} }
fn test_pop() ? { fn test_pop() ? {
@ -61,10 +61,10 @@ fn test_pop() ? {
queue.push(1) queue.push(1)
queue.push(2) queue.push(2)
queue.push(3) queue.push(3)
assert queue.pop() ? == 1 assert queue.pop()? == 1
queue.push(4) queue.push(4)
assert queue.pop() ? == 2 assert queue.pop()? == 2
assert queue.pop() ? == 3 assert queue.pop()? == 3
queue = Queue<int>{} queue = Queue<int>{}
queue.pop() or { return } queue.pop() or { return }
assert false assert false

View File

@ -12,16 +12,16 @@ fn test_len() ? {
assert stack.len() == 0 assert stack.len() == 0
stack.push(1) stack.push(1)
assert stack.len() == 1 assert stack.len() == 1
stack.pop() ? stack.pop()?
assert stack.len() == 0 assert stack.len() == 0
} }
fn test_peek() ? { fn test_peek() ? {
mut stack := dt.Stack<int>{} mut stack := dt.Stack<int>{}
stack.push(1) stack.push(1)
assert stack.peek() ? == 1 assert stack.peek()? == 1
stack.push(2) stack.push(2)
assert stack.peek() ? == 2 assert stack.peek()? == 2
stack = dt.Stack<int>{} stack = dt.Stack<int>{}
stack.peek() or { return } stack.peek() or { return }
assert false assert false
@ -30,11 +30,11 @@ fn test_peek() ? {
fn test_push() ? { fn test_push() ? {
mut stack := dt.Stack<int>{} mut stack := dt.Stack<int>{}
stack.push(1) stack.push(1)
assert stack.peek() ? == 1 assert stack.peek()? == 1
stack.push(2) stack.push(2)
assert stack.peek() ? == 2 assert stack.peek()? == 2
stack.push(3) stack.push(3)
assert stack.peek() ? == 3 assert stack.peek()? == 3
} }
fn test_pop() ? { fn test_pop() ? {
@ -42,10 +42,10 @@ fn test_pop() ? {
stack.push(1) stack.push(1)
stack.push(2) stack.push(2)
stack.push(3) stack.push(3)
assert stack.pop() ? == 3 assert stack.pop()? == 3
stack.push(4) stack.push(4)
assert stack.pop() ? == 4 assert stack.pop()? == 4
assert stack.pop() ? == 2 assert stack.pop()? == 2
stack = dt.Stack<int>{} stack = dt.Stack<int>{}
stack.pop() or { return } stack.pop() or { return }
assert false assert false

View File

@ -9,9 +9,9 @@ fn main() {
fn test_encode_int() ? { fn test_encode_int() ? {
a := 0x24 // should be 'd' in base58 a := 0x24 // should be 'd' in base58
assert encode_int(a) ? == 'd' assert encode_int(a)? == 'd'
test_encode_int_walpha() ? test_encode_int_walpha()?
} }
fn test_encode_int_walpha() ? { fn test_encode_int_walpha() ? {
@ -20,14 +20,14 @@ fn test_encode_int_walpha() ? {
panic(@MOD + '.' + @FN + ': this should never happen') panic(@MOD + '.' + @FN + ': this should never happen')
} }
a := 0x24 // should be '_' in base58 with our custom alphabet a := 0x24 // should be '_' in base58 with our custom alphabet
assert encode_int_walpha(a, abc) ? == '_' assert encode_int_walpha(a, abc)? == '_'
} }
fn test_decode_int() ? { fn test_decode_int() ? {
a := 'd' a := 'd'
assert decode_int(a) ? == 0x24 assert decode_int(a)? == 0x24
test_decode_int_walpha() ? test_decode_int_walpha()?
} }
fn test_decode_int_walpha() ? { fn test_decode_int_walpha() ? {
@ -35,7 +35,7 @@ fn test_decode_int_walpha() ? {
panic(@MOD + '.' + @FN + ': this should never happen') panic(@MOD + '.' + @FN + ': this should never happen')
} }
a := '_' a := '_'
assert decode_int_walpha(a, abc) ? == 0x24 assert decode_int_walpha(a, abc)? == 0x24
} }
fn test_encode_string() { fn test_encode_string() {
@ -51,13 +51,13 @@ fn test_encode_string() {
fn test_decode_string() ? { fn test_decode_string() ? {
a := 'TtaR6twpTGu8VpY' a := 'TtaR6twpTGu8VpY'
assert decode(a) ? == 'lorem ipsum' assert decode(a)? == 'lorem ipsum'
abc := new_alphabet('abcdefghij\$lmnopqrstuvwxyz0123456789_ABCDEFGHIJLMNOPQRSTUV') or { abc := new_alphabet('abcdefghij\$lmnopqrstuvwxyz0123456789_ABCDEFGHIJLMNOPQRSTUV') or {
panic(@MOD + '.' + @FN + ': this should never happen') panic(@MOD + '.' + @FN + ': this should never happen')
} }
b := '0P7yfPSL0pQh2L5' b := '0P7yfPSL0pQh2L5'
assert decode_walpha(b, abc) ? == 'lorem ipsum' assert decode_walpha(b, abc)? == 'lorem ipsum'
} }
fn test_fails() ? { fn test_fails() ? {

View File

@ -69,7 +69,7 @@ pub fn new_reader(data string, config ReaderConfig) &Reader {
// read reads a row from the CSV data. // read reads a row from the CSV data.
// If successful, the result holds an array of each column's data. // If successful, the result holds an array of each column's data.
pub fn (mut r Reader) read() ?[]string { pub fn (mut r Reader) read() ?[]string {
l := r.read_record() ? l := r.read_record()?
return l return l
} }
@ -133,7 +133,7 @@ fn (mut r Reader) read_record() ?[]string {
mut i := -1 mut i := -1
for { for {
if need_read { if need_read {
l := r.read_line() ? l := r.read_line()?
if l.len <= 0 { if l.len <= 0 {
if keep_raw { if keep_raw {
line += '\n' line += '\n'

View File

@ -15,24 +15,24 @@ pub fn decode(s string) ?[]u8 {
if hex_str.len == 0 { if hex_str.len == 0 {
return []u8{} return []u8{}
} else if hex_str.len == 1 { } else if hex_str.len == 1 {
return [char2nibble(hex_str[0]) ?] return [char2nibble(hex_str[0])?]
} else if hex_str.len == 2 { } else if hex_str.len == 2 {
n1 := char2nibble(hex_str[0]) ? n1 := char2nibble(hex_str[0])?
n0 := char2nibble(hex_str[1]) ? n0 := char2nibble(hex_str[1])?
return [(n1 << 4) | n0] return [(n1 << 4) | n0]
} }
// calculate the first byte depending on if hex_str.len is odd // calculate the first byte depending on if hex_str.len is odd
mut val := char2nibble(hex_str[0]) ? mut val := char2nibble(hex_str[0])?
if hex_str.len & 1 == 0 { if hex_str.len & 1 == 0 {
val = (val << 4) | char2nibble(hex_str[1]) ? val = (val << 4) | char2nibble(hex_str[1])?
} }
// set cap to hex_str.len/2 rounded up // set cap to hex_str.len/2 rounded up
mut bytes := []u8{len: 1, cap: (hex_str.len + 1) >> 1, init: val} mut bytes := []u8{len: 1, cap: (hex_str.len + 1) >> 1, init: val}
// iterate over every 2 bytes // iterate over every 2 bytes
// the start index depends on if hex_str.len is odd // the start index depends on if hex_str.len is odd
for i := 2 - (hex_str.len & 1); i < hex_str.len; i += 2 { for i := 2 - (hex_str.len & 1); i < hex_str.len; i += 2 {
n1 := char2nibble(hex_str[i]) ? n1 := char2nibble(hex_str[i])?
n0 := char2nibble(hex_str[i + 1]) ? n0 := char2nibble(hex_str[i + 1])?
bytes << (n1 << 4) | n0 bytes << (n1 << 4) | n0
} }
return bytes return bytes

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