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

Compare commits

...

814 Commits

Author SHA1 Message Date
Delyan Angelov
ed2d1286da help: improve v help test 2021-12-20 19:53:39 +02:00
yuyi
460f7c6637 cgen: fix fixed array of interfaces equality (#12908) 2021-12-20 19:09:22 +02:00
yuyi
9f7d71d338 ci: fix ci error of vls build (#12909) 2021-12-20 19:08:22 +02:00
Delyan Angelov
68ada041e6 tests: support VTEST_ONLY_FN=*test_sincos* ./v test . and ./v test -run-only test_sin . 2021-12-20 18:45:04 +02:00
playX
5f0160bf11 js,gg: more work on porting gg to JS backend (#12903) 2021-12-20 16:18:21 +03:00
Delyan Angelov
f81654e3a7 builtin: add s.match_glob(wildcard_pattern) 2021-12-20 14:17:08 +02:00
yuyi
7c85c2ab1f checker: fix error of map selector assign (#12902) 2021-12-20 08:09:15 +02:00
Miccah
d07975335d time: add Duration.str() (#12897)
* time: add str() method to Duration

* add Duration.str tests, move time.infinite to time.v, to be visible to the JS backend

Co-authored-by: Delyan Angelov <delian66@gmail.com>
2021-12-19 19:32:42 +02:00
Delyan Angelov
840a92c14e v.builder: change the default stack size for apps produced by MSVC to 16MB 2021-12-19 18:40:29 +02:00
yuyi
cd0b581445 ast: rename 'table.get_type_symbol()' to 'table.sym()' and more related calls (#12898) 2021-12-19 18:25:18 +02:00
yuyi
c957f59071 cgen: minor cleanup in cgen.v (#12896) 2021-12-19 14:31:04 +02:00
Delyan Angelov
41176c4967 cgen: add bool and complex to c_reserved 2021-12-19 13:44:54 +02:00
Leo Developer
a7019ac86c cgen: fix parallel waiter function generation (#12895) 2021-12-19 13:38:48 +02:00
yuyi
2ab861ef89 cgen: fix generic array of interface method call (fix #12882) (#12888) 2021-12-18 18:08:19 +02:00
yuyi
5e5c78ed37 cgen: minor cleanup of the field order in the Gen struct definition (#12890) 2021-12-18 17:52:33 +02:00
spaceface
de92f819f0 cgen: support closures with any number of parameters of any size on amd64 (#12891) 2021-12-18 17:33:24 +02:00
Benjamin Stigsen
3a504480d9 gg: add draw_arc_empty (#12887) 2021-12-18 12:39:14 +02:00
Sandro Martini
80995f3a2d log: improve logging interface (#12886) 2021-12-18 12:38:43 +02:00
Delyan Angelov
927eecf7c0 ci: retry more return_in_lock_test.v 2021-12-18 10:19:13 +02:00
yuyi
7c255f0ff2 builtin, cgen: fix array of map init with default value (#12885) 2021-12-18 10:07:25 +02:00
ChAoS_UnItY
50d988ebc7 v.parser: forbid unsupported language functions/types in specific backends (#12655) 2021-12-18 10:00:31 +02:00
Benjamin Stigsen
75830f1fe3 gg: add draw_ellipse_filled() + draw_ellipse_empty() APIs (#12869) 2021-12-17 21:19:18 +02:00
pancake
08766da7e8 js: dont use async js_main in '-es5' mode (#12870) 2021-12-17 16:37:19 +02:00
Subhomoy Haldar
4ecdb28f5a tools: add .gitattributes with v init and v new(#12879) 2021-12-17 16:11:19 +02:00
Tim Basel
130d189fce cgen: fix overwriting methods of embedded structs + empty struct for interfaces (#12876) 2021-12-17 15:32:31 +02:00
playX
b482da74e9 gg: move code using C types to c.v files, add js.v files (#12873) 2021-12-17 15:22:09 +02:00
yuyi
66070ec63e cgen: fix error of 'map_a[map_b[key]] += 2' (#12872) 2021-12-17 15:17:08 +02:00
yuyi
c9f6a96936 cgen: fix array of interfaces equality error (#12874) 2021-12-17 14:58:17 +02:00
spaceface
d80dd77adf cgen: support closures on arm32 as well (#12875) 2021-12-17 14:26:24 +02:00
zakuro
e5e3979e45 fmt: fix removal of selective imported types used in type decl (#12868) 2021-12-17 05:20:16 +02:00
zakuro
2f7ac7e407 cgen: fix c error when use reserved keyword as if guard var (#12871) 2021-12-17 04:50:52 +02:00
yuyi
f87f8ec3f7 cgen: fix defer with function variables (fix #12854) (#12866) 2021-12-16 20:58:54 +02:00
Delyan Angelov
5f1eaaf3b1 ci: retry more channel_select_6_test.v 2021-12-16 20:12:40 +02:00
spaceface
c6b902d2b7 cgen: support closures on arm64 (#12863) 2021-12-16 18:02:05 +02:00
spaceface
8a34fb7857 ci: run the full V test suite on arm64 (#12865) 2021-12-16 17:44:21 +02:00
Delyan Angelov
6ff953d936 preludes,builder,cgen: add support for VTEST_RUNNER=tap and -test-runner tap (#12523) 2021-12-16 15:59:46 +02:00
Delyan Angelov
caac89d6ca checker: fix function x is private error in main, for pub const abc = x() in a (sub)module 2021-12-16 12:03:49 +02:00
yuyi
674f99a658 checker: minor clean up in comptime_call() (#12860) 2021-12-16 11:47:47 +03:00
yuyi
d8a333058d checker, cgen: fix generic map with generic type key (#12859) 2021-12-16 09:53:05 +02:00
Delyan Angelov
1261468d8e ci: fix failed windows-msvc task (sokol examples) 2021-12-15 20:18:45 +02:00
Benjamin Stigsen
d90ef1f29f gg: draw_arc fixes (#12827) 2021-12-15 21:17:07 +03:00
yuyi
c44115c67d checker: fix goto label with comptime tmpl (#12853) 2021-12-15 18:48:43 +02:00
Delyan Angelov
2b981b011e ast: fix bug in parsing -Isomething -Danother from #flag and #pkgconfig directives 2021-12-15 17:55:52 +02:00
spaceface
65f12f3217 checker: fix invalid cast warning for flag enums (#12848) 2021-12-15 16:58:25 +02:00
playX
11d2b8b354 js: support -es5 flag (#12846) 2021-12-15 15:47:34 +02:00
Delyan Angelov
df7f2aa8a3 all: support [markused] tags for fns/consts/globals 2021-12-15 14:34:49 +02:00
Delyan Angelov
1a6899e85e cgen: fix building with -no-preludes -no-builtin -skip-unused (part 2) 2021-12-15 13:30:21 +02:00
yuyi
2ce1647ea0 cgen: fix error of embedded struct generating interface_table (#12847) 2021-12-15 13:21:21 +02:00
Delyan Angelov
fa1a7a85f0 cgen: fix building with -no-preludes -no-builtin (part 1) 2021-12-15 12:47:28 +02:00
Larpon
1d41d9daf9 json2: improve readability, add tests utilizing fix #12667 (#12836) 2021-12-15 12:20:05 +02:00
spaceface
5b5d0bbb9c ci: ensure that V can be built on arm64 using tcc (#12841) 2021-12-15 11:17:25 +02:00
spaceface
d13fe7843c v: fix build and failing tests on arm64 (#12840) 2021-12-15 09:00:38 +02:00
yuyi
1c629f4a93 cgen: fix ci error of empty struct init (#12838) 2021-12-15 08:49:30 +02:00
Delyan Angelov
6079448f35 tools: unset VCOLORS before producing reports with v bug 2021-12-14 17:35:03 +02:00
Delyan Angelov
c900dc1053 ci: use -Wno-excess-initializers for clang -cstrict, cleanup cgen 2021-12-14 17:14:45 +02:00
Delyan Angelov
96e9cc62b0 ci: fix clang macos build 2021-12-14 17:06:57 +02:00
Delyan Angelov
70564ae8b2 ci: fix generics test 2021-12-14 17:04:37 +02:00
Delyan Angelov
73e097c1cb Revert "ci: fix clang build error on macos/freebsd"
This reverts commit d7abdd314d.
2021-12-14 16:57:47 +02:00
pancake
a1efde8b10 v: list all js backends in v help build-js (#12835) 2021-12-14 15:42:14 +02:00
Delyan Angelov
d7abdd314d ci: fix clang build error on macos/freebsd 2021-12-14 15:39:08 +02:00
yuyi
eeb7d4a7fd cgen: fix embedded struct init with complex fields (#12831) 2021-12-14 14:55:58 +02:00
Thomas Mangin
99f14a7ead transformer: only enable array optimisation with -prod (#12833) 2021-12-14 13:05:54 +02:00
Delyan Angelov
5365984ef5 ci: use powershell Compress-Archive instead of zip in binary_artifact.yml 2021-12-14 12:20:20 +02:00
Delyan Angelov
2f99022f0f ci: simplify and cleanup binary_artifact.yml 2021-12-14 11:10:46 +02:00
zakuro
eed882950c fmt: remove extra comma of branch instead of parse error (#12814) 2021-12-14 08:14:43 +02:00
yuyi
731015cd9b ci: revert "cgen: fix embedded struct init with complex fields (fix #12823) (#12825)" (#12830)
This reverts commit b4b2a21453.
2021-12-14 08:11:11 +02:00
yuyi
b4b2a21453 cgen: fix embedded struct init with complex fields (fix #12823) (#12825) 2021-12-14 07:15:23 +03:00
Larpon
2a5356670b toml: add as_strings() method to map of Any (#12824) 2021-12-13 21:43:33 +02:00
Benjamin Stigsen
76f6f99bce gg: add draw_ring() (#12817) 2021-12-13 21:03:42 +02:00
Larpon
b1a9bf29db vgret: add support for config via toml and root path (#12821) 2021-12-13 20:58:31 +02:00
playX
cb4c67588c os: add support for signal handling on JS backend (#12818) 2021-12-13 20:18:12 +02:00
yuyi
d5c0bdf954 cgen: clean up interface_table() (#12816) 2021-12-13 13:45:27 +02:00
yuyi
be5823069a cgen: clean up struct_init (#12815) 2021-12-13 13:01:36 +02:00
yuyi
b303588491 cgen: fix struct init with interface field (#12820) 2021-12-13 12:55:46 +02:00
Delyan Angelov
3afbb9e90a all: split all backends into cmd/tools/builders (#12811) 2021-12-12 22:10:43 +03:00
yuyi
57c1faadbe cgen: fix multiple nested embed struct with duplicate field init (#12805) 2021-12-12 19:54:29 +02:00
yuyi
f407d6de02 ast, checker, cgen: fix generics multiple type comptime call (fix #12777) (#12806) 2021-12-12 19:42:40 +02:00
Benjamin Stigsen
ab6e93394f gg: add draw_empty_triangle() (#12804) 2021-12-12 19:41:27 +02:00
Leo Developer
8c1c70db04 checker: fix x.$(field.name) not working outside of $if (#12802) 2021-12-12 03:18:29 +02:00
Delyan Angelov
bf835d47d8 tools: fix v build-examples on windows 2021-12-12 01:20:21 +02:00
Delyan Angelov
79de408ef0 parser,checker: support [generated] module xyz (turns off notices). Use it for infix.v. 2021-12-12 00:58:38 +02:00
Delyan Angelov
9b7a50b1a2 v: split the interpreter to cmd/tools/vinterpret.v 2021-12-12 00:06:44 +02:00
Delyan Angelov
adf353702e v.eval: show sumtype or interface casts return void currently only with -v 2021-12-11 23:45:54 +02:00
Delyan Angelov
23be53e2de tools: build examples/viewer as a project folder 2021-12-11 23:20:08 +02:00
penguindark
d3b769d1bc examples: add an image viewer program (#12797) 2021-12-11 22:18:03 +02:00
Subhomoy Haldar
f0969698e2 cmd: add v bump (#12798) 2021-12-11 22:17:01 +02:00
Leo Developer
2ced182816 cgen: fix order of comptime reflection fields (#12799) 2021-12-11 22:09:47 +02:00
Thomas Mangin
0d0d7323bb transformer: provide direct_memory_access to arrays when safe (#12724) 2021-12-11 21:55:46 +02:00
Delyan Angelov
fe14e2fceb cgen: use c_name() for escaping goto label names too 2021-12-11 19:41:44 +02:00
Wertzui123
9e68a03f94 math: rename small to small_ to prevent C errors (workaround unescaped C labels) (#12796) 2021-12-11 19:35:40 +02:00
Delyan Angelov
24bc2ae406 cgen: add small to c_reserved 2021-12-11 19:14:26 +02:00
Delyan Angelov
cde0cbd5ad ci: fix failing tests-sanitize-address-clang step for vlib/toml/tests/spaced_keys_test.v 2021-12-11 19:03:47 +02:00
Delyan Angelov
b3287f8159 Revert "v.scanner: reduce memory consumption for Scanner.ident_name"
This reverts commit b18cd37e59.
2021-12-11 17:10:01 +02:00
Delyan Angelov
b18cd37e59 v.scanner: reduce memory consumption for Scanner.ident_name 2021-12-11 16:38:20 +02:00
Larpon
ba06eba39c toml: fix implicit allocation overwrite of existing table (#12793) 2021-12-11 15:21:46 +02:00
Leo Developer
9bf777c1ee vfmt: fix eating .zlib in $embed_file('v.png', .zlib) (#12794) 2021-12-11 15:21:26 +02:00
yuyi
7c7cdf8ce7 builtin: clean up array.v (#12784) 2021-12-11 11:17:00 +03:00
Alexander Medvednikov
a58c539ee6 checker: minor fixes 2021-12-11 10:56:37 +03:00
Alexander Medvednikov
19a47abcca checker: split up checker.v: fn.v, if.v, interface.v, match.v, return.v 2021-12-11 10:51:01 +03:00
Alexander Medvednikov
ee6c0a0691 checker: split up checker.v: fn.v, if.v, interface.v, match.v 2021-12-11 10:48:07 +03:00
Larpon
ea1f398f90 ci: add gfx_ci utilizing vgret (#12785) 2021-12-11 10:30:06 +03:00
yuyi
feb12b62dc tests: correct test file name (#12787) 2021-12-11 10:28:44 +03:00
yuyi
ade2a4cd01 cgen: fix multiple embed struct init (#12791) 2021-12-11 10:28:32 +03:00
Alexander Medvednikov
eaf0f9b4c1 checker: split up checker.v: assign.v, orm.v, comptime.v; c2v fixes 2021-12-11 10:23:58 +03:00
yuyi
ed4ecae57d checker: fix notice of eval.infix.v on windows (#12770) 2021-12-10 15:28:32 +02:00
yuyi
9b4329d2f6 ast, checker, cgen: fix interface method with struct embed (#12783) 2021-12-10 14:56:13 +02:00
playX
b116170735 js: add support for Promise.wait() (#12781)
* builtin/js: Change Promise<T,E> to Promise<T>

* js: codegen support for Promise.wait()

* checker: checker support for Promise.wait()
2021-12-10 14:54:20 +02:00
yuyi
7fc9e614a3 ast, parser, checker: fix generic fn in builtin module (#12769) 2021-12-09 21:37:43 +02:00
Larpon
dbe67c688f tools: add a v gret command to aid detecting visual regressions in gg based apps (#12775) 2021-12-09 21:31:55 +02:00
Subhomoy Haldar
4c95127cbc semver: add a Version.str() method with unit tests (#12779) 2021-12-09 21:25:55 +02:00
Alexander Medvednikov
8f9f681e81 checker: move check_types() on top; small c2v fixes 2021-12-09 05:44:41 +03:00
Delyan Angelov
0021fbbaa9 gg: support VGG_STOP_AT_FRAME=120 VGG_SCREENSHOT_FOLDER=. VGG_SCREENSHOT_FRAMES=10,20,30 ./v -d gg_record run examples/gg/bezier_anim.v (#12767) 2021-12-08 22:38:33 +02:00
zakuro
85f3372a32 readline: fix bug that full-width spaces are treated as eof (#12763) 2021-12-08 22:35:21 +02:00
zakuro
7379488cee fmt: fix bug that adds unnecessary module name to generic types (#12758) 2021-12-08 22:33:58 +02:00
yuyi
d88e67a5ec checker: fix const type with raw string literal (#12761) 2021-12-08 22:28:55 +02:00
Larpon
cd96f980cc v complete: add recent additions to cmd/tools, sort list (#12762) 2021-12-08 22:27:07 +02:00
Delyan Angelov
b1622c74b9 net.openssl: fix compilation of vpm.v on FreeBSD 2021-12-08 10:50:24 +02:00
yuyi
e433badcb8 parser, cgen: fix multiple comptime tmpl in one function (#12757) 2021-12-08 11:12:02 +03:00
crthpl
2fbf7fea75 all: initial interpreter code (#12605) 2021-12-08 11:09:10 +03:00
Delyan Angelov
525791fa3a tests: mark semaphore_timed_test.v with vtest retry: 3 2021-12-08 01:09:58 +02:00
penguindark
7a0b63e795 stbi: add image writing functions (#12754) 2021-12-08 00:31:37 +02:00
Ekopalypse
a19dd36473 cgen: ensure the different gdi32 notations are always matched in is_gui_app (#12756) 2021-12-07 22:13:56 +02:00
Jordan Bonecutter
fd4e071621 net.openssl: use a pkgconfig directive, instead of a hardcoded path (#12735) 2021-12-07 22:11:47 +02:00
Delyan Angelov
7bbc70820a tools: make v test vlib and v test-self skip _test.js.v files, when node is not installed 2021-12-07 21:31:29 +02:00
yuyi
c29a3cf6e8 parser: fix (absolute path) error (#12747) 2021-12-07 11:33:53 +02:00
yuyi
f60cf65284 cgen: fix comptime for_in methods call using str_intp (#12746) 2021-12-07 12:12:12 +03:00
playX
1cb06a2de4 js: ast.GoExpr support using promises on JS backend (#12749) 2021-12-07 12:11:54 +03:00
Tim Basel
c23ebec944 parser: support bool values in attributes (#12750) 2021-12-07 12:11:29 +03:00
Delyan Angelov
f86af7237f stbi: add a link_to_libm.c.v helper, to ensure import stbi works always. 2021-12-07 10:16:07 +02:00
Tim Basel
6d14275106 parser: support dot prefix for attributes (#12744) 2021-12-07 01:32:29 +03:00
yuyi
36fbd3c4fa checker: check sumtype as mismatched type (#12743) 2021-12-07 01:31:47 +03:00
Toby Webb
ef16a8ec54 vweb: add json_pretty method (#12745) 2021-12-07 01:31:17 +03:00
Larpon
047f059fb8 examples: use fontstash wrapper calls (#12718) 2021-12-06 23:39:43 +03:00
Delyan Angelov
1cd703d96b fontstash: use #flag darwin -I/usr/local/Cellar/freetype/2.10.2/include/freetype2 2021-12-06 19:08:50 +02:00
Alexander Medvednikov
325e116b7a cgen: 4 byte bool flagg for compatibility with some C software 2021-12-06 12:36:25 +03:00
Toby Webb
09955b7ce8 net.websocket: fix server not listening for IPv4 (#12717) 2021-12-06 11:10:25 +02:00
yuyi
d85111e3dd cgen: fix comptime for_in methods call (#12741) 2021-12-06 10:55:27 +02:00
Delyan Angelov
3ab82a23c5 tools: cleanup the output of V, compiled with -d trace_parser and -d trace_checker 2021-12-06 09:54:53 +02:00
penguindark
89eb5425cd examples: clean file path usage in the examples, move all the fonts in the common assets folder (#12736) 2021-12-06 09:53:46 +02:00
Delyan Angelov
6f5d952d8f tools: implement v ast -t file.v (terse mode) (#12734) 2021-12-06 09:50:44 +02:00
lydiandy
3b7e7c9c46 tools: update vast to latest V (#12733) 2021-12-05 19:45:51 +02:00
Taillook
7d1dec5b44 sync: add sync.ManyTimes (#12729) 2021-12-05 19:44:25 +02:00
yuyi
ae2ae6e6fd cgen: fix match sumtype var aggregate str_intp error (#12732) 2021-12-05 19:21:45 +02:00
Taillook
0c713f6edc sync.once: add Once (#12722) 2021-12-05 18:56:03 +02:00
playX
105d7fcf75 js: support JS.await (#12726) 2021-12-05 13:33:53 +02:00
Delyan Angelov
e4850a007c strings: add Builder.drain_builder/1 utility method 2021-12-05 11:59:18 +02:00
Delyan Angelov
229d2fb667 v.util.timers: improve tracing by supporting -d trace_timers_creation 2021-12-05 11:55:41 +02:00
yuyi
2754368873 ast: correct comments of the find_field_from_embeds (#12723) 2021-12-05 06:21:39 +02:00
Taillook
4b21d3e364 crypto.sha256: add missing documentation of sum (#12716) 2021-12-04 20:16:44 +02:00
penguindark
81a1490e31 builtin: add string.split_any/1 (#12720) 2021-12-04 20:13:40 +02:00
Leo Developer
ace63594bf all: support $embed_file('embed.vv', .zlib) (#12654) 2021-12-04 19:43:19 +02:00
yuyi
0f50ac3260 ast: cleanup struct embeds related methods (#12719) 2021-12-04 18:46:41 +02:00
yuyi
0cb4557a8d ast, checker, cgen: fix nested struct embed method call (#12714) 2021-12-04 14:51:42 +02:00
Delyan Angelov
d59aa14b26 builtin: fix {-7:08b} (interpolation of negative numbers with 0 padding), add tests 2021-12-04 13:11:05 +02:00
Delyan Angelov
89c08c6292 cgen: cleanup the generated code for dump(x) 2021-12-04 11:56:45 +02:00
yuyi
2d43fdb42a ast, checker, cgen: fix nested struct embed error (fix #12659) (#12712) 2021-12-04 11:19:19 +03:00
Larpon
7e6d4ebfe1 toml: add doc string to reflect methods (#12666) 2021-12-03 23:07:44 +02:00
Delyan Angelov
33163238e7 strconv: add a small performance optimisation 2021-12-03 20:14:14 +02:00
yuyi
365b46cad3 cgen: fix match sumtype print var aggregate error (#12667) 2021-12-03 20:00:00 +02:00
Delyan Angelov
4624de6cb5 cgen: support -d no_segfault_handler and -d no_main. Cleanup -d trace_xxx descriptions in CONTRIBUTING.md 2021-12-03 19:01:45 +02:00
Larpon
1d6cc57d9c toml: add reflection method (#12664) 2021-12-03 12:40:46 +02:00
playX
0da7e2f8ab js: make vlib/v/util compile on JS backend (#12660) 2021-12-03 12:25:36 +02:00
Alexander Medvednikov
be5446bfa4 checker: update enum test 2021-12-03 09:07:33 +03:00
Alexander Medvednikov
209747d03e checker: update enum test 2021-12-03 08:43:03 +03:00
Alexander Medvednikov
eca78a2906 checker: allow infix expressions in enum declarations 2021-12-03 07:45:37 +03:00
Delyan Angelov
c4363bc78b builtin: explain and better organise the different cstring_to_vstring/tos/tos_clone/vstring family of conversion functions 2021-12-02 15:46:53 +02:00
yuyi
66a67de8c0 checker, cgen: fix match expr returning optional with error (fix #12556) (#12645) 2021-12-02 12:22:48 +02:00
Larpon
7d0a36dd08 toml: solidify single-line escape validation (#12644) 2021-12-02 12:07:53 +02:00
Larpon
adddac4807 toml: add some meat to README.md (#12649) 2021-12-02 12:01:59 +02:00
Leo Developer
63b0798771 compress: add a new compress.zlib module (#12646) 2021-12-02 12:01:44 +02:00
Larpon
5ab91dd471 toml: support multi-level map keys in arrays-of-tables (#12641) 2021-12-02 11:19:45 +02:00
Larpon
ebfacca252 toml: fix bug in unicode decoding (#12643) 2021-12-02 11:19:12 +02:00
Miccah
799d7b843c net: properly convert IP address C strings to V strings (#12648) 2021-12-02 11:18:14 +02:00
Larpon
9cf7af0c75 toml: add better float validation (#12640) 2021-12-02 11:16:55 +02:00
Ulises Jeremias Cornejo Fandos
f7926ec9a4 vlib/context: add onecontext as submodule (#12549) 2021-12-02 11:15:07 +02:00
yuyi
2144471ce1 cgen: fix generic fn with anon fn in body (#12647) 2021-12-02 10:53:42 +02:00
yuyi
988779846f checker: fix map init with enum keys (#12637) 2021-12-01 18:11:50 +02:00
Larpon
8494e387ec strconv: fix format.md example snippets (#12642) 2021-12-01 17:23:35 +02:00
Delyan Angelov
d7bc2a88f7 builtin: add a non allocating rune.length_in_bytes() method and tests for it 2021-12-01 16:35:13 +02:00
Larpon
b3aedff3f8 toml: convert yaml value checks in iarna test suite (#12629) 2021-12-01 14:43:15 +02:00
pancake
6f297cdfaa js: add missing start_digraph() for the js backend (#12638) 2021-12-01 14:05:18 +02:00
Delyan Angelov
f5d283721e checker: add more string(x) checks, with more detailed replacement suggestions 2021-12-01 11:28:00 +02:00
Delyan Angelov
79cb303a6c sync: improve compatibility with -Wimpure-v 2021-12-01 11:24:51 +02:00
Delyan Angelov
47aa2b1f93 all: fix casting of string(MyString('abc')) and byte(MyByte(123)); improve TypeSymbol handling (#12617) 2021-12-01 09:50:53 +02:00
penguindark
519ca90cfa regex: added default support for long queries (#12635) 2021-12-01 08:38:50 +02:00
Taillook
f86710dcc7 crypto.bcrypt: add doc comments for public bcrypt functions (#12622) 2021-11-30 19:41:59 +02:00
Larpon
6f193c4300 toml: remove obsolete comment from checker (#12626) 2021-11-30 19:40:31 +02:00
yuyi
547f326f33 cgen: cleanup auto_str_methods (#12631) 2021-11-30 19:39:55 +02:00
Thomas Mangin
5e1cd13e39 v help: add build-c help information on how to use brew for libgc (#12633) 2021-11-30 19:39:27 +02:00
Larpon
758ba76d2b toml: update testdata/.gitignore (#12630) 2021-11-30 16:01:20 +02:00
Larpon
5c8e626912 toml: add alexcrichton/toml-rs test suite to CI (#12624) 2021-11-30 15:08:30 +02:00
yuyi
d1b0ce9e0c cgen: fix error of the interface str method (fix #12538) (#12620) 2021-11-30 15:03:44 +02:00
Larpon
7d9028db56 toml: add more checks for table redeclarations (#12615) 2021-11-30 15:01:00 +02:00
Larpon
f50f409ad7 toml: simplify bool keys in scanner and parser (#12625) 2021-11-30 14:26:47 +02:00
pancake
1b691e7612 native: implement for-c and for-in range loops (#12155) 2021-11-30 11:49:30 +02:00
Anton Zavodchikov
05db3533d3 picoev: use net C definitions (#12574) 2021-11-30 11:15:59 +02:00
pancake
8ac7739db8 parser: forbid empty match statements 'match cond.op {else {}}' (#12618) 2021-11-30 09:32:48 +02:00
Delyan Angelov
6749979534 builder: fix the uhm fine module lookup bug (part 1) 2021-11-29 22:54:52 +02:00
Taillook
bbc47562b3 crypto.blowfish: add doc comments for the public API (#12609) 2021-11-29 22:19:52 +02:00
Larpon
14424100e8 toml: comply with BurntSushi @eb989e5 (#12616) 2021-11-29 22:15:22 +02:00
Larpon
83260e5074 docs: add link to shader inclusion example (#12613) 2021-11-29 18:26:32 +02:00
Leo Developer
0f59d88ba6 v.embedfile: make path public (#12614) 2021-11-29 16:32:42 +02:00
playX
ddec89f9ee js,vfmt: fix formatting for JS types; add fetch API (#12608) 2021-11-29 15:32:29 +02:00
yuyi
9825c7e06c ast: fix generic sumtype of alias generic struct (#12611) 2021-11-29 15:12:00 +02:00
Larpon
65e9503556 toml: check for immutable tables (#12612) 2021-11-29 15:10:23 +02:00
Alexander Medvednikov
c14c324125 pref: .o build mode 2021-11-29 05:00:25 +03:00
Delyan Angelov
6d97b0a407 checker: improve checking of a << b, when a and b are numbers (#12589) 2021-11-29 03:48:49 +03:00
ChAoS_UnItY
fe37da31a8 v.transformer: fix string always escaped by transformer (#12603) 2021-11-28 23:53:30 +02:00
yuyi
6d6a23a1c9 checker: remove redundant code of find field with embed (#12600) 2021-11-28 21:31:19 +02:00
Delyan Angelov
87029e5707 encoding.base64: vfmt base64.c.v 2021-11-28 20:37:08 +02:00
Delyan Angelov
31fe02de8c builtin,crypto: fix problems detected by -fsanitize=address,undefined and -fsanitize=memory 2021-11-28 20:35:18 +02:00
Delyan Angelov
b4c52b72cf builtin: change the -d debug_malloc byte pattern to M so it is easier to spot with a plain text terminal. 2021-11-28 19:23:11 +02:00
Leo Developer
9c88317ca6 checker: add a warning if start value is higher than end value (#12602) 2021-11-28 18:46:52 +02:00
Delyan Angelov
5786dd84e6 tests: add a new import_x_json2.v skipped valgrind test 2021-11-28 18:36:05 +02:00
Delyan Angelov
1913de0187 x.json2: fix compilation with -autofree 2021-11-28 18:32:04 +02:00
Larpon
5deb56fc79 docs: add v shader section, add help text (#12594) 2021-11-28 17:17:04 +02:00
Delyan Angelov
969e0dce20 szip: cleanup after tests 2021-11-28 15:30:26 +02:00
Delyan Angelov
dc610a9a80 ci,crypto: fix -cstrict compilation 2021-11-28 15:30:13 +02:00
Larpon
0fc47b50a2 toml: fix date-time and time ms test inconsistency (#12593) 2021-11-28 12:42:32 +02:00
Taillook
783aba4552 vlib/crypto/bcrypt: Add bcrypt (#12595) 2021-11-28 12:40:50 +02:00
Leo Developer
f72d001db5 cgen: fix $embed_file not finding embedded file when using -prod (#12596) 2021-11-28 12:32:05 +02:00
Larpon
1d8ece7ac0 toml: fix, test and optimize nan and inf values (#12592) 2021-11-27 21:26:28 +02:00
Larpon
22043f2df1 toml: fix float checker bug for -0.01 (#12590) 2021-11-27 21:03:26 +02:00
Larpon
d52b62a4f4 toml: improve parsing of bare keys to include - and _ (#12588) 2021-11-27 15:46:05 +02:00
Delyan Angelov
8315e82188 checker: improve naming for .stmts() and c.stmts_ending_with_expression(), add a better explanation for their purpose 2021-11-27 08:09:36 +02:00
Delyan Angelov
deaeffc4db checker: add a check for unused x << y expressions (where x != array) (#12586) 2021-11-27 07:38:35 +02:00
Joe Conigliaro
12585e88e1 checker: remove obsolete/slow const ordering code. close #12544 2021-11-27 05:36:27 +11:00
Larpon
4383cf7de5 toml: add iarna/toml-spec-tests to CI tests (#12583) 2021-11-26 19:15:01 +02:00
pancake
89bab98833 native: implement a working hello world compilation for w64 (#12577) 2021-11-26 19:03:15 +02:00
Larpon
04b030b7ab toml: add 1MB file parsing test to CI (#12582) 2021-11-26 18:11:14 +03:00
Larpon
253e38d9d7 toml: support implicit array of tables key change (#12580) 2021-11-26 15:06:28 +02:00
Delyan Angelov
6299a73e90 builder: prepare for v -b native -os windows run file.v 2021-11-26 12:05:58 +02:00
Sandro Martini
85633fe546 tests: test more edge cases for interfaces (#5292) 2021-11-26 11:10:03 +02:00
yuyi
cf274f262c checker, cgen: fix fn type call of match expr (#12579) 2021-11-26 09:52:20 +02:00
Larpon
a59eabc4ab toml: clean up and improve spaced and dotted key parsing (#12576) 2021-11-25 16:51:54 +02:00
playX
f584e70cf2 js: add fixes for generic structures and functions; add promise API; refactor modules (#12575) 2021-11-25 16:49:53 +02:00
yuyi
ac3910b8c2 checker: merge comptime_const_eval.v and noreturn.v into checker.v (#12573) 2021-11-25 12:41:26 +02:00
Larpon
9a2c563735 toml: add conversion of ast inf and nan to Any (#12567) 2021-11-25 12:33:54 +02:00
Eragon
fb3a793a27 tools: add "skip to content" link for screan reader and tui browsers (#12571) 2021-11-25 02:53:02 +02:00
Larpon
11d70624af toml: streamline value() api (#12568) 2021-11-24 20:39:22 +02:00
Larpon
f825306cff toml: workaround #9507 (#12566) 2021-11-24 20:36:15 +02:00
playX
b0bc112168 jsdom, examples: add more WebGL APIs; add interactive 3D cube example running on VJS (#12562) 2021-11-24 20:31:39 +02:00
Larpon
ff95cf18d4 toml: expand short date time milliseconds in decoder (#12564) 2021-11-24 14:49:23 +02:00
yuyi
6f46fc2170 checker, cgen: fix for_in_mut iterator val (#12563) 2021-11-24 14:43:37 +02:00
Thomas Mangin
cbf4a5b58c docs: fix typos in vscode documentation (#12565)
The task configuration file is tasks.json not task.json
2021-11-24 14:24:36 +02:00
yuyi
43a1d2cfea ast: cleanup table.v (#12561) 2021-11-24 09:56:56 +02:00
pancake
70ff00efbb bootstrapping: fix building V on OpenBSD (#12558) 2021-11-24 09:46:46 +02:00
Ulises Jeremias Cornejo Fandos
ff911986e7 ci: add tasks for checking that vsl and vtl are not broken by updates to V (#12559) 2021-11-24 09:45:13 +02:00
Delyan Angelov
8e0de2036d net: use vmemset(&hints, 0, int(sizeof(hints))), instead of zeroing the fields 1 by 1 2021-11-24 09:34:48 +02:00
yuyi
e42db5bee2 ast: fix vtl compile error of generic array type cname (#12555) 2021-11-23 20:11:51 +02:00
Delyan Angelov
87f7a6d99f ci: update toml_ci.yml's TOML_TESTS_PINNED_COMMIT to 8baf830 2021-11-23 16:59:23 +02:00
Larpon
1be6aed16e toml: support checking and decoding quoted keys (#12552) 2021-11-23 16:59:07 +02:00
Larpon
0779b5fd8e toml: fix implicit array allocation (#12553) 2021-11-23 16:51:24 +02:00
Larpon
49cd1b3d59 toml: make value of +nan/-nan decode to nan (#12542) 2021-11-23 16:23:16 +02:00
playX
12ffe04212 jsdom, builtin/js: WebGL W.I.P; Added support for casting V arrays to typed arrays (#12551)
* builtin/js: TypedArray support

* jsdom: WebGL W.I.P
2021-11-23 14:51:59 +02:00
Larpon
e9efed02f0 toml: fix decoding most large number values (#12541) 2021-11-23 13:23:16 +02:00
Larpon
3f0e532660 toml: fix unicode and escape value decoding (#12534) 2021-11-23 11:02:43 +02:00
yuyi
13a2d547b4 checker: fix vtl compile error (#12550) 2021-11-23 10:55:15 +02:00
zakuro
93bdff5589 fmt: remove unnecessary paren in assert stmt (#12546) 2021-11-23 07:30:54 +02:00
yuyi
fbe2b5cb58 checker: check argument type error of the generics fn declaration (#12539) 2021-11-22 22:39:20 +02:00
Delyan Angelov
bf7074cad4 ci: disable the tcc32 windows tasks for now 2021-11-22 22:05:09 +02:00
Delyan Angelov
83fee01f6e make.bat: add -g flag to improve diagnostics reports on windows 2021-11-22 22:00:14 +02:00
Delyan Angelov
d431145a39 v.util,tools: use os.join_path_single 2021-11-22 21:42:55 +02:00
Delyan Angelov
bd9564e38b ci: fix failing ttf_test.v after making char unavailable for variable names 2021-11-22 18:28:25 +02:00
Delyan Angelov
42b97ef888 ci: add -ladvapi32 for bootstrapping with gcc/clang on windows 2021-11-22 17:07:39 +02:00
Delyan Angelov
278be77c11 ci: use wine64 explicitly in ci_cross.yml 2021-11-22 16:59:21 +02:00
yuyi
f37eb6a932 checker: check invalid fn parameter name (#12540) 2021-11-22 16:51:58 +02:00
Delyan Angelov
6914763493 vc: reduce further the average vc commit diff size 2021-11-22 16:46:28 +02:00
Delyan Angelov
1bbbba5813 ci: improve ci_cross.yml 2021-11-22 16:36:26 +02:00
Delyan Angelov
759f3d28b7 ci: improve diagnostic messages for cloning tcc on windows 2021-11-22 16:24:56 +02:00
Delyan Angelov
5e8288528a ci: fix v -b js vlib/builtin/js/array_test.js.v 2021-11-22 15:11:33 +02:00
Delyan Angelov
6a252ed015 os: implement a JS version of os.join_path_single too 2021-11-22 15:03:05 +02:00
Delyan Angelov
7a0dc60d04 os: re-add the leak in os.join_path (the os.join_path(x, ...arr) case should be handled by V). Add a memleak free os.join_path_single version. 2021-11-22 14:40:55 +02:00
Delyan Angelov
5e1782bf9c tests: add more common patterns of os function usage in the -autofree test import_os_and_use_its_constants.v 2021-11-22 13:37:06 +02:00
Delyan Angelov
c3b8e5e181 ci: fix compilation on FreeBSD 2021-11-22 09:32:13 +00:00
Delyan Angelov
84aa05f8fb ci: fix macos build 2021-11-22 11:07:26 +02:00
Delyan Angelov
fe48380e85 os: cleanup; ci: fix a segfault in the tcc32 job when calling pref.vexe_path() -> os.real_path(os.executable()) 2021-11-22 10:32:10 +02:00
Delyan Angelov
e77a11001e os: make init_os_args_wide (windows), more simillar to the current init_os_args (unix) 2021-11-21 23:04:30 +02:00
Delyan Angelov
c7bd74e0f8 ci: fix build, remove [manualfree] from os.vmodules_paths for now 2021-11-21 22:34:38 +02:00
Delyan Angelov
1aaac13a60 cgen: make os less special, fix an -autofree leak on just import os
* Improve documentation of v.util.Surrounder

* Remove `os` from the list of "no auto free" `builtin` mods

* Fix -autofree freeing of `const x = []string{}`.

* Add a valgrind regression test.

* Implement os.getenv_opt in vlib/os/environment.js.v too.
2021-11-21 21:50:10 +02:00
Delyan Angelov
117c99d938 v.util: add Surrounder.builder_write_befores and Surrounder.builder_write_afters methods for writing to an existing strings.Builder 2021-11-21 20:56:47 +02:00
kahsa
480f3876ee gg: fix system_font_path (#12533) 2021-11-21 19:12:15 +02:00
playX
243e66a106 js,jsdom: Canvas & context API; Added TypeSymbol.is_js_compatible & temporary hacks for JS ifaces (#12526) 2021-11-20 21:28:11 +02:00
Delyan Angelov
258d0d6df7 cgen: make dump(x) use a single write call, fix memleaks for autogenerated .str() methods of nested structs (#12529) 2021-11-20 20:55:19 +02:00
Larpon
f1dd0e3355 toml: add value decoding (#12521) 2021-11-20 19:48:44 +02:00
Larpon
4b9e8e243c toml: support arrays in value key query syntax (#12527) 2021-11-20 19:45:17 +02:00
Ned
82010e729d checker: fix "unregistered" variadic interface call arguments (#12525) 2021-11-20 18:15:20 +02:00
Delyan Angelov
90ba856107 cgen: fix dump(x) with fn (x &Type) str() string { 2021-11-20 13:12:03 +02:00
Delyan Angelov
24ffc1ffb2 os: fix os.rmdir_all for folders with recursive symlinks 2021-11-20 10:28:12 +02:00
Larpon
1bbc73384c toml: fix memory corruption when returning new date/time types (#12507) 2021-11-19 20:35:11 +02:00
Larpon
a894a6cf36 toml: fix parsing of alphanumeric keys (#12517) 2021-11-19 20:34:21 +02:00
yuyi
eec8788333 checker: fix generics fn infer nested generic fn (#12519) 2021-11-19 20:31:55 +02:00
Subhomoy Haldar
2794aa623a tools: include vls.log in the .gitignore files for new V projects (#12522) 2021-11-19 19:23:35 +02:00
Delyan Angelov
b576181a66 cgen: fix const x := opt() or {} side effect interference when the consts are in different files in the same module too 2021-11-19 19:02:33 +02:00
Delyan Angelov
e275220f05 cgen: fix const x := opt() or {} side effect interference with parallel cgen 2021-11-19 18:15:06 +02:00
Delyan Angelov
762a7fde2a os: add os.getenv_opt/1 2021-11-19 17:47:45 +02:00
yuyi
c2eb909c9b cgen: fix multiple matches in one expr (#12516) 2021-11-19 13:52:28 +02:00
pancake
80a4ff9900 native: handle some more statements and dont echo warnings (#12518) 2021-11-19 13:50:44 +02:00
Delyan Angelov
fa995ca537 checker: add an error for x.method({}) calls, when method expects a struct 2021-11-19 13:30:45 +02:00
pancake
9eac656e55 native: support passing a directory, instead of just a .v file (#12512) 2021-11-19 10:30:46 +02:00
Larpon
76cf11e6b5 toml: add Any.default_to() method (#12506) 2021-11-19 10:26:45 +02:00
pancake
b367ed9ba3 native: support defining functions in any order (#12511) 2021-11-19 10:25:42 +02:00
yuyi
d498c365c2 checker: cleanup infer_fn_generic_types() (#12515) 2021-11-19 10:24:03 +02:00
Delyan Angelov
24ba660367 bitfield,flag: document the remaining functions 2021-11-18 20:15:26 +02:00
Larpon
96554fad71 toml: improve number conversion (#12509) 2021-11-18 19:46:19 +02:00
Delyan Angelov
3caeadfa0d cgen,vfmt: support [weak] tags for functions and globals 2021-11-18 18:32:39 +02:00
Larpon
7fba3e65e9 toml: support empty tables (#12504) 2021-11-18 15:39:44 +02:00
Larpon
24ea15c8f0 toml: remove fixed value tests from skip list (#12503) 2021-11-18 13:57:14 +02:00
kahsa
0ec02e3247 sqlite: add enum result code (#12505) 2021-11-18 13:56:15 +02:00
Larpon
7ec70d5477 toml: small refactor, move all json functionality to submodule (#12502) 2021-11-18 13:27:59 +02:00
Alexander Medvednikov
5bf28c5287 cgen: handle c2v fn casts 2021-11-18 11:58:00 +03:00
playX
1edb3e559e js,jsdom: make JS structs plain objects; add more DOM API support for jsdom (#12501) 2021-11-18 10:09:53 +02:00
Larpon
409321327b toml: don't use time.Time for time representation (#12498) 2021-11-18 07:44:24 +02:00
zakuro
b5e410e408 fmt: format explicit map init with parameter (#12499) 2021-11-18 08:34:30 +03:00
Don Park
ae54cd78f5 json2: encode ascii chars < 0x20 in json (#12494) 2021-11-18 08:34:00 +03:00
zakuro
26fbf1885d checker: report error for test functions that have parameters (#12500) 2021-11-18 08:33:28 +03:00
Larpon
3b612899bf toml: eat first nl if present in multiline strings (#12496) 2021-11-17 23:48:29 +02:00
Larpon
81455acd29 toml: simplify Doc.to_any() method (#12495) 2021-11-17 20:58:06 +02:00
Larpon
2f5fae06ee toml: fix a few string value tests (#12493) 2021-11-17 20:54:48 +02:00
Delyan Angelov
2733319879 term: fix a leak in _test.v files in the default test runner without -autofree 2021-11-17 20:39:08 +02:00
Larpon
dbf469e000 toml: move to_burntsushi functionality (#12492) 2021-11-17 17:25:50 +02:00
Larpon
7cdc906683 toml: fix scanning of short unicode escapes (#12491) 2021-11-17 17:24:40 +02:00
yuyi
3e1fb22a04 checker: format checker.v (#12490) 2021-11-17 15:57:17 +02:00
yuyi
1370516f53 checker: check struct field using 'any' type (#12489) 2021-11-17 11:42:05 +02:00
playX
2eb02ff5a7 jsdom, js: start refactoring jsdom; improve JS interfaces; add two attributes for them (#12488) 2021-11-17 11:41:33 +02:00
Delyan Angelov
6ac109a7c3 builtin: add a [has_globals] tag for all the .v files, with global declarations in them 2021-11-17 10:29:06 +02:00
Larpon
bd9ac598f7 toml: add support for validation of structure and values (#12481) 2021-11-17 08:30:40 +02:00
yuyi
5a89c0a480 ast: change CompFor to ComptimeFor (#12482) 2021-11-17 08:29:43 +02:00
yuyi
927df948ae cgen: fix generic struct free() (#12487) 2021-11-17 08:18:46 +03:00
Khalyomede
11ce26b3f6 sqlite: make constants public (#12485) 2021-11-17 05:45:50 +03:00
Alexander Medvednikov
49a36515dc checker, cgen: c2v fixes 2021-11-16 20:56:50 +03:00
yuyi
2984751a57 checker: fix the argument mismatch of fn call (#12479) 2021-11-16 17:19:02 +02:00
Delyan Angelov
3fab0a5d05 cgen: fix codegen for for k,v in map_of_pointers { 2021-11-16 17:03:58 +02:00
Delyan Angelov
045579fd8a parser: use the [has_globals] module attribute, remove the parser global_enabled_mods whitelist (part 2) 2021-11-16 11:44:36 +02:00
Delyan Angelov
f0f5f97e9f parser: support a [has_globals] module attribute, to eliminate a parser whitelist (part 1) 2021-11-16 11:34:26 +02:00
kahsa
3f37ab2ef2 gg: fix system_font_path on Linux (#12477) 2021-11-16 12:14:35 +03:00
yuyi
bede0587ad cgen: fix string interliteral of the comptime selector (#12475) 2021-11-16 08:45:47 +02:00
yuyi
9565adf597 checker: check invalid map variable name (#12474) 2021-11-16 08:42:49 +02:00
Larpon
2f75ce0d4c toml: use json2 to encode output from .to_json() (#12470) 2021-11-16 08:41:37 +02:00
Larpon
7b9cca7524 toml: add convenience convertion of Doc to map[string]toml.Any (#12473) 2021-11-15 19:00:09 +02:00
yuyi
c28041cecc all: cleanup/rename all comp_ names to be comptime_ (#12467) 2021-11-15 15:47:29 +02:00
Charles WANG
1d003228cb tests: update generics_method_str_overload_test.v to return a generic type, instead of Gen<G>. (#12465) 2021-11-15 15:36:54 +02:00
Larpon
cbdb270d2f toml: upgrade the module to 100% BurntSushi test suite parsing compatibility (#12466) 2021-11-15 15:36:14 +02:00
Larpon
78662c800c toml: fix parsing formatting on Windows with crlf line endings (#12468) 2021-11-15 15:35:30 +02:00
playX
a8a1e9381f strconv,js: f64_to_str works on JS backend now; Fix BigInt usage in infix expressions (#12464) 2021-11-15 14:13:44 +02:00
Delyan Angelov
1d2b16dde2 js: support [if userflag?] fn tags 2021-11-15 13:23:27 +02:00
Delyan Angelov
7b723262e4 tools: support VJOBS=1 VTEST_FAIL_FAST=1 ./v test . 2021-11-15 11:44:54 +02:00
zakuro
5e75c89b71 checker: allow noreturn in if expr (#12462) 2021-11-15 10:29:58 +02:00
yuyi
d8479f107f cgen: fix typeof comptime selector (fix #12461) (#12463) 2021-11-15 10:23:49 +02:00
playX
e3d98b1b28 js,strconv: port some functions to JS backend, improve rune.str() (#12460) 2021-11-14 21:06:58 +02:00
yuyi
460f4523aa checker: check array pop immutable (#12458) 2021-11-14 21:00:22 +02:00
yuyi
fb997eb5fe cgen: fix comptime for in field selector (#12457) 2021-11-14 20:58:22 +02:00
Delyan Angelov
61b99e1915 vfmt: handle comments right after interface fields 2021-11-13 13:42:17 +02:00
Larpon
9c508237bd toml: support for [a."b.c"] quoted keys (#12444) 2021-11-13 11:17:35 +02:00
playX
6c32c544e1 js,parser: allow declaring methods on JS interfaces for easier FFI (#12447) 2021-11-13 11:08:17 +02:00
yuyi
3bb1c3f930 checker, cgen: fix for in iterator of generic struct (#12441) 2021-11-12 14:29:01 +02:00
Delyan Angelov
50a608aab3 os: remove unnecessary heap allocation from os.execute 2021-11-12 11:45:37 +02:00
Delyan Angelov
c6b8b0bb0a ci: make test_execute in os_test.v more robust 2021-11-12 11:24:37 +02:00
MrsHerobrine
1c17ba82ac tools: fix the batch script for v symlink, if the vexe path contains spaces on windows (#12443) 2021-11-12 10:29:57 +02:00
Delyan Angelov
fcecf527ec ci: fix failing os_test.v on the CI 2021-11-12 10:27:35 +02:00
Delyan Angelov
20d63de136 os: fix os.execute for command output that contains 0 bytes 2021-11-12 09:39:15 +02:00
Larpon
4b42dcad8e toml: support complex array-tables-array constructs (#12438) 2021-11-11 18:30:34 +02:00
Delyan Angelov
6c5dfc5c2f examples: fix initial clock size on hdpi displays 2021-11-11 18:09:57 +02:00
Delyan Angelov
4728b975e3 examples: use app.gg.quit() instead of exit(0) 2021-11-11 17:45:22 +02:00
Delyan Angelov
9cb378bb6b examples: reduce the memory usage of the clock example, without -autofree & -gc boehm 2021-11-11 17:39:02 +02:00
Larpon
c8cb1bf6b4 toml: check for single-key reassignment in inline tables (#12436) 2021-11-11 14:57:11 +02:00
Larpon
35f00c9f91 toml: check for text after comma in arrays (#12435) 2021-11-11 14:55:51 +02:00
yuyi
6f55439930 tests: supplement tests for different types of generic parameters (#12432) 2021-11-11 14:45:55 +02:00
playX
a4c57ba56e js: support JS interfaces (#12426) 2021-11-11 14:36:32 +02:00
Larpon
015cfdb49f toml: add excerpt to value parse errors (#12429) 2021-11-11 07:29:38 +02:00
Larpon
dbd5acd5ba toml: small start -> end word use change (#12428) 2021-11-11 07:28:46 +02:00
Larpon
69fa87ad24 toml: add date and time checks (#12427) 2021-11-11 07:27:41 +02:00
zakuro
823a3ab838 fmt: fix removal of selective imported types used as type parameter (#12431) 2021-11-11 07:15:30 +02:00
yuyi
72a7d5a559 checker: minor cleanup in method_call (#12430) 2021-11-11 07:12:59 +02:00
Delyan Angelov
8a971c3bf7 ci,vweb: fix hard coded data in vweb_test.v 2021-11-10 18:41:25 +02:00
Delyan Angelov
637ebe5d42 examples: improve examples/vweb/file_upload 2021-11-10 18:26:16 +02:00
Delyan Angelov
3c6356ba36 ci: fix request_test.v (add missing \r to hardcoded post data) 2021-11-10 18:16:15 +02:00
Delyan Angelov
466ced2876 net.http: fix multipart/form-data file upload handling 2021-11-10 17:31:41 +02:00
Larpon
66e53279c2 toml: check for more wrong line ending cases (#12424) 2021-11-10 15:03:51 +02:00
yuyi
d5e767f389 checker, cgen: fix alias of map keys() (#12422) 2021-11-10 13:04:59 +02:00
playX
194b3647e2 js,checker: allow casting JS primitives to V primitives and vice-versa (#12420) 2021-11-10 11:37:16 +02:00
Delyan Angelov
6c244d3065 cgen: improve diagnostic for a v compiler panic in dicordv 2021-11-10 08:12:12 +02:00
yuyi
8f4180ea09 parser: check generic parameters error of generic struct declaration (#12418) 2021-11-09 09:25:57 +02:00
Delyan Angelov
3f841edec1 v.util: make get_vtmp_folder() return /tmp/v_{uid} by default (see https://github.com/vlang/v/discussions/11796) 2021-11-09 08:25:19 +02:00
yuyi
08667c5645 pref: allow running a .vsh script with just v build.vsh gcc, instead of v run build.vsh gcc (#12409) 2021-11-08 15:18:11 +02:00
Taras
15242d8082 docs: add description of how to use a custom table name to the ORM example – (#12408) 2021-11-08 12:22:42 +02:00
yuyi
758c18a906 cgen: fix for in mut val in array.index() (#12410) 2021-11-08 11:12:10 +02:00
yuyi
1211029926 cgen: avoid generating typedef generic array type (#12407) 2021-11-07 21:24:30 +02:00
yuyi
c8ff9e39b5 checker: cleanup generic struct init (#12406) 2021-11-07 18:47:38 +02:00
Delyan Angelov
bc98da9111 ast: speed up the frequently called methods .find_field, .find_method etc 2021-11-07 18:07:04 +02:00
yuyi
9ec1262734 ast: fix generic nested struct init (#12405) 2021-11-07 17:06:37 +02:00
Delyan Angelov
1c12186701 v.token,ast,scanner,parser: use a KeywordsMatcher lookup for builtin_type_names searches too 2021-11-07 16:39:40 +02:00
Delyan Angelov
80242c8041 builtin,ast: apply small performance improvements, suggested by hotspot 2021-11-07 13:30:44 +02:00
playX
d8f971ffb5 jsdom: add Path2D API, All CanvasRenderingContext2D methods (except image methods) (#12404) 2021-11-07 10:06:28 +02:00
Delyan Angelov
852d85b3a9 gg: cleanup the minimal gg program more 2021-11-07 09:16:49 +02:00
Delyan Angelov
32b74dd348 gg: simplify the minimal gg application even more with context.user_data = context 2021-11-06 18:24:19 +02:00
Delyan Angelov
8be64ef80e gg: improve font loading diagnostics with -d debug_font 2021-11-06 17:15:17 +02:00
playX
5f3dcde358 jsdom,builtin: add all methods for DOMMatrix; add conversion methods to convet from/to JS types (#12395) 2021-11-06 15:52:24 +02:00
Delyan Angelov
7a9ba9f41f ci: pin burntsushi/toml-test to their latest master for now 2021-11-06 15:47:49 +02:00
Larpon
d2d67e9f4d toml: add new inline-table duplicate-key test to skip list (#12399) 2021-11-06 15:19:40 +02:00
Larpon
9b00564d98 toml: panic if access fails to a key that was checked (#12384) 2021-11-05 14:14:50 +02:00
Larpon
24cd619ff8 toml: fix parsing array of tables (#12388) 2021-11-05 12:08:40 +02:00
Larpon
db65b65f3c toml: disallow spacing between (array of tables) key syntax (#12382) 2021-11-05 11:29:25 +02:00
Larpon
c3b389cde9 toml: rename sub_key -> dotted_key (#12383) 2021-11-05 11:28:54 +02:00
lydiandy
b963aff8e8 vast: update to latest V (#12387) 2021-11-04 19:57:51 +02:00
Alexander Medvednikov
7ea57bfa1e builtin: make map.keys() public 2021-11-04 19:09:37 +03:00
Alexander Medvednikov
ace9444108 checker: more c2v fixes 2021-11-04 18:43:02 +03:00
Larpon
1999fb9a95 toml: remove some skipped tests related to recent formatting update (#12380) 2021-11-04 14:27:14 +02:00
Larpon
fc7f4c5b1f toml: disallow multiline keys (#12381) 2021-11-04 14:26:25 +02:00
yuyi
59e21c2068 cgen: fix array of threads wait (fix #12350) (#12378) 2021-11-04 14:24:58 +02:00
yuyi
73e25ccb3c checker: check generic struct field fn args type mismatch (#12379) 2021-11-04 10:18:36 +02:00
Delyan Angelov
a27833ed0d all: support volatile field Type in struct declarations 2021-11-04 09:45:50 +02:00
Larpon
1a54817c81 toml: parse formatting (#12374) 2021-11-04 09:15:50 +02:00
playX
2b4154910c jsdom, checker: add more methods for CanvasRenderingContext2D, fix interop check for JS methods (#12372) 2021-11-03 16:54:28 +02:00
Delyan Angelov
c4e282a0c8 parser: check fn args in declarations too with -Wimpure-v
`v -Wimpure-v examples/2048/` now passes cleanly.
2021-11-03 16:20:24 +02:00
yuyi
4bafc5042b checker: check generic struct field fn args error (#12373) 2021-11-03 10:20:39 +02:00
Larpon
45c938bdec toml: streamline scanner.at() return type, fixes #12344 (#12370) 2021-11-03 10:18:09 +02:00
Larpon
bd5e2db460 toml: add Parser.peek(n) method (#12369) 2021-11-03 10:15:40 +02:00
Larpon
99fd84dfe4 toml: fix hex values starting with a, e or E and comments ending with crlf (#12367) 2021-11-02 19:07:27 +02:00
yuyi
3fdbfca202 cgen: fix for in with mutable structs (#12368) 2021-11-02 18:40:13 +03:00
yuyi
639cbfa0d1 checker: fix generics with assign nested generic fn call (#12366) 2021-11-02 10:12:26 +02:00
yuyi
0952af606c checker: fix comptime if T is interface (#12365) 2021-11-02 09:35:01 +02:00
Delyan Angelov
4ed6fb0e9b tools: cleanup a dump() from vwatch.v 2021-11-02 09:29:12 +02:00
crthpl
1d1793ec34 fmt: correctly format segment offsets (#12364) 2021-11-02 08:04:41 +02:00
Wertzui123
9aba00cd08 doc: update github link to libsodium (#12360) 2021-11-02 03:35:54 +03:00
yuyi
dcf230ca24 checker: fix nested generic method call (#12353) 2021-11-01 15:41:54 +03:00
null
0ab133a563 doc: fix typo (#12357)
changed `submiting` to `submitting`.
2021-11-01 15:41:07 +03:00
yuyi
da65680acf checker: fix comptime if expr of sync.threads (#12356) 2021-11-01 09:41:04 +02:00
Lucas Jenß
51f5841b6e checker: do not deref non-pointer types in fn_signature_using_aliases (#12340) 2021-11-01 02:26:15 +03:00
Lucas Jenß
28cada3fd5 docs: fix some typos (#12341) 2021-10-31 14:12:04 +02:00
Delyan Angelov
6937074e7a strings,builder: reduce V cgen and parser memory consumption, fix strings.Builder leak (#12342) 2021-10-31 12:58:55 +02:00
Miccah
ce9f26c589 examples/vweb: use map instead of string in call to app.json (#12338) 2021-10-31 12:31:49 +02:00
czkz
81b95ece51 docs: improve the docs by provide better examples and describe module publishing (#12308) 2021-10-31 11:32:31 +02:00
Delyan Angelov
579d5ae649 builtin,checker: add array.flags. Allow changing it in unsafe {} blocks 2021-10-31 11:04:56 +02:00
Wertzui123
612e742c1f examples: remove unneeded workaround (#12336) 2021-10-30 18:49:54 +03:00
Delyan Angelov
a7d4236337 sync,strings,cgen: reduce memory consumption in cgen 2021-10-29 22:29:56 +03:00
Xiao
7e0f2fcda9 docs: update VS Code debugger configuration descriptions (#12335) 2021-10-29 18:06:28 +03:00
Delyan Angelov
1785b184b9 readline: improve README.md with working examples 2021-10-29 17:36:17 +03:00
Delyan Angelov
d1acca3e52 ci: fix ./v -cg -cstrict -o v cmd/v job failures for clang 2021-10-29 17:21:53 +03:00
yuyi
d5642b6134 cgen: fix error of nested match expr (#12334) 2021-10-29 17:14:49 +03:00
Delyan Angelov
71392111f8 ci: fix cross compilation of vc/v.c 2021-10-29 17:12:05 +03:00
Delyan Angelov
4c67c01e72 parser,util: improve libleak false positive detection rate 2021-10-29 16:42:55 +03:00
Delyan Angelov
3d800b12e8 scanner: small optimisation of the ident_name hot loop 2021-10-29 16:18:34 +03:00
Delyan Angelov
b86c79329b os, builtin: reduce leaks without -autofree 2021-10-29 15:49:30 +03:00
Lucas Jenß
f801ef5e17 checker: disallow mut keyword in right-hand side of assignment (#12318) 2021-10-29 12:03:05 +03:00
playX
a32dae335a js: fix interfaces behaviour & disable struct deep copy for now (#12333) 2021-10-29 11:23:40 +03:00
Louis Schmieder
d33f7d12f7 orm: fix time struct in sql stmt (#12298) 2021-10-28 22:31:41 +03:00
Larpon
5e4594a121 toml: isolate, fix and regress-test sumtype cast causing memory corruption (#12329) 2021-10-28 19:57:30 +03:00
playX
fa02418a55 js: copy variables passed to closures (#12328) 2021-10-28 19:31:56 +03:00
yuyi
0e95e4d7b4 ast, cgen: fix generic method str() overload (#12330) 2021-10-28 19:03:17 +03:00
Delyan Angelov
475a2f9b43 ci: fix failing vlib/orm/orm_test.v 2021-10-28 17:33:18 +03:00
Delyan Angelov
4d0f6767b1 builtin: use malloc instead of calloc for []Type{cap: size} 2021-10-28 17:18:03 +03:00
Delyan Angelov
2c3e44eb20 strings: use memdup_noscan in Builder.str() 2021-10-28 17:00:16 +03:00
Larpon
a987440e2f toml: add UTF header support, add BOM tests (#12326) 2021-10-28 16:38:49 +03:00
Delyan Angelov
99e71d0868 scanner: preallocate space for tokens to reduce the number of allocations in the hot loop 2021-10-28 16:23:24 +03:00
Larpon
5ecaa160a7 toml: fix paths in skipped tests for Windows compatibility (#12323) 2021-10-28 15:56:56 +03:00
Delyan Angelov
8014235e0e scanner: speed up text_scan by using a specialised keywords matcher, instead of a generic V map of keywords 2021-10-28 15:41:13 +03:00
Delyan Angelov
b1bb1d361a ci: vfmt parser.v 2021-10-28 10:51:55 +03:00
Delyan Angelov
1b6cccaf6d parser,checker: allow a goto label right after return 2021-10-28 10:40:31 +03:00
ChAoS_UnItY
8cd01e0eac cgen: fix error caused by fixed size array init syntax with variable it (#12314) 2021-10-28 02:20:49 +03:00
Delyan Angelov
8fd66994c7 ci: comment out the main body in draw.js.v for now 2021-10-28 02:18:38 +03:00
playX
cfecb62299 js: DOM API. Part 1 (#12296) 2021-10-27 23:18:09 +03:00
Delyan Angelov
0ff23eeb74 ci: fix failing assign_expr_channel_push.out 2021-10-27 22:54:41 +03:00
Delyan Angelov
f79bc8619a scanner: remove unused .line_ends field 2021-10-27 22:37:00 +03:00
Larpon
bc3827ae15 toml: improve array parsing (#12322) 2021-10-27 20:26:33 +03:00
Lucas Jenß
43fbc68f1e checker: disallow <- (channel push) on right-hand side of assignment (fix #12309) (#12321) 2021-10-27 17:53:50 +03:00
Delyan Angelov
159a9c3070 markused: fix -skip-unused on programs with generic methods (fix #12306) 2021-10-27 17:22:26 +03:00
Larpon
462d097bf5 toml: small clarification on utf8_max const (#12320) 2021-10-27 16:41:22 +03:00
yuyi
943a807d30 parser: implement generics method with auto multi generic types (#12312) 2021-10-27 15:41:13 +03:00
Darío Hereñú
e5c759eb91 docs: fix typos (line 22, 26, 28, 34, 50, 107) (#12310) 2021-10-27 15:31:18 +03:00
Larpon
d53bb54c0a toml: implement checks for UTF-8 validity (#12313) 2021-10-27 15:28:46 +03:00
Wertzui123
ea6d2d53db parser: disallow for mut in range (fix #12234) (#12277) 2021-10-27 14:55:36 +03:00
Larpon
6eaacd3391 toml: improve checker documentation (#12315) 2021-10-27 14:31:29 +03:00
Lucas Jenß
d7fd4a563b parser: remove commented out debug statement (#12316) 2021-10-27 14:30:22 +03:00
Larpon
1b9eef74aa toml: improve inline-table parsing (#12307) 2021-10-26 17:00:41 +03:00
Larpon
c526752419 toml: remove unused enum (#12304) 2021-10-26 16:58:58 +03:00
Larpon
9a3967bd7d toml: improve comment support (#12305) 2021-10-26 16:58:05 +03:00
Larpon
52df19ef61 toml: check for invalid placement of underscores around exponent (#12303) 2021-10-26 13:49:25 +03:00
Andreas Schoeller
f14dabc6bd math.big: add a new greatest-common-divisor-algo for big.Integer, also add a benchmark for it (#12261) 2021-10-26 11:10:13 +03:00
yuyi
f62b2dcfa7 table: fix generic method with multi generic types (#12297) 2021-10-26 11:00:27 +03:00
Delyan Angelov
508f29c101 docs: document the purpose of the [params] trailing struct tag 2021-10-26 10:53:14 +03:00
Miccah
655b5c563a net.http: use [params] for Config structs (#12299) 2021-10-26 10:45:27 +03:00
Delyan Angelov
06796a6119 ci,toml: add the new float/trailing-us-exp.toml to the ignored skip list for now 2021-10-26 10:42:40 +03:00
Delyan Angelov
5b325b99e8 docs: give a concrete example of bounds access check, and error propagation with x := arr[idx] ? 2021-10-25 17:19:24 +03:00
yuyi
ac99007cab table: fix generic sumtype instantiations (#12288) 2021-10-25 15:22:41 +03:00
kahsa
77a1e3dedb gg: improve system_font_path on linux (#12290) 2021-10-25 15:16:29 +03:00
Amund Tenstad
18da724a9f examples: prevent a 180 turn in snek (#12286) 2021-10-25 10:57:05 +03:00
Bakul Shah
cc2847f6ff builtin: fix compilation with -gc boehm on some FreeBSD versions (#12289) 2021-10-25 10:24:08 +03:00
Delyan Angelov
45c1c1ab41 ci: fix import_symbol_private_err.vv and its .out file (time.since is no longer private) 2021-10-24 22:06:32 +03:00
Delyan Angelov
49ebba535e time: implement pub fn since(t Time) Duration 2021-10-24 21:36:28 +03:00
Delyan Angelov
bb71089b70 os: make the os_test.v functions more robust on windows (normalise the returned paths before comparing them) 2021-10-24 19:54:00 +03:00
Delyan Angelov
e99b699ac6 os: make os.mkdir_all more robust (honor / on windows too), add a test for it 2021-10-24 19:16:46 +03:00
Delyan Angelov
f34daf9ff4 os: add os.walk_with_context/3 and a test for it 2021-10-24 19:12:14 +03:00
Delyan Angelov
e34046a0e1 os: remove pub from impl_walk_ext 2021-10-24 18:48:54 +03:00
Delyan Angelov
d1c4b470bc os: make os.ls('') return an error, make os.walk_ext more memory efficient on deep hierarchies, add tests for os.walk_ext 2021-10-24 18:44:13 +03:00
Delyan Angelov
d9c6c9a7df http: cleanup download_file, remove unimplemented download_file_with_progress 2021-10-24 17:19:44 +03:00
playX
2eae4cf63e js: fix optional error propagation (#12283) 2021-10-24 15:56:44 +03:00
Delyan Angelov
c340906280 cgen: cleanup vinit_string_literals, _vcleanup and reload_so declarations 2021-10-24 15:29:42 +03:00
zakuro
242b99340d vfmt: fix bug where duplicated comma is placed before comment in array init (#12281) 2021-10-24 12:05:34 +03:00
penguindark
47a2301139 regex: add OR error, if sourounded by char classes, and a test (#12278) 2021-10-24 11:54:51 +03:00
Delyan Angelov
e45cd02029 mysql: always use #include <mysql.h>, rely on pkgconfig to get the correct include folder 2021-10-23 21:22:10 +03:00
Delyan Angelov
008d15dcb5 builder,pref: add support for -no-builtin (useful for writing Linux kernel modules) 2021-10-23 12:53:53 +03:00
Delyan Angelov
aa22751d26 vlib: remove unused glm module (#12274) 2021-10-22 22:23:14 +03:00
playX
864d6eae6b js: codegen & vlib fixes, replace the Game of Life CLI example (#12272) 2021-10-22 22:03:19 +03:00
Larpon
8a4756819a toml: disallow unclosed arrays (#12273) 2021-10-22 20:30:29 +03:00
Larpon
506924b01c android: hide printf hijack for android logging behind define (#12269) 2021-10-22 19:59:25 +03:00
Larpon
8273c0582b toml: check for illegal characters, fix all related skipped tests (#12270) 2021-10-22 19:57:32 +03:00
Larpon
eb364f0301 toml: check for exponents starting with an underscore (#12271) 2021-10-22 19:56:43 +03:00
Delyan Angelov
eed94c727c os: move C struct declarations in their own _default.c.v files (#12268) 2021-10-22 17:08:08 +03:00
Delyan Angelov
0401b5ece0 mysql: fix compilation with libmariadb-dev, but no libmysqlclient-dev installed 2021-10-22 16:44:08 +03:00
Larpon
76ff708cf8 toml: squash recently fixed invalid tests (#12266) 2021-10-22 13:38:36 +03:00
Subramani
0d7057dd44 readme: improve wording, fix typos (#12250) 2021-10-22 08:18:01 +03:00
Larpon
cc2ef4188d toml: support parsing (+/-)nan and (+/-)inf (#12256) 2021-10-22 08:16:47 +03:00
Alexander Medvednikov
47313cbf27 doc: clean up array init docs 2021-10-22 07:23:45 +03:00
ChAoS_UnItY
5b69593766 cgen,js: fix missing break in switch case, generated by match with range branches (#12260) 2021-10-21 22:30:05 +03:00
czkz
da7dad07a3 builder: fix sigint handling for v run (#12246) 2021-10-21 16:40:32 +03:00
Larpon
909ed76b8f toml: check binary, octal and hexadecimals literals (#12255) 2021-10-21 16:37:38 +03:00
Delyan Angelov
a85707246f help: document -skip-unused in the v help output. 2021-10-21 16:33:04 +03:00
a-iga
1ba839dc3b openssl: change read_into to read (#12251) 2021-10-21 14:13:04 +03:00
Larpon
a84b1a53ec toml: fix bin, oct and hex capital identifier check (#12254) 2021-10-21 14:12:17 +03:00
czkz
5607224be6 docs: improve os.ProcessState markdown rendering (#12245) 2021-10-21 11:19:01 +03:00
yuyi
ff02c19827 table, builder, checker: cleanup unwrap_generic (#12241) 2021-10-21 05:48:02 +03:00
playX
57c79770b3 js: port more methods (os, builtin) (#12238) 2021-10-20 16:02:21 +03:00
Lance Fredrickson
7c1fff3495 builder: pass -std=gnu99 to the C backend under linux (#12236) 2021-10-20 14:26:25 +03:00
05st
3e52d54586 cgen: fix match expr when evaluating to sumtype (#12237) 2021-10-20 11:52:11 +03:00
Delyan Angelov
ef0eaeee08 ci: fix broken js tests 2021-10-19 20:05:27 +03:00
Alexander Medvednikov
a8ced46564 sokol: fix a typo 2021-10-19 17:18:49 +03:00
ChAoS_UnItY
ab350d52ec cgen: support RangeExpr while emitting enum switch case (#12226) 2021-10-19 17:02:22 +03:00
Alexander Medvednikov
d8ea9e4969 sokol: move _sapp_macos_resize_window 2021-10-19 16:58:39 +03:00
Alexander Medvednikov
45534b512b time: move pure V function from time.c.v 2021-10-19 16:03:45 +03:00
Delyan Angelov
f2cda1a529 parser: update p.inside_or_expr consistently (fix v fmt -w vls/analyzer/symbol_registration.v) 2021-10-19 13:36:10 +03:00
yuyi
6aca360507 parser: fix checking unexpected name (#12233) 2021-10-19 12:27:59 +03:00
playX
c1aa782a6c js,checker: fix some modules build for v -b js self, fix or block check in ast.CallExpr (#12231) 2021-10-19 12:11:54 +03:00
Delyan Angelov
39c3817ce4 readme: add a section for installing openssl so linking to it when answering is easier. 2021-10-19 09:43:29 +03:00
czkz
a84a6d1fb1 docs: fix typos, cleanup wording (#12227) 2021-10-18 21:03:27 +03:00
xiao xigua
108644d260 vweb: add file method to vweb.Context, make the existing json method generic (#12211) 2021-10-18 18:25:06 +03:00
Delyan Angelov
e9aa18fcc8 roadmap: mark parallel cgen and interface embedding as done 2021-10-18 17:50:05 +03:00
lydiandy
3af53e29c9 doc: update the interface sections (#12225) 2021-10-18 14:24:09 +03:00
Delyan Angelov
b23984a211 builder: only print the thirdparty object rebuilding line with '-v' 2021-10-18 13:28:09 +03:00
ChAoS_UnItY
53c2e262f1 cgen & jsgen: generate when possible a switch from match x { (#12216) 2021-10-18 10:59:52 +03:00
playX
a3de67de28 js: support WASM interoperability using wasm_import/wasm_export fn tags (#12212) 2021-10-18 10:56:21 +03:00
lydiandy
2070839722 io: pub the RandomReader interface (#12222) 2021-10-18 10:51:36 +03:00
Delyan Angelov
5dd3864617 markused: fix v -skip-unused cmd/tools/vpm.v regression after 98b2bdb 2021-10-18 08:43:56 +03:00
Delyan Angelov
735c961682 autofree: add skipped string_plus_string_plus.v sample 2021-10-17 19:46:35 +03:00
Delyan Angelov
6e4bda3741 strconv: fix string builder leaks in format_dec_old, format_es_old, format_fl_old, v_sprintf 2021-10-17 19:46:34 +03:00
Delyan Angelov
1313dcf601 gg: fix leak in draw_image_with_config 2021-10-17 19:46:34 +03:00
lydiandy
98b2bdb410 io: cleanup ReaderWriter interface (#12218) 2021-10-17 19:39:51 +03:00
czkz
3a073329ff builder: use os.new_process() instead of os.system() in v run (#12214) 2021-10-17 19:01:34 +03:00
yuyi
a006090b08 ast: minor cleanup of register_type_symbol (#12213) 2021-10-17 15:50:42 +03:00
czkz
29f068997b math: add fn clamp (#12205) 2021-10-17 06:42:40 +03:00
05st
fd3a10ab43 checker: fix mut check bypass with for in loops (#12208) 2021-10-17 06:41:39 +03:00
Alexander Medvednikov
e6b7ab8b9d net.http: authority header 2021-10-17 06:40:19 +03:00
Larpon
678e3a210d tools: add vshader (#12195) 2021-10-16 22:10:48 +03:00
Larpon
bff7cc5f20 thirdparty: remove patch marks in sokol_gfx.h (#12198) 2021-10-15 19:36:44 +03:00
Delyan Angelov
dee4ffbc99 builder: make -usecache rebuild cached, but changed modules, and their dependants (#12193) 2021-10-15 12:22:59 +03:00
yuyi
c108e01917 checker: fix generic fn return types with generic struct (#12186) 2021-10-15 11:50:10 +03:00
yuyi
27cd21e459 cgen: fix infix ops, for cross assignments of types with overloaded operators (#12192) 2021-10-15 11:32:58 +03:00
playX
814b4ebb4c term: get_terminal_size() for js_node, term.clear() for all js backends (#12189) 2021-10-15 10:10:40 +03:00
playX
d3887c1568 time: fix sys_mono_now for the JS backend (#12187) 2021-10-15 09:22:15 +03:00
czkz
c29a5cdedb term: fix readme typo (#12180) 2021-10-15 06:08:31 +03:00
ChAoS_UnItY
4d1307f29b all: index accessor in array init expression (#12181) 2021-10-15 03:57:49 +03:00
Carlos Esquerdo Bernat
6d62574e7f tutorials: fix argument type (#12182) 2021-10-15 02:24:22 +03:00
yuyi
c9b2f878b3 parser, checker: optimize checking generic struct type mismatch (#12179) 2021-10-15 00:11:31 +03:00
Ulises Jeremias Cornejo Fandos
4490d5ed29 context: cleanup the tests and the documentation (#12175) 2021-10-14 13:32:42 +03:00
Delyan Angelov
4c2cb1b6df vdoc: prevent leaking to the docs the pure_v_but_overriden_by_ prefix 2021-10-14 11:47:50 +03:00
yuyi
05885059bd cgen: remove the extra generated parentheses of single in_expr (fix #12158) (#12168) 2021-10-14 11:38:16 +03:00
ChAoS_UnItY
6f629d1a6a transformer: eliminate unreachable branches & redundant branch expressions in MatchExpr (#12174) 2021-10-14 02:15:52 +03:00
nyx-litenite
5b9553d5c4 orm: fix last_id() call in mysql (#12173) 2021-10-13 21:24:07 +03:00
Larpon
5bfa3d5530 sokol: add screenshot function to OpenGL based backends (#12169) 2021-10-13 21:22:58 +03:00
yuyi
97e999768a checker: fix generic fn return array of generic struct (#12170) 2021-10-13 21:21:32 +03:00
playX
d373eba79b js: implement more functions for JS backend (#12167) 2021-10-13 09:40:14 +03:00
pancake
ade5774313 native: fix return a+b infix construction (#12161) 2021-10-12 19:38:17 +03:00
Delyan Angelov
6c728cf389 js: add draft support for -skip-unused (hello_world.v works) 2021-10-12 19:34:37 +03:00
pancake
1d2b56d71d native: fix example exit((1,2)->(a,b)return a+b) (#12154) 2021-10-12 18:51:28 +03:00
pancake
347ebe5fd3 native: append .exe, when using the native backend on windows (#12159) 2021-10-12 18:49:42 +03:00
pancake
a0a0ae85eb native: add support for pe64 when -os windows is used (#12149) 2021-10-12 10:43:40 +03:00
playX
22962dd2d2 js: change codegen for match statement, speedup string.split_into_lines (#12157) 2021-10-12 09:52:16 +03:00
Alexander Medvednikov
cfc56b24fb vweb: fix [post] route matching 2021-10-12 08:18:04 +03:00
Alexander Medvednikov
555e8cada6 tutorials: update the vweb tutorial with the new form parsing syntax 2021-10-12 07:17:49 +03:00
Alexander Medvednikov
da58ba0d5c vweb: populate action method params with form values 2021-10-12 07:10:12 +03:00
Anton Zavodchikov
4d7bb95c2f vweb: add a vweb_global attribute (#12064) 2021-10-12 06:35:36 +03:00
pancake
5eba02ea94 native: fix stackframe bug on return statements (#12153) 2021-10-12 06:03:44 +03:00
penguindark
0fafefc078 regex: bug fix on find groups indexes (#12152) 2021-10-12 06:03:23 +03:00
Delyan Angelov
3c8be0db72 tests: reduce maxn in builder_test.js.v to just 1000 for now (runs in under 200ms, vs ~240s before that) 2021-10-11 19:57:35 +03:00
Delyan Angelov
9fabf9f20c checker: check for x := Abc { f: fn () ? {} } mismatch, when f is fn () 2021-10-11 19:20:41 +03:00
Delyan Angelov
6c6bb08547 tools/vast: update vast to latest V 2021-10-11 15:52:06 +03:00
Alexander Ivanov
0386f2bbea checker: add an interface check for mutability, fixes #1081, fixes #7038 (#11963) 2021-10-11 15:41:31 +03:00
ChAoS_UnItY
d0c961ebc0 transformer: eliminate unreachable branches in IfExpr and fold more expressions and statements (#12135)
* v: fix using constant as length in fixed array

* format test file

* v/trasnformer: discard unreachable if branches

* transform more expressions and statements

* replace IfExpr with EmptyExpr when all branches were eliminated

* fix typo

* fix gens

* only allows branch elimination on if expression statement

* fix native gen

* fix handling of multi branch ifs in the native backend, also allow for `if true {}`

Co-authored-by: KyleLin921021 <43753315+KyleLin921021@users.noreply.github.com>
Co-authored-by: Delyan Angelov <delian66@gmail.com>
2021-10-11 14:29:17 +03:00
Ulises Jeremias Cornejo Fandos
35b301f73c math: add some benchmark tests (#12142) 2021-10-11 14:20:07 +03:00
05st
3e02cfd528 cgen: fix in op usage on array of sumtypes without cast (#12141) 2021-10-11 14:17:04 +03:00
Delyan Angelov
ceb24bc32e tests: show the number of parallel jobs used while testing 2021-10-11 13:10:55 +03:00
yuyi
1831eccd5e checker: check generic struct using in non-generic fn (#12136) 2021-10-11 02:46:44 +03:00
05st
e69df54a36 cgen: fix multi-return in if/match exprs (#12139) 2021-10-11 02:45:01 +03:00
Ulises Jeremias Cornejo Fandos
0f7dfb984a math: remove the C backend for f64 functions (#12121) 2021-10-10 11:21:48 +03:00
yuyi
83bc9b35b1 ast: fix checking generic fn call with fntype arg mismatch (#12132) 2021-10-10 11:14:19 +03:00
Yeuda By
8d5931c96c orm: fix a typo (#12131) 2021-10-10 03:47:35 +03:00
ChAoS_UnItY
3647fc6633 parser: perform constant folding before checking size of fixed array (#12126) 2021-10-10 01:55:25 +03:00
yuyi
093cab6f56 checker: check generics struct init that types mismatch (fix #12115) (#12120) 2021-10-09 15:03:37 +03:00
pancake
7a6491b9b0 native: initial implementation of C.syscall (#12098) 2021-10-09 15:01:30 +03:00
Delyan Angelov
d14b5d0c11 ci: reduce flakyness of vlib/v/pref/options_test.v on ubuntu 2021-10-09 12:58:21 +03:00
Delyan Angelov
32ea53960e v doc: show a proper error message instead of panic on v doc -m file.v 2021-10-09 11:56:37 +03:00
playX
e267106220 math: implement logarithm function in pure V (#12111) 2021-10-09 11:17:09 +03:00
Delyan Angelov
23e679475c time: sanity check parsed date/times 2021-10-09 11:05:49 +03:00
yuyi
3c7c11e55b cgen: fix sumtype with none type (fix #12101) (#12102) 2021-10-09 03:32:37 +03:00
05st
43931be451 math: sqrti, powi, factoriali (#12072) 2021-10-08 22:07:44 +03:00
05st
cd5b304cbf cgen: add interface case for gen_struct_equality_fn (#12094) 2021-10-08 19:04:24 +03:00
playX
a8ace2c41c math: implement pow in pure V (#12105) 2021-10-08 17:44:55 +03:00
Delyan Angelov
60add6cc28 ci: fix failing tests 2021-10-07 19:22:08 +03:00
Alexander Medvednikov
c356e347f5 pref: do not allow -prod with v run 2021-10-07 16:13:58 +03:00
playX
33a1006cc5 js: comptime&assert improvements, more byte and strings.Builder methods ported (#12096) 2021-10-07 15:55:47 +03:00
Larpon
42359d8915 toml: fix error return in value parsing (#12097) 2021-10-07 15:51:18 +03:00
Delyan Angelov
fbe54e49f5 tools: support v fmt -w -backup file.v 2021-10-07 13:59:49 +03:00
Larpon
09cc0c7247 gg: use sgl.begin_points for pixels + improve pixels example (#12085) 2021-10-07 10:46:57 +03:00
Larpon
d2d70450a5 gg: use sgl.begin_triangles when drawing triangles (#12083) 2021-10-07 10:45:21 +03:00
Larpon
53aa4eba0d sokol: add sg_isvalid wrapper to gfx (#12081) 2021-10-07 10:41:57 +03:00
Larpon
f454d30318 gg: use sgl.begin_triangles when drawing triangles (#12083) 2021-10-07 03:45:23 +03:00
Larpon
42c088896a gg: mute font print on Linux, use flag debug_font instead (#12082) 2021-10-07 03:45:02 +03:00
pancake
32259af2c9 v.parser: improve error message when no arch is set 'asm{}' (#12093) 2021-10-07 03:44:27 +03:00
Delyan Angelov
e53682320c v.gen.c: fix compiling go f(x) for x of the same struct in different .v files with parallel cgen 2021-10-06 22:12:21 +03:00
yuyi
0d53705776 v.checker: check fn returning void type (fix #12076) (#12078) 2021-10-06 21:04:33 +03:00
yuyi
5f736dd768 v test-cleancode: remove interop_test.v from the exceptions list (#12084) 2021-10-06 20:53:50 +03:00
yuyi
963233687e v.fmt: fix fmt of 'fn(mut a &int)' (#12075) 2021-10-06 20:51:38 +03:00
yuyi
f1742a6f62 v.ast: change 'type.to_ptr()' to 'type.ref()' (#12086) 2021-10-06 20:49:39 +03:00
Wertzui123
77c18f4435 cgen: fix alphabetic order of ast statement generation (#12080) 2021-10-06 14:32:42 +03:00
playX
b2945e916f js: add initial support for runes (#12077) 2021-10-06 10:43:49 +03:00
Delyan Angelov
115493781b tests: make the output of coutput_test.v more accurate/easily reproducible in case of failures 2021-10-06 10:15:18 +03:00
Delyan Angelov
5bc8b4dadb os: implement support for VOPEN_URI_CMD env override for os.open_uri 2021-10-06 06:33:04 +03:00
Delyan Angelov
2526aca75f tests: fix typo in coutput_test.v (thanks Jalon) 2021-10-06 00:33:01 +03:00
Delyan Angelov
efa1092199 v.gen.c: add coutput tests for the [console] codegen to prevent future regressions 2021-10-06 00:14:16 +03:00
Delyan Angelov
aa8915bdf6 v.gen.c: fix [console] handling for sokol programs on windows with parallel cgen 2021-10-05 23:57:14 +03:00
Delyan Angelov
443fa50244 docs: cleanup the Test files section a little 2021-10-05 22:49:51 +03:00
Delyan Angelov
6d2c1f7e2c v.gen.c: enable again parallel cgen for -g, make -g more robust 2021-10-05 21:51:49 +03:00
crthpl
7cf9c198fe asm: add segment addressing and fix [10] (#12068) 2021-10-05 18:57:15 +03:00
Delyan Angelov
514443a019 ci: comment out a failing assert in the tests for os.notify 2021-10-05 16:01:54 +03:00
Delyan Angelov
eef8017281 ci: reduce flakyness of notify_test.v, by re-trying it 3 times 2021-10-05 15:50:38 +03:00
Delyan Angelov
ccb5f1d563 tests: support // vtest vflags: -prod in coutput_test.v.
Use it, to add a `-prod` test for `$embed_file()`,
to prevent future codegen regressions.
2021-10-05 15:44:12 +03:00
Delyan Angelov
e23d61d99e v.pref: disable the parallel cgen when -g is given for now (the line numbers/paths are wrong) 2021-10-05 15:08:28 +03:00
Delyan Angelov
92f2e5bad2 v.gen.c: fix compilation with -prod, for files using $embed_file() (regression after parallel cgen in 85b58b0) 2021-10-05 15:06:17 +03:00
Delyan Angelov
b4d1429ef0 tests: rename as_cast_literal.v to as_cast_literal_test.v 2021-10-05 11:57:57 +03:00
yuyi
7bc3e67e24 fmt: fix import with symbols (fix #12065) (#12069) 2021-10-05 11:44:48 +03:00
05st
7555b337b9 cgen: fix expr_as_cast for int/float literals (#12067) 2021-10-05 09:53:05 +03:00
playX
8d1ba52d0c js: fix string.bytes codegen, readline, add tests for strings (#12060) 2021-10-04 18:28:30 +03:00
yuyi
e94e08475d cgen: format shared structs (#12062) 2021-10-04 18:27:38 +03:00
yuyi
03269f9854 cgen: fix error of reference struct str() (#12061) 2021-10-04 09:58:50 +03:00
Larpon
a8c2c419cd builtin: improve malloc panic messages (#12054) 2021-10-03 20:27:46 +03:00
Delyan Angelov
bfb8116623 ci: let process_test.v repeatedly fail 3 times, before consider it failed 2021-10-03 20:26:38 +03:00
yuyi
82e6d6e51d cgen: fix threads array wait without go calls (fix #12009) (#12050) 2021-10-03 18:24:44 +03:00
Larpon
b62520af9e os: fix rare crash in read_file. Fix #12052 (#12053) 2021-10-03 18:24:06 +03:00
Anton Zavodchikov
895daf297f vweb: router refactor (#12041) 2021-10-03 16:26:44 +03:00
Ekopalypse
9be16eba63 v.gen.c: add tests to ensure the same calling convention is used on exported functions for -m32/-m64 (#11977) 2021-10-03 15:47:08 +03:00
spaceface
9b6e07e2a6 cgen: support index and in for sumtype/interface arrays (#12051) 2021-10-03 15:44:13 +03:00
yuyi
10caf4a84a cgen: cleanup generated thread wait code (#12048) 2021-10-03 10:52:29 +03:00
playX
9145cd66ec js: add more tests to builtin/js and implement more builtin functions (#12049) 2021-10-03 10:08:21 +03:00
05st
129c81f34d cgen: implement eq operator for interfaces (#12047) 2021-10-03 09:04:05 +03:00
05st
f282e64fe3 arrays: add binary_search, lower_bound, and upper_bound array operations (#12045) 2021-10-03 08:14:39 +03:00
Nicolas Sauzede
117091452b os: workaround _ = C.pipe(&pipeset[0]) gcc warning warning: ignoring return value of pipe declared with attribute warn_unused_result (#12046) 2021-10-03 08:09:08 +03:00
05st
86a5e72c74 v.checker: fix return type checking being skipped for mutable method receivers (#12043) 2021-10-02 23:26:46 +03:00
Delyan Angelov
02e4aa0f0e v.checker: fix panic for a, b, c = fn_returning_several_maps() 2021-10-02 18:40:35 +03:00
Delyan Angelov
0916806350 ci: do not use htonll and ntohll on windows, use the portable versions instead. 2021-10-02 18:21:16 +03:00
Delyan Angelov
9a4dbc25ca ci: fix failing conv_test.v on windows 2021-10-02 15:51:48 +03:00
Anton Zavodchikov
4c8094d0d9 net.http: make public errors and parse_form (#12038) 2021-10-02 15:28:35 +03:00
Anton Zavodchikov
600880660a net.http: add a deprecated attribute for un/escape functions (#12037) 2021-10-02 15:19:32 +03:00
Delyan Angelov
c86935309e v.gen.c: fix compilation of if c_struct_1 != c_struct_2 { 2021-10-02 15:12:18 +03:00
05st
cc4af235f3 cgen: fix if-expression code generation if it evaluates to propagating optional / or block (#12032) 2021-10-02 14:30:04 +03:00
Delyan Angelov
552daea04f tools: fix the output of v run cmd/tools/oldv.v d329e1d -c "./v file.v" 2021-10-02 14:13:17 +03:00
Delyan Angelov
d1d4877348 net.conv: add a test for the nth16/nth32/nth64/htn16/htn32/htn64 functions 2021-10-02 13:26:09 +03:00
playX
82f187e5e0 js: fix rand build, properly use key values on map, add rand.string (#12020) 2021-10-01 21:23:49 +03:00
05st
60ecbec8ea cgen: fix closure code gen with if statement in definition (#12028) 2021-10-01 16:52:34 +03:00
Alexander Ivanov
cb149bfa00 checker: show errors for index calls to values which are not functions, fixes #11539 (#12024) 2021-10-01 15:17:02 +03:00
zakuro
ce0867f40c vfmt: fix removal of selective imported type used in map (#12030) 2021-10-01 15:14:21 +03:00
Delyan Angelov
41de0c3c6a ci: fix v -cc gcc -cstrict examples/pico/pico.v 2021-10-01 13:49:38 +03:00
Delyan Angelov
6f7c3a7cdf ci: do brew install openssl on the macos job, reduce flakyness of tcp_test.v 2021-10-01 13:13:05 +03:00
Delyan Angelov
2bdba5ed73 net: fix declarations of C.htonl/C.htons/C.ntohl/C.ntohs in aasocket.c.v 2021-10-01 12:57:47 +03:00
Delyan Angelov
149517ced4 v.builder,v.gen: time Builder.front_stages.parse_files, Builder.resolve_deps, Gen.sort_structs 2021-09-30 20:49:19 +03:00
Alexander Medvednikov
4a6d161c08 orm: postgres fixes 2021-09-30 20:00:27 +03:00
Larpon
8705db5844 toml: fix scanner escape collecting in literal strings (#12022) 2021-09-30 16:04:21 +03:00
Alexander Medvednikov
d4b3c65c45 cgen: a minor optimization; checker: a c2v fix 2021-09-30 12:51:53 +03:00
cindRoberta
6cffcf515a docs: add the topics Hoistings and Closures (#12021) 2021-09-30 12:43:26 +03:00
Wertzui123
e3d379a1eb builtin: add byte.repeat() and rune.repeat() (#12007) 2021-09-30 09:32:20 +03:00
Louis Schmieder
f9ceb12e22 checker: fix orm cast check (#12018) 2021-09-30 00:43:08 +03:00
Alexander Medvednikov
d374c347e5 ci: fix gitly test 2021-09-30 00:08:28 +03:00
Larpon
e3d3727c0c toml: fix 7 escape tests (#12017) 2021-09-29 19:28:09 +03:00
Alexander Medvednikov
c2f535fee1 ci: run the gitly web server test 2021-09-29 19:26:49 +03:00
playX
4333a53f28 js: support running .js.v tests in v test-self, fixes for array methods & codegen (#12011) 2021-09-29 15:33:14 +03:00
Larpon
4ff061927b toml: easier scanner configuration (#12016) 2021-09-29 14:53:06 +03:00
yuyi
f2c710d306 cgen: fix fn mut args with interface type (#12012) 2021-09-29 13:54:23 +03:00
yuyi
8789cc422c v.ast: fix fmt of 'bytestr' to '&byte' (#12014) 2021-09-29 13:53:46 +03:00
Larpon
d39fec3479 toml: fix unbalanced quoted tests (#12006) 2021-09-29 10:19:49 +03:00
Delyan Angelov
24c1d552d7 ci: vfmt vlib/v/gen/c/cgen.v 2021-09-29 08:58:27 +03:00
André Diego Piske
8dde9d4a7b cgen: fixes for ... in with index (#11995) 2021-09-28 19:35:07 +03:00
yuyi
5d3795e876 cgen: fix the C codegen error for '_ = map[key]' (fix #11999) (#12000) 2021-09-28 18:45:50 +03:00
Delyan Angelov
86694ddc85 ci: bump up fetch-depth to 10 for the bootstrapping CI jobs 2021-09-28 18:43:33 +03:00
Larpon
bc4aad5fb4 toml: add quote details to ast.Quoted (#11997) 2021-09-28 17:40:03 +03:00
Delyan Angelov
a03693e881 ci: extract bootstrapping tests into their own .yml file 2021-09-28 17:38:03 +03:00
Delyan Angelov
85c38bac34 ci: make the bootstrapping failure detection more sensitive 2021-09-28 17:17:55 +03:00
Delyan Angelov
87fe15e39f ci: fix typo 2021-09-28 15:30:05 +03:00
Delyan Angelov
3467ab1551 ci: fix the g++ build and the alpine-musl task 2021-09-28 15:29:00 +03:00
Delyan Angelov
9bf6d57032 ci: remove make.bat --verbose usages from the .yml files 2021-09-28 13:11:55 +03:00
Delyan Angelov
c8f1e6b5b6 ci: simplify make.bat, make it verbose to fix errors easier 2021-09-28 13:03:07 +03:00
Delyan Angelov
d07a96ede8 v.gen.c: fix v examples/hello_world.v on FreeBSD 2021-09-28 12:00:34 +03:00
Delyan Angelov
8f4fe61381 v.pref: only show the disabling parallel cgen message when -no-parallel was not given and -prealloc was 2021-09-28 11:52:27 +03:00
Delyan Angelov
975550f912 ci: add -lpthread on FreeBSD's makefile 2021-09-28 11:42:14 +03:00
Delyan Angelov
d31c9250d3 ci: further makefile bootstrapping fixes 2021-09-28 11:38:33 +03:00
Delyan Angelov
97eb0fc74f ci: workaround linking on macos (missing sem_timedwait) 2021-09-28 11:27:47 +03:00
Delyan Angelov
9e2607db57 sync: rename sync_macos.c.v to sync_darwin.c.v 2021-09-28 11:12:03 +03:00
Delyan Angelov
858161bbc4 ci: fix makefiles 2021-09-28 11:02:05 +03:00
Delyan Angelov
6b40ead54d fix ./v -cc g++ run examples/concurrency/concurrency_http.v 2021-09-28 10:35:02 +03:00
Delyan Angelov
bf0b86774a fix for the "v.c should be buildable with no warnings" step in v test-all 2021-09-28 10:34:54 +03:00
crthpl
85b58b03a3 cgen: parallelize (#10844) 2021-09-28 10:28:04 +03:00
Ken
a17b943e87 builtin: add method byte() for string (#11998) 2021-09-28 10:08:10 +03:00
Ulises Jeremias Cornejo Fandos
c151e075e1 context: update ValueContext to handle Any value and more Key types, use closures (#11993) 2021-09-27 17:52:20 +03:00
yuyi
d6a4bce2ef checker: fix generic array.map with generic callback fn (#11991) 2021-09-27 17:50:15 +03:00
Larpon
2ee873d6ca toml: fix invalid bad-multiline test (#11996) 2021-09-27 17:42:20 +03:00
yuyi
4e1ebca0cb ci: remove vls master branch test (#11992) 2021-09-27 07:11:18 +03:00
Delyan Angelov
105e76f321 ci: bump up perf-regressions limits to 251ms for hw, and 1501ms for v -o v.c cmd/v, to avoid false positives :-| 2021-09-26 22:36:58 +03:00
Wertzui123
07d65b2aab builtin: move byte methods from rune.v to int.v (#11987) 2021-09-26 22:34:25 +03:00
czkz
6967a47e07 net.openssl: fix typos in comments (#11988) 2021-09-26 22:33:10 +03:00
Delyan Angelov
6a2ef733de v.parser: add a generated .all(.flag1|.flag2) method to [flag] enums
Unlike `.has(.flag1|.flag2)`, which is true, for any of `.flag1` or `.flag2`,
the new method `.all()` tests whether *all flags* are set at the same time.
2021-09-26 21:40:44 +03:00
Rémi
09dfc3f301 arrays: add a generic arrays.concat(os.args,'abc','xyz') function (#11985) 2021-09-26 19:41:50 +03:00
yuyi
4c01627e00 cgen: cleanup stmt_path_pos processing (#11983) 2021-09-26 15:51:18 +03:00
yuyi
d93737dd34 cgen: fix assign map get to blank (fix #11508) (#11982) 2021-09-26 13:07:51 +03:00
Louis Schmieder
6391f3d2da orm: fix other int types (#11981) 2021-09-26 11:17:56 +03:00
yuyi
e09860731f cgen: fix if expr with complex nested array call (#11979) 2021-09-26 07:35:48 +03:00
Larpon
da47638f42 toml: correct documentation (#11976) 2021-09-26 07:34:47 +03:00
playX
863dd0b23e js: array improvements (#11952) 2021-09-26 07:33:53 +03:00
penguindark
f3757a7cd1 strconv: float memory leak fix (#11980) 2021-09-26 07:33:35 +03:00
yuyi
d329e1decd cgen: fix if expr with nested array calls (fix #11953) (#11973) 2021-09-25 20:38:33 +03:00
Larpon
13b2aa701c toml: rename ast.Node -> ast.Value (#11974) 2021-09-25 20:31:02 +03:00
Anton Zavodchikov
80c15607da json: assert encoded struct with a sumtype (#11970) 2021-09-25 20:29:52 +03:00
Larpon
970768288d gg: expose sapp_desc.swap_interval via gg.Config (#11975) 2021-09-25 15:06:56 +03:00
Miccah
956fdffd96 net.http: allow custom headers in post_multipart_form (#11971) 2021-09-25 10:09:49 +03:00
Ruofan XU
4fbf3fdf03 examples: make the binary search tree example generic (#11968) 2021-09-24 21:17:26 +03:00
Larpon
5541ec8670 vlib: add toml module + tests (#11964) 2021-09-24 21:13:52 +03:00
Ruofan XU
834cf40ab2 cgen, fmt, scanner: fix and use nested lambda in scanner (#11967) 2021-09-24 18:21:22 +03:00
Ekopalypse
400ab7876b ast: fix fixed array typedef generation issue (#11962) 2021-09-24 17:01:42 +03:00
Anton Zavodchikov
c75271fcb7 cgen: json sumtype inlining (#11961) 2021-09-24 16:49:00 +03:00
yuyi
430677a0c0 cgen: format generated C code of nested array call (#11955) 2021-09-23 19:56:12 +03:00
Delyan Angelov
ad58fe8249 ci: mark cancel_test.v with vtest retry: 3 2021-09-23 14:55:10 +03:00
zakuro
b354f9ae9a cgen: fix c error of if-expression when debug mode (#11950) 2021-09-23 14:52:32 +03:00
Delyan Angelov
4a0d00fb30 io.util: simplify random number generation in util.v 2021-09-23 14:20:39 +03:00
Delyan Angelov
afc3531945 ci: work around a failing g++ compilation (order of methods in an interface dispatching table matters for C++ compilers) 2021-09-23 14:08:50 +03:00
Delyan Angelov
ece5fa183c fast.v: freebsd fixes 2021-09-23 13:48:41 +03:00
Delyan Angelov
930b95f76c v.gen.c: fix uninitialised value usages regression after e5fb4e4 2021-09-23 12:24:03 +03:00
Delyan Angelov
8837712f2b rand: fix leaks with -autofree 2021-09-23 12:24:03 +03:00
Delyan Angelov
79e33d92f1 v.markused: remove hash.init() function (map fn usages are detected more precisely) 2021-09-23 12:24:02 +03:00
trollkarlen
b52f79e137 log: add temporary get_level() (#11946) 2021-09-23 12:05:11 +03:00
Alexander Ivanov
4d0f835548 checker: fix detection of invalid insertions, fixes #3600 (#11945) 2021-09-23 11:59:43 +03:00
Alexander Medvednikov
27f5c35bde autofree: test returning optionals 2021-09-23 09:18:01 +03:00
yuyi
b8935551f1 cgen: fix nested array call (#11948) 2021-09-23 08:50:37 +03:00
Alexander Medvednikov
7b60367512 autofree: free reference types with -experimental for now 2021-09-23 04:35:09 +03:00
Ruofan XU
52b53f17b2 scanner: clean up scanning of > (#11943) 2021-09-23 02:24:23 +03:00
Delyan Angelov
bf2569a9a8 all: support mut volatile x := 123 declarations (#11940) 2021-09-22 13:06:30 +03:00
yuyi
76e360ce86 cgen: format the generated C code for array map/filter/all/any methods (#11936) 2021-09-22 09:24:36 +03:00
yuyi
e5fb4e4845 cgen: fix if expr with array call (fix #11557) (#11569) 2021-09-22 02:21:18 +03:00
Alexander Ivanov
b9720f5d9e cgen: fix struct init with multiple branches, fixes #11564 (#11570) 2021-09-22 00:46:07 +03:00
yuyi
2f3925a0cf fmt: format vlib/v/token/token.v (#11568) 2021-09-21 23:29:53 +03:00
yuyi
de4c0c237b cgen: fix if infix expr with array.all/any() (#11567) 2021-09-21 16:20:41 +03:00
yuyi
108a01d65f fmt: fix unnecessary line break in array init (fix #11448) (#11562) 2021-09-21 16:20:09 +03:00
yuyi
d6fa6a459c checker: fix generic sumtype method (#11565) 2021-09-21 16:19:43 +03:00
ChAoS_UnItY
95136cbfc7 all: add unsigned shift operators (#11536) 2021-09-21 14:02:17 +03:00
penguindark
e4bd2306da sokol: upgrade to latest version, add program icon support (#11559)
* updated sokol_gfx.h to the last version: 16d7b2e

* merged sokol_app and update enums.v

* added missing icons structs

* try to fixing Mac keyboard problems

* added v patch marker to sokol_app.h

* upgrade for sokol_gl.h, sokol_fontstash.h

* manage sgl_load_default_pipeline

* added load_default_pipeline() for sokol coherence

* vfmt sapp_structs.c.v

Co-authored-by: Delyan Angelov <delian66@gmail.com>
2021-09-21 09:55:06 +03:00
Alexander Medvednikov
49886b8c40 examples: add a missing vweb header 2021-09-21 08:13:42 +03:00
Alexander Medvednikov
f6bdc6b87e tmpl: fix <div> inside <div> 2021-09-21 07:54:10 +03:00
Enzo
b2ecca3966 all: remove size_t (#11478) 2021-09-21 02:12:38 +03:00
Alexander Medvednikov
4aa99e4303 tmpl: add a <div> test 2021-09-21 02:11:33 +03:00
Ruofan XU
1430ebc5e3 scanner: cleanup scanning of > (#11558) 2021-09-21 00:57:05 +03:00
Anton Zavodchikov
d51f8ed878 v.gen.c: use unmangled variant name for encoding sumtype values in json (#11554) 2021-09-20 21:19:16 +03:00
ChAoS_UnItY
077c55d0c8 encoding.utf8: add pub fn is_letter(r rune) bool (#11547) 2021-09-20 21:16:50 +03:00
Delyan Angelov
5cf0ee46b3 v.pref,v.builder: support overriding the C cross compiler by setting VCROSS_COMPILER_NAME 2021-09-20 19:57:43 +03:00
El Koulali András
9c4507d115 cgen: fix illegal character encoding with rune consts above 127 (#11550) 2021-09-20 10:45:42 +03:00
Delyan Angelov
1de4f1af2e ci: reduce chance of spurious go_wait_option_test.v failures by retrying it 3 times 2021-09-20 10:32:40 +03:00
05st
f9f4867c25 tmpl: fix $tmpl comptime operation only working in return statement (#11541) 2021-09-19 23:22:26 +03:00
Rémi
2534946ead json: support sumtypes (#11549) 2021-09-19 21:36:26 +03:00
Delyan Angelov
7bd145d88a os,net: cleanup deprecated @VROOT usages 2021-09-19 16:24:24 +03:00
Ruofan XU
b343f19bec v.scanner: fix ambiguity of two-level generics and shift-right (#11540) 2021-09-19 16:22:28 +03:00
Delyan Angelov
76f70d51f3 ci: fix another options_test.v failute, refactor for readability 2021-09-19 08:49:52 +03:00
Delyan Angelov
b5d8c53a0c v.gen.c: fix the :X string interpolation format for isize/usize on 64bit systems 2021-09-19 05:09:03 +03:00
Alexander Medvednikov
6799f3ac5c orm: verify column name in updates 2021-09-19 04:49:29 +03:00
Rémi
e76be4ba37 checker: temporary error for optional struct fields (#11293) (#11534) 2021-09-18 23:22:24 +03:00
Delyan Angelov
0b4e03ad5c ci: fix the failing new options_test.v on the ubuntu job 2021-09-18 21:10:41 +03:00
Delyan Angelov
6b2cc9c5cf v.pref: add a simple options_test.v to check for -cflags regressions 2021-09-18 16:08:15 +03:00
yuyi
8501217a4e cgen: add gen_free_for_type_array/map() (#11530) 2021-09-18 15:18:32 +03:00
Delyan Angelov
f5efa93570 ci: disable tests-sanitize-address-msvc for now 2021-09-18 15:14:17 +03:00
Delyan Angelov
0a7fb34613 checker: simplify noreturn.v 2021-09-18 13:43:15 +03:00
czkz
396eede4db math: fix typos (#11533) 2021-09-18 12:23:31 +03:00
Delyan Angelov
740af306c0 ci: use quotes for "/fsanitize=address" in tests-sanitize-address-msvc 2021-09-18 12:08:09 +03:00
Delyan Angelov
df8a4a03a0 tests: support // vtest retry: 4 for marking flaky tests 2021-09-18 11:48:32 +03:00
Delyan Angelov
eec930b86a os: turn some panics into return error() 2021-09-18 10:45:04 +03:00
Delyan Angelov
209b159554 ci: fix tests-sanitize-address-msvc job (pass proper /fsanitize=address option) 2021-09-18 10:05:35 +03:00
yuyi
39ad6da506 checker, cgen: generate .free() methods for custom structs automatically (#11529) 2021-09-18 09:38:42 +03:00
Delyan Angelov
2eeba4758a v.builder: fix -cc msvc -cflags /O2 and support CFLAGS and LDFLAGS env vars 2021-09-18 09:14:21 +03:00
Alexander Medvednikov
219a764a83 autofree: only free user reference types 2021-09-18 06:32:25 +03:00
Alexander Medvednikov
6d47dd22df autofree: free references 2021-09-18 04:19:16 +03:00
yuyi
44ec8a8cd4 v.fmt, v.gen.js: use 'if foo in [TypeA, TypeB]' in fmt.v and js.v (#11524) 2021-09-17 21:59:16 +03:00
Delyan Angelov
bd65ceb463 v.markused: remove __print_assert_failure from all_fn_root_names 2021-09-17 21:47:22 +03:00
Ruofan XU
9180647f99 scanner, fmt: fix multi-level generics (#11517) 2021-09-17 21:44:31 +03:00
Alexander Ivanov
30e53c95c7 checker: handle if _likely_(x is Interface) { from #11485 (#11519) 2021-09-17 21:01:12 +03:00
yuyi
fb75d528eb builder: remove panics, when cleaning up tmp files after tests (#11525) 2021-09-17 20:56:33 +03:00
czkz
816c6c62b5 os: fix documentation typo in args.v (#11526) 2021-09-17 20:55:16 +03:00
Michele Zenoni
92bb292113 examples: add Rule 110 example (#11516) 2021-09-17 03:24:28 +03:00
Vincent Laisney
273154c1ae math.big: add Newton and Karatsuba algorithms (#11487) 2021-09-16 19:31:07 +03:00
yuyi
467afad065 cgen: use if foo in [TypeA, TypeB] in cgen.v (#11518) 2021-09-16 19:26:53 +03:00
JalonSolov
1688148828 flag: switch panics to optionals (#11515) 2021-09-16 19:25:05 +03:00
Delyan Angelov
0a18690a4f v.gen.c: fix assert f().len == 1 calling f() twice (closes issue 11501) 2021-09-16 19:01:35 +03:00
playX
c175b4fd48 v.gen.js: refactor code, fix alias codegen, -stats now again works with tests on the JS backend (#11512) 2021-09-16 14:00:15 +03:00
Miccah
ead5e66afd net.http: add post_multipart_form function (#11511) 2021-09-16 07:34:07 +03:00
Dialga
f295469fac net.urllib: make unescape() autofree compatible (#11510) 2021-09-16 07:09:20 +03:00
yuyi
d5e00b0920 checker, cgen: fix generic arrays sum() (#11502) 2021-09-16 07:08:28 +03:00
yuyi
09ded16e3d checker: use 'if foo in [TypeA, TypeB]' in checker.v (#11494) 2021-09-16 07:08:14 +03:00
playX
7d1776b84d js: equality method generation for V types (#11503) 2021-09-16 07:07:48 +03:00
Alexander Medvednikov
d00808660f json: omitempty 2021-09-16 07:02:43 +03:00
Delyan Angelov
5bc6cc9512 v.checker: fix spurious warning for if x := map_of_sumtypes[k] {} 2021-09-15 15:42:28 +03:00
JalonSolov
7145461cc5 arrays: switch panics to optionals (#11497) 2021-09-15 15:17:55 +03:00
yuyi
ef690dc06b testing: remove panics when cleaning up after test runs (#11505) 2021-09-15 15:15:46 +03:00
1018 changed files with 61998 additions and 17902 deletions

View File

@@ -1,7 +1,8 @@
freebsd_instance:
image_family: freebsd-13-0
task:
freebsd_task:
name: Code CI / freebsd
install_script: pkg install -y git
script: |
echo 'Building V'
@@ -12,3 +13,76 @@ task:
##tcc -v -v
echo 'Build cmd/tools/fast'
cd cmd/tools/fast && ../../../v fast.v && ./fast -clang
arm64_task:
name: Code CI / arm64-ubuntu-tcc
arm_container:
image: ubuntu:latest
install_script: apt-get update -y && apt-get install --quiet -y build-essential pkg-config wget git valgrind libsqlite3-dev libssl-dev libxi-dev libxcursor-dev libfreetype6-dev libxi-dev libxcursor-dev libgl-dev xfonts-75dpi xfonts-base libmysqlclient-dev libpq-dev gcc-10-arm-linux-gnueabihf libc6-dev-armhf-cross qemu-user
env:
DEBIAN_FRONTEND: noninteractive
VFLAGS: -cc tcc -no-retry-compilation
VJOBS: 2
script: |
set -e
wget https://github.com/wkhtmltopdf/packaging/releases/download/0.12.6-1/wkhtmltox_0.12.6-1.focal_arm64.deb
apt install --fix-missing -y ./wkhtmltox_0.12.6-1.focal_arm64.deb
# ensure that a V binary can be built, even if tcc has broken for some reason
VFLAGS='-cc gcc' make
./v -g self
./v -g self
./v -d debug_malloc -d debug_realloc -o v cmd/v
./v -cg -cstrict -o v cmd/v
#Test v->c
thirdparty/tcc/tcc.exe -version
./v -cg -o v cmd/v # Make sure vtcc can build itself twice
# - name: v self compilation
./v -o v2 cmd/v && ./v2 -o v3 cmd/v && ./v3 -o v4 cmd/v
# - name: v self compilation with -skip-unused
./v -skip-unused -o v2 cmd/v && ./v2 -skip-unused -o v3 cmd/v && ./v3 -skip-unused -o v4 cmd/v
# - name: v doctor
./v doctor
# - name: Verify `v test` works
./v cmd/tools/test_if_v_test_system_works.v
./cmd/tools/test_if_v_test_system_works
# - name: Self tests
./v -silent test-self
## - name: Self tests (-cstrict)
## ./v -cstrict test-self
# - name: Test time functions in a timezone UTC-12
TZ=Etc/GMT+12 ./v test vlib/time/
# - name: Test time functions in a timezone UTC-3
TZ=Etc/GMT+3 ./v test vlib/time/
# - name: Test time functions in a timezone UTC+3
TZ=Etc/GMT-3 ./v test vlib/time/
# - name: Test time functions in a timezone UTC+12
TZ=Etc/GMT-12 ./v test vlib/time/
# - name: Test time functions in a timezone using daylight saving (Europe/Paris)
TZ=Europe/Paris ./v test vlib/time/
# - name: Build examples
./v -W build-examples
# - name: Test building v tools
./v -W build-tools
# - name: Test v binaries
./v build-vbinaries
# - name: Run a VSH script
./v run examples/v_script.vsh
# - name: Test v tutorials
./v tutorials/building_a_simple_web_blog_with_vweb/code/blog
# test the arm32 version of tcc
# TODO: support something like `V_EMULATOR=qemu-arm v run file.v` so that V automatically runs all binaries under qemu
./v -arch arm32 -cc arm-linux-gnueabihf-gcc-10 -o av cmd/v && qemu-arm -L /usr/arm-linux-gnueabihf ./av -arch arm32 -cc arm-linux-gnueabihf-gcc-10 -o av2 cmd/v && qemu-arm -L /usr/arm-linux-gnueabihf ./av2 -arch arm32 -cc arm-linux-gnueabihf-gcc-10 -o av3 cmd/v && qemu-arm -L /usr/arm-linux-gnueabihf ./av3 -arch arm32 -cc arm-linux-gnueabihf-gcc-10 -o av4 cmd/v
./v -arch arm32 -o closure_test.c vlib/v/tests/closure_test.v && arm-linux-gnueabihf-gcc-10 -o closure_test closure_test.c && qemu-arm -L /usr/arm-linux-gnueabihf ./closure_test

1
.gitattributes vendored
View File

@@ -2,3 +2,4 @@
*.vv linguist-language=V text=auto eol=lf
*.bat text=auto eol=crlf
Dockerfile.* linguist-language=Dockerfile
*.toml text eol=lf

View File

@@ -12,86 +12,96 @@ jobs:
runs-on: ubuntu-20.04
env:
CC: gcc
ZIPNAME: v_linux.zip
steps:
- uses: actions/checkout@v1
- name: Compile
run: |
make -j4
./v -cc $CC -o v -prod cmd/v
./v -prod cmd/tools/vup.v
./v -prod cmd/tools/vdoctor.v
make -j4
./v -cc $CC -prod -o v cmd/v
./v -cc $CC -prod cmd/tools/vup.v
./v -cc $CC -prod cmd/tools/vdoctor.v
- name: Remove excluded
run: |
rm -rf .git
rm -rf vc/
rm -rf v_old
- name: Create ZIP archive
run: |
cd ..
zip -r9 --symlinks $ZIPNAME v/
mv $ZIPNAME v/
cd v/
- name: Create artifact
uses: actions/upload-artifact@v2
with:
name: linux
path: |
.
./cmd/tools/vup
./cmd/tools/vdoctor
!./.git
!./vc
!./v_old
- name: Create binary only artifact
uses: actions/upload-artifact@v2
with:
name: linux-binary
path: ./v
path: v_linux.zip
build-macos:
runs-on: macos-latest
env:
CC: clang
ZIPNAME: v_macos.zip
steps:
- uses: actions/checkout@v1
- name: Compile
env:
CC: clang
run: |
make -j4
./v -cc $CC -o v -prod cmd/v
./v -prod cmd/tools/vup.v
./v -prod cmd/tools/vdoctor.v
./v -cc $CC -prod -o v cmd/v
./v -cc $CC -prod cmd/tools/vup.v
./v -cc $CC -prod cmd/tools/vdoctor.v
- name: Remove excluded
run: |
rm -rf .git
rm -rf vc/
rm -rf v_old
- name: Create ZIP archive
run: |
cd ..
zip -r9 --symlinks $ZIPNAME v/
mv $ZIPNAME v/
cd v/
- name: Create artifact
uses: actions/upload-artifact@v2
with:
name: macos
path: |
.
./cmd/tools/vup
./cmd/tools/vdoctor
!./.git
!./vc
!./v_old
- name: Create binary only artifact
uses: actions/upload-artifact@v2
with:
name: macos-binary
path: ./v
path: v_macos.zip
build-windows:
runs-on: windows-latest
env:
CC: msvc
ZIPNAME: v_windows.zip
steps:
- uses: actions/checkout@v1
- uses: msys2/setup-msys2@v2
- name: Compile
run: |
.\make.bat
.\make.bat -tcc
.\v.exe cmd\tools\vup.v
.\v.exe cmd\tools\vdoctor.v
- name: Remove excluded
shell: msys2 {0}
run: |
rm -rf .git
rm -rf vc/
rm -rf v_old.exe
- name: Create archive
shell: msys2 {0}
run: |
cd ..
powershell Compress-Archive v $ZIPNAME
mv $ZIPNAME v/
cd v/
# NB: the powershell Compress-Archive line is from:
# https://superuser.com/a/1336434/194881
# It is needed, because `zip` is not installed by default :-|
- name: Create artifact
uses: actions/upload-artifact@v2
with:
name: windows
path: |
.
./cmd/tools/vup.exe
./cmd/tools/vdoctor.exe
!./.git
!./vc
!./v_old.exe
- name: Create binary only artifact
uses: actions/upload-artifact@v2
with:
name: windows-binary
path: ./v.exe
path: v_windows.zip
release:
name: Create Github Release
@@ -128,23 +138,6 @@ jobs:
with:
name: ${{ matrix.version }}
path: ./${{ matrix.version }}
- name: Build Zip Archives
run: |
mkdir -p workdir/
mv ${{ matrix.version }}/ workdir/v/
cd workdir/v/
chmod 755 v || true
chmod 755 v.exe || true
chmod 755 thirdparty/tcc/tcc.exe || true
chmod 755 cmd/tools/vup || true
chmod 755 cmd/tools/vup.exe || true
chmod 755 cmd/tools/vdoctor || true
chmod 755 cmd/tools/vdoctor.exe || true
rm -rf v_old v_old.exe
cd ..
zip -r9 --symlinks ../v_${{ matrix.version }}.zip v/*
cd ..
rm -rf workdir/
- name: Get short tag name
uses: jungwinter/split@v1
id: split
@@ -165,6 +158,6 @@ jobs:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.get_release_info.outputs.upload_url }}
asset_path: ./v_${{ matrix.version }}.zip
asset_path: ${{ matrix.version }}/v_${{ matrix.version }}.zip
asset_name: v_${{ matrix.version }}.zip
asset_content_type: application/zip

View File

@@ -42,9 +42,9 @@ jobs:
- name: Build the repeat tool
run: ./v cmd/tools/repeat.v
- name: Repeat -o hw.c examples/hello_world.v
run: cmd/tools/repeat --max_time 201 --series 3 --count 20 --nmins 2 --nmaxs 5 --warmup 3 --fail_percent 10 -t 'cd {T} ; ./v -show-timings -o hw.c examples/hello_world.v' . ./vmaster
run: cmd/tools/repeat --max_time 251 --series 3 --count 20 --nmins 2 --nmaxs 5 --warmup 3 --fail_percent 10 -t 'cd {T} ; ./v -show-timings -o hw.c examples/hello_world.v' . ./vmaster
- name: Repeat -o v.c cmd/v
run: cmd/tools/repeat --max_time 1201 --series 3 --count 20 --nmins 2 --nmaxs 5 --warmup 3 --fail_percent 10 -t 'cd {T} ; ./v -show-timings -o v.c cmd/v' . ./vmaster
run: cmd/tools/repeat --max_time 1501 --series 3 --count 20 --nmins 2 --nmaxs 5 --warmup 3 --fail_percent 10 -t 'cd {T} ; ./v -show-timings -o v.c cmd/v' . ./vmaster
ubuntu-tcc:
needs: no-scheduling
@@ -188,24 +188,6 @@ jobs:
- name: Build v
run: make
- name: v.c can be compiled and run with -os cross
run: |
./v -os cross -o /tmp/v.c cmd/v
gcc -g -std=gnu11 -w -o v_from_vc /tmp/v.c -lm -lpthread
ls -lart v_from_vc
./v_from_vc version
- name: Ensure v up works
run: |
./v cmd/tools/oldv.v
./cmd/tools/oldv -v HEAD^^^^^
cd ~/.cache/oldv/v_at_HEAD_____/
./v version
./v -v up
./v version
./v -o v2 cmd/v
./v2 -o v3 cmd/v
- name: Ensure V can be compiled with -autofree
run: ./v -autofree -o v2 cmd/v ## NB: this does not mean it runs, but at least keeps it from regressing
@@ -235,7 +217,7 @@ jobs:
- name: g++ version
run: g++-9 --version
- name: V self compilation with g++
run: ./v -cc g++-9 -o v2 cmd/v && ./v2 -cc g++-9 -o v3 cmd/v
run: ./v -cc g++-9 -no-std -cflags -std=c++11 -o v2 cmd/v && ./v2 -cc g++-9 -no-std -cflags -std=c++11 -o v3 cmd/v
## - name: Running tests with g++
## run: ./v -cc g++-9 -silent test-self
@@ -257,18 +239,20 @@ jobs:
- name: Checkout
uses: actions/checkout@v2
- name: Build V
run: |
make CC=clang
- name: Show PWD and Environment
- name: Show Environment
run: |
echo "PWD:"
pwd
echo "ENVIRONMENT"
echo "ENVIRONMENT:"
env
echo "C Compiler:"
gcc --version
- name: Build V
run: CC=gcc make
- name: Test V fixed tests
run: |
./v -silent test-self
run: ./v -silent test-self
macos:
needs: no-scheduling
@@ -276,6 +260,7 @@ jobs:
timeout-minutes: 121
env:
VFLAGS: -cc clang
PKG_CONFIG_PATH: /usr/local/opt/openssl@3/lib/pkgconfig
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v1
@@ -285,8 +270,9 @@ jobs:
run: |
##brew install libpq openssl freetype ### these are *already installed* on Catalina ...
brew uninstall --ignore-dependencies libpq ## libpq is a dependency of PHP
brew install postgresql
brew install postgresql openssl
export LIBRARY_PATH="$LIBRARY_PATH:/usr/local/opt/openssl/lib/"
echo "PKG_CONFIG_PATH is '$PKG_CONFIG_PATH'"
- name: Build V
run: make -j4 && ./v -cg -cstrict -o v cmd/v
- name: Run sanitizers
@@ -320,13 +306,6 @@ jobs:
./v cmd/tools/test_if_v_test_system_works.v
./cmd/tools/test_if_v_test_system_works
- name: v.c can be compiled and run with -os cross
run: |
./v -os cross -o /tmp/v.c cmd/v
cc -g -std=gnu11 -w -o v_from_vc /tmp/v.c -lm -lpthread
ls -lart v_from_vc
./v_from_vc version
- name: Self tests
run: VJOBS=1 ./v -silent test-self
@@ -627,7 +606,7 @@ jobs:
gcc --version
.\make.bat -gcc
- name: Test new v.c
run: .\v.exe -o v.c cmd/v && gcc -Werror -municode -w v.c
run: .\v.exe -o v.c cmd/v && gcc -Werror -I ./thirdparty/stdatomic/win -municode -w v.c
- name: Install dependencies
run: |
.\v.exe setup-freetype
@@ -669,7 +648,7 @@ jobs:
run: |
echo %VFLAGS%
echo $VFLAGS
.\make.bat -msvc --verbose
.\make.bat -msvc
.\v.exe -cflags /WX self
- name: Install dependencies
run: |
@@ -713,9 +692,9 @@ jobs:
node-version: 12.x
- name: Build with make.bat -tcc
run: |
.\make.bat -tcc --verbose
.\make.bat -tcc
- name: Test new v.c
run: .\v.exe -o v.c cmd/v && .\thirdparty\tcc\tcc.exe -Werror -w -ladvapi32 -bt10 v.c
run: .\v.exe -o v.c cmd/v && .\thirdparty\tcc\tcc.exe -I ./thirdparty/stdatomic/win -Werror -w -ladvapi32 -bt10 v.c
- name: Install dependencies
run: |
.\v.exe setup-freetype
@@ -757,45 +736,45 @@ jobs:
- name: v2 self compilation
run: .\v.exe -o v2.exe cmd/v && .\v2.exe -o v3.exe cmd/v
## tcc32
- name: Build with make.bat -tcc32
run: |
Remove-Item -Recurse -Force .\thirdparty\tcc
.\v.exe wipe-cache
.\make.bat -tcc32 --verbose
- name: Test new v.c
run: .\v.exe -o v.c cmd/v && .\thirdparty\tcc\tcc.exe -Werror -w -ladvapi32 -bt10 v.c
- name: v doctor
run: ./v doctor
- name: Verify `v test` works
run: |
.\v.exe cmd/tools/test_if_v_test_system_works.v
.\cmd\tools\test_if_v_test_system_works.exe
- name: Verify `v vlib/v/gen/c/coutput_test.v` works
run: |
.\v.exe vlib/v/gen/c/coutput_test.v
- name: Make sure running TCC32 instead of TCC64
run: ./v -stats .github\workflows\make_sure_ci_run_with_32bit_compiler_test.v
- name: Test v build-tools
run: ./v -W build-tools
- name: Test ./v doc clipboard
run: ./v doc clipboard
- name: Self tests
run: ./v test-self
- name: Test v->js
run: ./v -o hi.js examples/hello_v_js.v && node hi.js
- name: Test v binaries
run: ./v build-vbinaries
- name: Build examples
run: ./v build-examples
- name: v2 self compilation
run: .\v.exe -o v2.exe cmd/v && .\v2.exe -o v3.exe cmd/v
## ## tcc32
## - name: Build with make.bat -tcc32
## run: |
## Remove-Item -Recurse -Force .\thirdparty\tcc
## .\v.exe wipe-cache
## .\make.bat -tcc32
## - name: Test new v.c
## run: .\v.exe -o v.c cmd/v && .\thirdparty\tcc\tcc.exe -I ./thirdparty/stdatomic/win -Werror -g -w -ladvapi32 -bt10 v.c
## - name: v doctor
## run: ./v doctor
##
## - name: Verify `v test` works
## run: |
## .\v.exe cmd/tools/test_if_v_test_system_works.v
## .\cmd\tools\test_if_v_test_system_works.exe
##
## - name: Verify `v vlib/v/gen/c/coutput_test.v` works
## run: |
## .\v.exe vlib/v/gen/c/coutput_test.v
##
## - name: Make sure running TCC32 instead of TCC64
## run: ./v -stats .github\workflows\make_sure_ci_run_with_32bit_compiler_test.v
##
## - name: Test v build-tools
## run: ./v -W build-tools
##
## - name: Test ./v doc clipboard
## run: ./v doc clipboard
##
## - name: Self tests
## run: ./v test-self
## - name: Test v->js
## run: ./v -o hi.js examples/hello_v_js.v && node hi.js
## - name: Test v binaries
## run: ./v build-vbinaries
## - name: Build examples
## run: ./v build-examples
## - name: v2 self compilation
## run: .\v.exe -o v2.exe cmd/v && .\v2.exe -o v3.exe cmd/v
parser-silent:
needs: no-scheduling
@@ -847,22 +826,40 @@ jobs:
run: make && sudo ./v symlink
## vls
- name: Clone tree-sitter-v to ~/.vmodules/tree_sitter_v
run: git clone --depth 1 https://github.com/nedpals/tree-sitter-v ~/.vmodules/tree_sitter_v
- name: Clone VLS tree-sitter
run: git clone --depth 1 --no-single-branch https://github.com/vlang/vls
- name: Checkout branch tree-sitter
run: pushd vls; git checkout use-tree-sitter; popd
- name: Build VLS tree-sitter
- name: Clone VLS
run: git clone --depth 1 https://github.com/vlang/vls
- name: Build VLS
run: pushd vls; v cmd/vls ; popd
- name: Build VLS tree-sitter with -prod
- name: Build VLS with -prod
run: pushd vls; v -prod cmd/vls; popd
- name: Checkout branch master
run: pushd vls; git checkout master; popd
- name: Build VLS master
run: pushd vls; v cmd/vls ; popd
- name: Build VLS master with -prod
run: pushd vls; v -prod cmd/vls ; popd
## vsl
- name: Clone VSL
run: git clone --depth 1 https://github.com/vlang/vsl ~/.vmodules/vsl
- name: Install dependencies
run: sudo apt-get install --quiet -y --no-install-recommends gfortran liblapacke-dev libopenblas-dev libgc-dev
- name: Execute Tests using Pure V Backend
run: ~/.vmodules/vsl/bin/test
- name: Execute Tests using Pure V Backend with Pure V Math
run: ~/.vmodules/vsl/bin/test --use-cblas
- name: Execute Tests using Pure V Backend and Garbage Collection enabled
run: ~/.vmodules/vsl/bin/test --use-gc boehm
- name: Execute Tests using Pure V Backend with Pure V Math and Garbage Collection enabled
run: ~/.vmodules/vsl/bin/test --use-cblas --use-gc boehm
## vtl
- name: Clone VTL
run: git clone --depth 1 https://github.com/vlang/vtl ~/.vmodules/vtl
- name: Install dependencies
run: sudo apt-get install --quiet -y --no-install-recommends gfortran liblapacke-dev libopenblas-dev libgc-dev
- name: Execute Tests using Pure V Backend
run: ~/.vmodules/vtl/bin/test
- name: Execute Tests using Pure V Backend with Pure V Math
run: ~/.vmodules/vtl/bin/test --use-cblas
- name: Execute Tests using Pure V Backend and Garbage Collection enabled
run: ~/.vmodules/vtl/bin/test --use-gc boehm
- name: Execute Tests using Pure V Backend with Pure V Math and Garbage Collection enabled
run: ~/.vmodules/vtl/bin/test --use-cblas --use-gc boehm
## vab
- name: Clone vab
@@ -880,6 +877,8 @@ jobs:
../v .
# ./gitly -ci_run
../v -autofree .
../v -o x tests/first_run.v
./x
cd ..
## vex

View File

@@ -0,0 +1,77 @@
name: Bootstraping works
on:
push:
paths-ignore:
- "**.md"
pull_request:
paths-ignore:
- "**.md"
jobs:
ubuntu:
runs-on: ubuntu-20.04
timeout-minutes: 15
env:
VFLAGS: -cc tcc -no-retry-compilation
B_CFLAGS: -g -std=gnu11 -I ./thirdparty/stdatomic/nix -w
B_LFLAGS: -lm -lpthread
steps:
- uses: actions/checkout@v2
with:
fetch-depth: 10
- name: Build v
run: make
- name: v.c can be compiled and run with -os cross (bootstrapping works)
run: |
ls -la v vc/v.c
./v -os cross -o vc/v.c cmd/v
gcc $B_CFLAGS -o v_from_vc vc/v.c $B_LFLAGS
ls -lart v_from_vc
./v_from_vc version
./v_from_vc run examples/hello_world.v
./v_from_vc -o v_from_vc_produced_native_v cmd/v
./v_from_vc_produced_native_v run examples/hello_world.v
make local=1
ls -la v vc/v.c v_from_vc v_from_vc_produced_native_v
- name: Ensure v up works
run: |
./v cmd/tools/oldv.v
./cmd/tools/oldv -v HEAD^^^^^
cd ~/.cache/oldv/v_at_HEAD_____/
./v version
./v -v up
./v version
./v -o v2 cmd/v
./v2 -o v3 cmd/v
macos:
runs-on: macos-11
timeout-minutes: 15
env:
VFLAGS: -cc clang
B_CFLAGS: -g -std=gnu11 -I ./thirdparty/stdatomic/nix -w
B_LFLAGS: -lm -lpthread
steps:
- uses: actions/checkout@v2
with:
fetch-depth: 10
- name: Build V
run: make && ./v -cg -cstrict -o v cmd/v
- name: v.c can be compiled and run with -os cross (bootstrapping works)
run: |
ls -la v vc/v.c
./v -os cross -o vc/v.c cmd/v
cc $B_CFLAGS -o v_from_vc vc/v.c $B_LFLAGS
ls -lart v_from_vc
./v_from_vc version
./v_from_vc run examples/hello_world.v
./v_from_vc -o v_from_vc_produced_native_v cmd/v
./v_from_vc_produced_native_v run examples/hello_world.v
### the next make invocation will simulate building V from scratch,
### using this commit
make local=1
ls -la v vc/v.c v_from_vc v_from_vc_produced_native_v

View File

@@ -19,23 +19,23 @@ jobs:
- uses: actions/checkout@v2
with:
fetch-depth: 10
- name: Install dependencies
run: |
brew install mingw-w64
export LIBRARY_PATH="$LIBRARY_PATH:/usr/local/opt/openssl/lib/"
- name: Build V
run: make
- name: Test symlink
run: ./v symlink
- name: Cross-compilation to Linux
run: |
./v -os linux cmd/v
# TODO: fix this: ./v -os linux examples/2048/2048.v
- name: Cross-compilation to Windows
run: |
./v -os windows cmd/v
@@ -52,35 +52,37 @@ jobs:
fetch-depth: 10
- name: Install dependencies
run: |
## sudo dpkg --add-architecture i386
sudo apt update
sudo apt-get install --quiet -y libssl-dev sqlite3 libsqlite3-dev valgrind
sudo apt-get install --quiet -y libssl-dev sqlite3 libsqlite3-dev
sudo apt-get install --quiet -y mingw-w64 wine-stable winetricks
## sudo apt-get install --quiet -y wine32
- name: Turn off the wine crash dialog
run: winetricks nocrashdialog
- name: Build v
run: make
- name: v.c can be compiled and run with -os cross
run: |
./v -os cross -o /tmp/v.c cmd/v
gcc -g -std=gnu11 -w -o v_from_vc /tmp/v.c -lm -lpthread
gcc -g -std=gnu11 -I ./thirdparty/stdatomic/nix -w -o v_from_vc /tmp/v.c -lm -lpthread
ls -lart v_from_vc
./v_from_vc version
- name: v_win.c can be compiled and run with -os windows
run: |
./v -os windows -o /tmp/v_win.c cmd/v
x86_64-w64-mingw32-gcc /tmp/v_win.c -std=c99 -w -municode -o v_from_vc.exe
x86_64-w64-mingw32-gcc -I ./thirdparty/stdatomic/win /tmp/v_win.c -std=c99 -w -municode -o v_from_vc.exe
ls -lart v_from_vc.exe
wine v_from_vc.exe version
wine64 ./v_from_vc.exe version
- name: hello_world.v can be cross compiled to hello_world.exe
run: |
./v -os windows examples/hello_world.v
ls -lart examples/hello_world.exe
wine examples/hello_world.exe
wine64 examples/hello_world.exe
- name: 2048.v can be cross compiled to 2048.exe
run: |
./v -os windows examples/2048/2048.v
@@ -97,10 +99,11 @@ jobs:
run: |
echo %VFLAGS%
echo $VFLAGS
.\make.bat --verbose -msvc
.\make.bat -msvc
- name: TODO v_win.c can be compiled and run with -os windows
run: |
.\v.exe -os windows -showcc -o v2.exe cmd\v
.\v.exe -os windows -o v_win.c cmd\v
dir v2.exe
dir v_win.c
.\v2.exe version

View File

@@ -159,14 +159,14 @@ jobs:
echo %VFLAGS%
echo $VFLAGS
.\make.bat -msvc
.\v.exe -cflags /WX self
- name: Install dependencies
run: |
.\v.exe setup-freetype
.\.github\workflows\windows-install-sqlite.bat
- name: Self tests (-fsanitize=address)
run: |
.\v.exe -cflags -fsanitize=address test-self
.\v.exe self
## - name: Install dependencies
## run: |
## .\v.exe setup-freetype
## .\.github\workflows\windows-install-sqlite.bat
## - name: Self tests (TODO: /fsanitize=address)
## run: |
## .\v.exe -cflags "/fsanitize=address" test-self
tests-sanitize-address-gcc:
needs: no-scheduling

View File

@@ -18,7 +18,7 @@ jobs:
run: |
echo %VFLAGS%
echo $VFLAGS
.\make.bat --verbose -msvc
.\make.bat -msvc
.\v.exe -cflags /WX self
- name: Install dependencies
run: |

53
.github/workflows/gfx_ci.yml vendored Normal file
View File

@@ -0,0 +1,53 @@
name: Graphics CI
on:
push:
paths-ignore:
- "**.md"
pull_request:
paths-ignore:
- "**.md"
jobs:
gg-regressions:
runs-on: ubuntu-18.04
timeout-minutes: 10
env:
VFLAGS: -cc tcc
DISPLAY: :99
steps:
- name: Checkout V
uses: actions/checkout@v2
- name: Build local v
run: make -j4
- name: Setup dependencies
run: |
# xvfb : xvfb (installed by openrndr/setup-opengl@v1.1)
# openimageio-tools : idiff
# libxcursor-dev libxi-dev : V gfx deps
# mesa-common-dev : For headless rendering
# freeglut3-dev : Fixes graphic apps compilation with tcc
sudo apt-get install imagemagick openimageio-tools mesa-common-dev libxcursor-dev libxi-dev freeglut3-dev
wget https://raw.githubusercontent.com/tremby/imgur.sh/c98345d/imgur.sh
chmod +x ./imgur.sh
- uses: openrndr/setup-opengl@v1.1
- uses: actions/checkout@v2
with:
repository: Larpon/gg-regression-images
path: gg-regression-images
- name: Sample and compare
id: compare
continue-on-error: true
run: |
Xvfb $DISPLAY -screen 0 1280x1024x24 &
./v gret -t ./gg-regression-images/vgret.v_examples.toml -v ./gg-sample_images ./gg-regression-images
- name: Upload regression to imgur
if: steps.compare.outcome != 'success'
run: |
./imgur.sh /tmp/fail.png
exit 1

70
.github/workflows/toml_ci.yml vendored Normal file
View File

@@ -0,0 +1,70 @@
name: toml CI
on:
push:
paths-ignore:
- "**.md"
pull_request:
paths-ignore:
- "**.md"
jobs:
toml-module-pass-external-test-suites:
runs-on: ubuntu-18.04
timeout-minutes: 10
env:
TOML_BS_TESTS_PATH: vlib/toml/tests/testdata/burntsushi/toml-test
TOML_BS_TESTS_PINNED_COMMIT: eb989e5
TOML_IARNA_TESTS_PATH: vlib/toml/tests/testdata/iarna/toml-test
TOML_IARNA_TESTS_PINNED_COMMIT: 1880b1a
TOML_ALEXCRICHTON_TESTS_PATH: vlib/toml/tests/testdata/alexcrichton/toml-test
TOML_ALEXCRICHTON_TESTS_PINNED_COMMIT: 499e8c4
steps:
- uses: actions/checkout@v2
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install --quiet -y jq
- name: Build V
run: make -j2 && ./v -cc gcc -o v cmd/v
- name: Run local TOML tests
run: ./v test vlib/toml
# Tests found at https://github.com/BurntSushi/toml-test
- name: Clone BurntSushi/toml-test
run: |
git clone https://github.com/BurntSushi/toml-test.git $TOML_BS_TESTS_PATH
## TODO: update/remove this pinning once all our skip lists are empty:
git -C $TOML_BS_TESTS_PATH checkout $TOML_BS_TESTS_PINNED_COMMIT
- name: Run BurntSushi TOML tests
run: ./v vlib/toml/tests/burntsushi.toml-test_test.v
# Tests found at gist
- name: Get large_toml_file_test.toml
run: wget https://gist.githubusercontent.com/Larpon/89b0e3d94c6903851ff15559e5df7a05/raw/62a1f87a4e37bf157f2e0bfb32d85d840c98e422/large_toml_file_test.toml -O vlib/toml/tests/testdata/large_toml_file_test.toml
- name: Run large TOML file tests
run: ./v vlib/toml/tests/large_toml_file_test.v
# Tests found at https://github.com/iarna/toml-spec-tests
- name: Clone iarna/toml-spec-tests
run: |
git clone https://github.com/iarna/toml-spec-tests.git $TOML_IARNA_TESTS_PATH
## TODO: update/remove this pinning once all our skip lists are empty:
git -C $TOML_IARNA_TESTS_PATH checkout $TOML_IARNA_TESTS_PINNED_COMMIT
- name: Run iarna TOML tests
run: ./v vlib/toml/tests/iarna.toml-spec-tests_test.v
# Tests found at https://github.com/alexcrichton/toml-rs
- name: Clone alexcrichton/toml-rs
run: |
git clone https://github.com/alexcrichton/toml-rs.git $TOML_ALEXCRICHTON_TESTS_PATH
## TODO: update/remove this pinning once all our skip lists are empty:
git -C $TOML_ALEXCRICHTON_TESTS_PATH checkout $TOML_ALEXCRICHTON_TESTS_PINNED_COMMIT
- name: Run alexcrichton TOML tests
run: ./v vlib/toml/tests/alexcrichton.toml-rs-tests_test.v

View File

@@ -20,7 +20,8 @@ jobs:
- name: Build V
run: make
- name: Clone current Vinix
run: git clone https://github.com/vlang/vinix.git --depth=1
run: |
git clone https://github.com/vlang/vinix.git --depth 1
- name: Clone current mlibc
run: git clone https://github.com/managarm/mlibc.git --depth=1
- name: Patch mlibc for Vinix

6
.gitignore vendored
View File

@@ -20,6 +20,7 @@ vdbg.exe
*.dll
*.lib
*.bak
*.dylib
a.out
.noprefix.vrepl_temp
@@ -99,3 +100,8 @@ shell.nix
default.nix
flake.nix
.envrc
thirdparty/stdatomic/nix/cpp/*.h
# ignore VLS log
vls.log

View File

@@ -183,17 +183,19 @@ to create a copy of the compiler rather than replacing it with `v self`.
| Flag | Usage |
|------|-------|
| `debugautostr` | Prints informations about `.str()` method auto-generated by the compiler during C generation |
| `debugscanner` | Prints debug information during the scanning phase |
| `debug_codegen` | Prints automatically generated V code during the scanning phase |
| `debug_interface_table` | Prints generated interfaces during C generation |
| `debug_interface_type_implements` | Prints debug information when checking that a type implements in interface |
| `debug_embed_file_in_prod` | Prints debug information about the embedded files with `$embed_file('somefile')` |
| `print_vweb_template_expansions` | Prints vweb compiled HTML files |
| `time_checking` | Prints the time spent checking files and other related informations |
| `time_parsing` | Prints the time spent parsing files and other related informations |
| `time_checking` | Prints the time spent checking files and other related information |
| `time_parsing` | Prints the time spent parsing files and other related information |
| `trace_autofree` | Prints details about how/when -autofree puts free() calls |
| `trace_autostr` | Prints details about `.str()` method auto-generated by the compiler during C generation |
| `trace_ccoptions` | Prints options passed down to the C compiler |
| `trace_checker` | Prints informations about the statements being checked |
| `trace_checker` | Prints details about the statements being checked |
| `trace_gen` | Prints strings written to the generated C file. Beware, this flag is very verbose |
| `trace_parser` | Prints informations about parsed statements and expressions |
| `trace_thirdparty_obj_files` | Prints informations about built thirdparty obj files |
| `trace_use_cache` | Prints informations about cache use |
| `trace_parser` | Prints details about parsed statements and expressions |
| `trace_thirdparty_obj_files` | Prints details about built thirdparty obj files |
| `trace_usecache` | Prints details when -usecache is used |

View File

@@ -4,7 +4,7 @@ LABEL maintainer="Vitaly Takmazov <vitalyster@gmail.com>"
COPY . .
RUN make
RUN ./v -os windows -o v.c cmd/v
RUN x86_64-w64-mingw32-gcc v.c -std=c99 -w -municode -o v.exe
RUN x86_64-w64-mingw32-gcc v.c -std=c99 -I ./thirdparty/stdatomic/win -w -municode -o v.exe
RUN file v.exe
CMD [ "bash" ]

View File

@@ -84,13 +84,16 @@ endif
all: latest_vc latest_tcc
ifdef WIN32
$(CC) $(CFLAGS) -std=c99 -municode -w -o $(V) $(VC)/$(VCFILE) $(LDFLAGS)
$(V) -o v2.exe $(VFLAGS) cmd/v
move /y v2.exe v.exe
$(CC) $(CFLAGS) -std=c99 -municode -w -I ./thirdparty/stdatomic/nix -o v1.exe $(VC)/$(VCFILE) $(LDFLAGS)
v1.exe -no-parallel -o v2.exe $(VFLAGS) cmd/v
v2.exe -o $(V) $(VFLAGS) cmd/v
del v1.exe
del v2.exe
else
$(CC) $(CFLAGS) -std=gnu99 -w -o $(V) $(VC)/$(VCFILE) -lm -lpthread $(LDFLAGS)
$(V) -o v2.exe $(VFLAGS) cmd/v
mv -f v2.exe v
$(CC) $(CFLAGS) -std=gnu99 -w -I ./thirdparty/stdatomic/nix -o v1.exe $(VC)/$(VCFILE) -lm -lpthread $(LDFLAGS)
./v1.exe -no-parallel -o v2.exe $(VFLAGS) cmd/v
./v2.exe -o $(V) $(VFLAGS) cmd/v
rm -rf v1.exe v2.exe
endif
@echo "V has been successfully built"
@$(V) -version

View File

@@ -1,8 +1,11 @@
CC ?= cc
VFLAGS ?=
all:
rm -rf vc/
git clone --depth 1 --quiet https://github.com/vlang/vc
$(CC) -std=gnu11 -w -o v vc/v.c -lm -lexecinfo
rm -rf vc/
$(CC) -std=gnu11 -w -I ./thirdparty/stdatomic/nix -o v1 vc/v.c -lm -lexecinfo -lpthread
./v1 -no-parallel -o v2 $(VFLAGS) cmd/v
./v2 -o v $(VFLAGS) cmd/v
rm -rf v1 v2 vc/
@echo "V has been successfully built"

View File

@@ -29,19 +29,19 @@
- Fast compilation: ≈110k loc/s with a Clang backend,
≈1 million loc/s with native and tcc backends *(Intel i5-7500, SSD, no optimization)* ([demo video](https://www.youtube.com/watch?v=pvP6wmcl_Sc))
- Easy to develop: V compiles itself in less than a second
- Performance: as fast as C (V's main backend compiles to human readable C)
- Performance: as fast as C (V's main backend compiles to human-readable C)
- Safety: no null, no globals, no undefined behavior, immutability by default
- C to V translation
- Hot code reloading
- [Innovative memory management](https://vlang.io/#memory) ([demo video](https://www.youtube.com/watch?v=gmB8ea8uLsM))
- [Cross-platform UI library](https://github.com/vlang/ui)
- Built-in graphics library
- Easy cross compilation
- Easy cross-compilation
- REPL
- [Built-in ORM](https://github.com/vlang/v/blob/master/doc/docs.md#orm)
- [Built-in web framework](https://github.com/vlang/v/blob/master/vlib/vweb/README.md)
- C and JavaScript backends
- Great for writing low level software ([Vinix OS](https://github.com/vlang/vinix))
- Great for writing low-level software ([Vinix OS](https://github.com/vlang/vinix))
## Stability guarantee and future changes
@@ -112,7 +112,7 @@ sudo ./v symlink
```
On Windows, start a new shell with administrative privileges, for
example by <kbd>Windows Key</kbd>, then type `cmd.exe`, right click on its menu
example by <kbd>Windows Key</kbd>, then type `cmd.exe`, right-click on its menu
entry, and choose `Run as administrator`. In the new administrative
shell, cd to the path, where you have compiled v.exe, then type:
@@ -125,7 +125,7 @@ Please restart your shell/editor after that, so that it can pick
the new PATH variable.
NB: there is no need to run `v symlink` more than once - v will
continue to be available, even after `v up`, restarts and so on.
continue to be available, even after `v up`, restarts, and so on.
You only need to run it again, if you decide to move the V repo
folder somewhere else.
@@ -184,7 +184,9 @@ v run tetris/tetris.v
NB: In order to build Tetris or 2048 (or anything else using `sokol` or `gg` graphics modules)
on some Linux systems, you need to install `libxi-dev` and `libxcursor-dev` .
If you plan to use the http package, you also need to install OpenSSL on non-Windows systems.
## V net.http, net.websocket, `v install`
If you plan to use the net.http module, or the net.websocket module, you also need to install
OpenSSL on non-Windows systems:
```bash
macOS:
@@ -266,7 +268,7 @@ https://github.com/vlang/gitly
## Vinix, an OS/kernel written in V
V is great for writing low level software like drivers and kernels.
V is great for writing low-level software like drivers and kernels.
Vinix is an OS/kernel that already runs bash, GCC, V, and nano.
https://github.com/vlang/vinix

View File

@@ -15,11 +15,12 @@
- [x] iOS/Android support
- [ ] parallel parser
- [ ] parallel checker
- [ ] parallel cgen
- [x] parallel cgen
- [ ] parallel C compilation
- [ ] `recover()` from panics
- [x] IO streams
- [x] struct embedding
- [ ] interface embedding
- [x] interface embedding
- [x] interfaces: allow struct fields (not just methods)
- [ ] vfmt: fix common errors automatically (make vars mutable and vice versa, add missing imports)
- [ ] method expressions with an explicit receiver as the first argument

View File

@@ -0,0 +1,11 @@
module main
import v.builder.cbuilder
// TODO: change bootstrapping to use the C code generated from
// `VEXE=v cmd/tools/builders/c_builder -os cross -o c.c cmd/tools/builders/c_builder.v`
// See also `cmd/v/v.v`
fn main() {
cbuilder.start()
}

View File

@@ -0,0 +1,7 @@
module main
import v.builder.interpreterbuilder
fn main() {
interpreterbuilder.start()
}

View File

@@ -0,0 +1,7 @@
module main
import v.builder.jsbuilder
fn main() {
jsbuilder.start()
}

View File

@@ -0,0 +1,7 @@
module main
import v.builder.nativebuilder
fn main() {
nativebuilder.start()
}

View File

@@ -5,6 +5,7 @@ import v.util
import v.util.diff
import v.pref
import v.builder
import v.builder.cbuilder
import v.ast
import rand
import term
@@ -98,7 +99,7 @@ fn (app App) gen_api_for_module_in_os(mod_name string, os_name string) string {
tmpname := '/tmp/${mod_name}_${os_name}.c'
prefs, _ := pref.parse_args([], ['-os', os_name, '-o', tmpname, '-shared', mpath])
mut b := builder.new_builder(prefs)
b.compile_c()
cbuilder.compile_c(mut b)
mut res := []string{}
for f in b.parsed_files {
for s in f.stmts {

View File

@@ -21,11 +21,13 @@ fn main() {
println('fast.html generator needs to be located in `v/cmd/tools/fast`')
}
println('fast.html generator\n')
println('Fetching updates...')
ret := os.system('$vdir/v up')
if ret != 0 {
println('failed to update V')
return
if !os.args.contains('-noupdate') {
println('Fetching updates...')
ret := os.system('$vdir/v up')
if ret != 0 {
println('failed to update V')
return
}
}
// Fetch the last commit's hash
commit := exec('git rev-parse HEAD')[..8]
@@ -55,7 +57,6 @@ fn main() {
} else {
exec('./v -o vprod -prod -prealloc cmd/v')
}
// println('cur vdir="$vdir"')
// cache vlib modules
exec('$vdir/v wipe-cache')
exec('$vdir/v -o v2 -prod cmd/v')

View File

@@ -7,14 +7,25 @@ import benchmark
import sync.pool
import v.pref
import v.util.vtest
import runtime
const github_job = os.getenv('GITHUB_JOB')
pub const github_job = os.getenv('GITHUB_JOB')
const show_start = os.getenv('VTEST_SHOW_START') == '1'
pub const show_start = os.getenv('VTEST_SHOW_START') == '1'
const hide_skips = os.getenv('VTEST_HIDE_SKIP') == '1'
pub const hide_skips = os.getenv('VTEST_HIDE_SKIP') == '1'
const hide_oks = os.getenv('VTEST_HIDE_OK') == '1'
pub const hide_oks = os.getenv('VTEST_HIDE_OK') == '1'
pub const fail_fast = os.getenv('VTEST_FAIL_FAST') == '1'
pub const test_only = os.getenv('VTEST_ONLY').split_any(',')
pub const test_only_fn = os.getenv('VTEST_ONLY_FN').split_any(',')
pub const is_node_present = os.execute('node --version').exit_code == 0
pub const all_processes = os.execute('ps ax').output.split_any('\r\n')
pub struct TestSession {
pub mut:
@@ -25,6 +36,7 @@ pub mut:
vtmp_dir string
vargs string
failed bool
fail_fast bool
benchmark benchmark.Benchmark
rm_binaries bool = true
silent_mode bool
@@ -185,6 +197,7 @@ pub fn new_test_session(_vargs string, will_compile bool) TestSession {
vexe: vexe
vroot: vroot
skip_files: skip_files
fail_fast: testing.fail_fast
vargs: vargs
vtmp_dir: new_vtmp_dir
silent_mode: _vargs.contains('-silent')
@@ -233,6 +246,7 @@ pub fn (mut ts TestSession) test() {
remaining_files = vtest.filter_vtest_only(remaining_files, fix_slashes: false)
ts.files = remaining_files
ts.benchmark.set_total_expected_steps(remaining_files.len)
ts.benchmark.njobs = runtime.nr_jobs()
mut pool_of_test_runners := pool.new_pool_processor(callback: worker_trunner)
// for handling messages across threads
ts.nmessages = chan LogMessage{cap: 10000}
@@ -248,7 +262,7 @@ pub fn (mut ts TestSession) test() {
// cleanup generated .tmp.c files after successfull tests:
if ts.benchmark.nfail == 0 {
if ts.rm_binaries {
os.rmdir_all(ts.vtmp_dir) or { panic(err) }
os.rmdir_all(ts.vtmp_dir) or {}
}
}
ts.show_list_of_failed_tests()
@@ -256,6 +270,11 @@ pub fn (mut ts TestSession) test() {
fn worker_trunner(mut p pool.PoolProcessor, idx int, thread_id int) voidptr {
mut ts := &TestSession(p.get_shared_context())
if ts.fail_fast {
if ts.failed {
return pool.no_result
}
}
tmpd := ts.vtmp_dir
show_stats := '-stats' in ts.vargs.split(' ')
// tls_bench is used to format the step messages/timings
@@ -266,9 +285,21 @@ fn worker_trunner(mut p pool.PoolProcessor, idx int, thread_id int) voidptr {
p.set_thread_context(idx, tls_bench)
}
tls_bench.no_cstep = true
tls_bench.njobs = ts.benchmark.njobs
mut relative_file := os.real_path(p.get_item<string>(idx))
mut cmd_options := [ts.vargs]
if relative_file.contains('global') && !ts.vargs.contains('fmt') {
mut run_js := false
is_fmt := ts.vargs.contains('fmt')
if relative_file.ends_with('js.v') {
if !is_fmt {
cmd_options << ' -b js'
}
run_js = true
}
if relative_file.contains('global') && !is_fmt {
cmd_options << ' -enable-globals'
}
if ts.root_relative {
@@ -279,17 +310,20 @@ fn worker_trunner(mut p pool.PoolProcessor, idx int, thread_id int) voidptr {
// Ensure that the generated binaries will be stored in the temporary folder.
// Remove them after a test passes/fails.
fname := os.file_name(file)
generated_binary_fname := if os.user_os() == 'windows' {
generated_binary_fname := if os.user_os() == 'windows' && !run_js {
fname.replace('.v', '.exe')
} else if !run_js {
fname.replace('.v', '')
} else {
fname.replace('.v', '')
}
generated_binary_fpath := os.join_path(tmpd, generated_binary_fname)
generated_binary_fpath := os.join_path_single(tmpd, generated_binary_fname)
if os.exists(generated_binary_fpath) {
if ts.rm_binaries {
os.rm(generated_binary_fpath) or { panic(err) }
os.rm(generated_binary_fpath) or {}
}
}
if !ts.vargs.contains('fmt') {
cmd_options << ' -o "$generated_binary_fpath"'
}
@@ -306,22 +340,35 @@ fn worker_trunner(mut p pool.PoolProcessor, idx int, thread_id int) voidptr {
}
if show_stats {
ts.append_message(.ok, term.h_divider('-'))
status := os.system(cmd)
if status == 0 {
ts.benchmark.ok()
tls_bench.ok()
} else {
mut status := os.system(cmd)
if status != 0 {
details := get_test_details(file)
os.setenv('VTEST_RETRY_MAX', '$details.retry', true)
for retry := 1; retry <= details.retry; retry++ {
ts.append_message(.info, ' retrying $retry/$details.retry of $relative_file ...')
os.setenv('VTEST_RETRY', '$retry', true)
status = os.system(cmd)
if status == 0 {
unsafe {
goto test_passed_system
}
}
}
ts.failed = true
ts.benchmark.fail()
tls_bench.fail()
ts.add_failed_cmd(cmd)
return pool.no_result
} else {
test_passed_system:
ts.benchmark.ok()
tls_bench.ok()
}
} else {
if testing.show_start {
ts.append_message(.info, ' starting $relative_file ...')
}
r := os.execute(cmd)
mut r := os.execute(cmd)
if r.exit_code < 0 {
ts.failed = true
ts.benchmark.fail()
@@ -331,6 +378,18 @@ fn worker_trunner(mut p pool.PoolProcessor, idx int, thread_id int) voidptr {
return pool.no_result
}
if r.exit_code != 0 {
details := get_test_details(file)
os.setenv('VTEST_RETRY_MAX', '$details.retry', true)
for retry := 1; retry <= details.retry; retry++ {
ts.append_message(.info, ' retrying $retry/$details.retry of $relative_file ...')
os.setenv('VTEST_RETRY', '$retry', true)
r = os.execute(cmd)
if r.exit_code == 0 {
unsafe {
goto test_passed_execute
}
}
}
ts.failed = true
ts.benchmark.fail()
tls_bench.fail()
@@ -338,6 +397,7 @@ fn worker_trunner(mut p pool.PoolProcessor, idx int, thread_id int) voidptr {
ts.append_message(.fail, tls_bench.step_message_fail('$normalised_relative_file\n$r.output.trim_space()$ending_newline'))
ts.add_failed_cmd(cmd)
} else {
test_passed_execute:
ts.benchmark.ok()
tls_bench.ok()
if !testing.hide_oks {
@@ -347,24 +407,20 @@ fn worker_trunner(mut p pool.PoolProcessor, idx int, thread_id int) voidptr {
}
if os.exists(generated_binary_fpath) {
if ts.rm_binaries {
os.rm(generated_binary_fpath) or { panic(err) }
os.rm(generated_binary_fpath) or {}
}
}
return pool.no_result
}
pub fn vlib_should_be_present(parent_dir string) {
vlib_dir := os.join_path(parent_dir, 'vlib')
vlib_dir := os.join_path_single(parent_dir, 'vlib')
if !os.is_dir(vlib_dir) {
eprintln('$vlib_dir is missing, it must be next to the V executable')
exit(1)
}
}
pub fn v_build_failing(zargs string, folder string) bool {
return v_build_failing_skipped(zargs, folder, [])
}
pub fn prepare_test_session(zargs string, folder string, oskipped []string, main_label string) TestSession {
vexe := pref.vexe_path()
parent_dir := os.dir(vexe)
@@ -375,7 +431,7 @@ pub fn prepare_test_session(zargs string, folder string, oskipped []string, main
eprintln('v compiler args: "$vargs"')
}
mut session := new_test_session(vargs, true)
files := os.walk_ext(os.join_path(parent_dir, folder), '.v')
files := os.walk_ext(os.join_path_single(parent_dir, folder), '.v')
mut mains := []string{}
mut skipped := oskipped.clone()
next_file: for f in files {
@@ -399,7 +455,7 @@ pub fn prepare_test_session(zargs string, folder string, oskipped []string, main
maxc := if c.len > 300 { 300 } else { c.len }
start := c[0..maxc]
if start.contains('module ') && !start.contains('module main') {
skipped_f := f.replace(os.join_path(parent_dir, ''), '')
skipped_f := f.replace(os.join_path_single(parent_dir, ''), '')
skipped << skipped_f
}
for skip_prefix in oskipped {
@@ -414,10 +470,13 @@ pub fn prepare_test_session(zargs string, folder string, oskipped []string, main
return session
}
pub fn v_build_failing_skipped(zargs string, folder string, oskipped []string) bool {
pub type FnTestSetupCb = fn (mut session TestSession)
pub fn v_build_failing_skipped(zargs string, folder string, oskipped []string, cb FnTestSetupCb) bool {
main_label := 'Building $folder ...'
finish_label := 'building $folder'
mut session := prepare_test_session(zargs, folder, oskipped, main_label)
cb(mut session)
session.test()
eprintln(session.benchmark.total_message(finish_label))
return session.failed
@@ -446,8 +505,7 @@ pub fn building_any_v_binaries_failed() bool {
mut failed := false
v_build_commands := ['$vexe -o v_g -g cmd/v', '$vexe -o v_prod_g -prod -g cmd/v',
'$vexe -o v_cg -cg cmd/v', '$vexe -o v_prod_cg -prod -cg cmd/v',
'$vexe -o v_prod -prod cmd/v',
]
'$vexe -o v_prod -prod cmd/v']
mut bmark := benchmark.new_benchmark()
for cmd in v_build_commands {
bmark.step()
@@ -484,3 +542,28 @@ pub fn setup_new_vtmp_folder() string {
os.setenv('VTMP', new_vtmp_dir, true)
return new_vtmp_dir
}
pub struct TestDetails {
pub mut:
retry int
}
pub fn get_test_details(file string) TestDetails {
mut res := TestDetails{}
lines := os.read_lines(file) or { [] }
for line in lines {
if line.starts_with('// vtest retry:') {
res.retry = line.all_after(':').trim_space().int()
}
}
return res
}
pub fn find_started_process(pname string) ?string {
for line in testing.all_processes {
if line.contains(pname) {
return line
}
}
return error('could not find process matching $pname')
}

View File

@@ -76,7 +76,7 @@ pub fn prepare_vc_source(vcdir string, cdir string, commit string) (string, stri
pub fn clone_or_pull(remote_git_url string, local_worktree_path string) {
// NB: after clone_or_pull, the current repo branch is === HEAD === master
if os.is_dir(local_worktree_path) && os.is_dir(os.join_path(local_worktree_path, '.git')) {
if os.is_dir(local_worktree_path) && os.is_dir(os.join_path_single(local_worktree_path, '.git')) {
// Already existing ... Just pulling in this case is faster usually.
scripting.run('git -C "$local_worktree_path" checkout --quiet master')
scripting.run('git -C "$local_worktree_path" pull --quiet ')
@@ -107,14 +107,14 @@ pub mut:
pub fn (mut vgit_context VGitContext) compile_oldv_if_needed() {
vgit_context.vexename = if os.user_os() == 'windows' { 'v.exe' } else { 'v' }
vgit_context.vexepath = os.real_path(os.join_path(vgit_context.path_v, vgit_context.vexename))
vgit_context.vexepath = os.real_path(os.join_path_single(vgit_context.path_v, vgit_context.vexename))
mut command_for_building_v_from_c_source := ''
mut command_for_selfbuilding := ''
if 'windows' == os.user_os() {
command_for_building_v_from_c_source = '$vgit_context.cc -std=c99 -municode -w -o cv.exe "$vgit_context.path_vc/v_win.c" '
command_for_building_v_from_c_source = '$vgit_context.cc -std=c99 -I ./thirdparty/stdatomic/win -municode -w -o cv.exe "$vgit_context.path_vc/v_win.c" '
command_for_selfbuilding = './cv.exe -o $vgit_context.vexename {SOURCE}'
} else {
command_for_building_v_from_c_source = '$vgit_context.cc -std=gnu11 -w -o cv "$vgit_context.path_vc/v.c" -lm -lpthread'
command_for_building_v_from_c_source = '$vgit_context.cc -std=gnu11 -I ./thirdparty/stdatomic/nix -w -o cv "$vgit_context.path_vc/v.c" -lm -lpthread'
command_for_selfbuilding = './cv -o $vgit_context.vexename {SOURCE}'
}
scripting.chdir(vgit_context.workdir)

View File

@@ -123,7 +123,7 @@ fn main() {
}
should_sync := fp.bool('cache-sync', `s`, false, 'Update the local cache')
if !should_sync {
fp.limit_free_args(1, 1)
fp.limit_free_args(1, 1) ?
}
////
context.cleanup = fp.bool('clean', 0, false, 'Clean before running (slower).')
@@ -171,6 +171,9 @@ fn main() {
}
scripting.cprint_strong('# result: ')
print(cmdres.output)
if !cmdres.output.ends_with('\n') {
println('')
}
exit(cmdres.exit_code)
}
}

View File

@@ -56,15 +56,18 @@ fn (c Context) compare_versions() {
'v @DEBUG@ -o source.c examples/hello_world.v',
'v -o source.c examples/hello_world.v',
])
perf_files << c.compare_v_performance('source_v', ['vprod @DEBUG@ -o source.c @COMPILER@',
'vprod -o source.c @COMPILER@', 'v @DEBUG@ -o source.c @COMPILER@',
perf_files << c.compare_v_performance('source_v', [
'vprod @DEBUG@ -o source.c @COMPILER@',
'vprod -o source.c @COMPILER@',
'v @DEBUG@ -o source.c @COMPILER@',
'v -o source.c @COMPILER@',
])
perf_files << c.compare_v_performance('binary_hello', [
'vprod -o hello examples/hello_world.v',
'v -o hello examples/hello_world.v',
])
perf_files << c.compare_v_performance('binary_v', ['vprod -o binary @COMPILER@',
perf_files << c.compare_v_performance('binary_v', [
'vprod -o binary @COMPILER@',
'v -o binary @COMPILER@',
])
println('All performance files:')
@@ -107,8 +110,7 @@ fn (c &Context) prepare_v(cdir string, commit string) {
scripting.show_sizes_of_files(['$cdir/cv', '$cdir/cv_stripped', '$cdir/cv_stripped_upxed'])
scripting.show_sizes_of_files(['$cdir/v', '$cdir/v_stripped', '$cdir/v_stripped_upxed'])
scripting.show_sizes_of_files(['$cdir/vprod', '$cdir/vprod_stripped',
'$cdir/vprod_stripped_upxed',
])
'$cdir/vprod_stripped_upxed'])
vversion := scripting.run('$cdir/v -version')
vcommit := scripting.run('git rev-parse --short --verify HEAD')
println('V version is: $vversion , local source commit: $vcommit')
@@ -192,7 +194,7 @@ fn main() {
fp.description(tool_description)
fp.arguments_description('COMMIT_BEFORE [COMMIT_AFTER]')
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.hyperfineopts = fp.string('hyperfine_options', 0, '', 'Additional options passed to hyperfine.
${flag.space}For example on linux, you may want to pass:

View File

@@ -143,19 +143,19 @@ const (
fn main() {
mut context := Context{}
context.parse_options()
context.parse_options() ?
context.run()
context.show_diff_summary()
}
fn (mut context Context) parse_options() {
fn (mut context Context) parse_options() ? {
mut fp := flag.new_flag_parser(os.args)
fp.application(os.file_name(os.executable()))
fp.version('0.0.1')
fp.description('Repeat command(s) and collect statistics. NB: you have to quote each command, if it contains spaces.')
fp.arguments_description('CMD1 CMD2 ...')
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.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.')

View File

@@ -40,24 +40,31 @@ fn cleanup_tdir() {
os.rmdir_all(tdir) or { eprintln(err) }
}
fn create_test(tname string, tcontent string) ?string {
tpath := os.join_path(tdir, tname)
os.write_file(tpath, tcontent) ?
eprintln('>>>>>>>> tpath: $tpath | tcontent: $tcontent')
return tpath
}
fn main() {
defer {
os.chdir(os.wd_at_startup) or {}
}
println('> vroot: $vroot | vexe: $vexe | tdir: $tdir')
ok_fpath := os.join_path(tdir, 'single_test.v')
os.write_file(ok_fpath, 'fn test_ok(){ assert true }') ?
check_ok('"$vexe" $ok_fpath')
check_ok('"$vexe" test $ok_fpath')
fail_fpath := os.join_path(tdir, 'failing_test.v')
os.write_file(fail_fpath, 'fn test_fail(){ assert 1 == 2 }') ?
check_fail('"$vexe" $fail_fpath')
check_fail('"$vexe" test $fail_fpath')
check_fail('"$vexe" test $tdir')
ok_fpath := create_test('a_single_ok_test.v', 'fn test_ok(){ assert true }') ?
check_ok('"$vexe" "$ok_fpath"')
check_ok('"$vexe" test "$ok_fpath"')
check_ok('"$vexe" test "$tdir"')
fail_fpath := create_test('a_single_failing_test.v', 'fn test_fail(){ assert 1 == 2 }') ?
check_fail('"$vexe" "$fail_fpath"')
check_fail('"$vexe" test "$fail_fpath"')
check_fail('"$vexe" test "$tdir"')
rel_dir := os.join_path(tdir, rand.ulid())
os.mkdir(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')
}
fn check_ok(cmd string) string {

File diff suppressed because it is too large Load Diff

View File

@@ -105,6 +105,7 @@ fn main() {
eprintln('v bug: no v file listed to report')
exit(1)
}
os.unsetenv('VCOLORS')
// collect error information
// output from `v doctor`
vdoctor_output := get_vdoctor_output(is_verbose)

View File

@@ -3,13 +3,28 @@ module main
import os
import testing
const vroot = @VMODROOT
const efolders = [
'examples/viewer',
]
fn main() {
args_string := os.args[1..].join(' ')
params := args_string.all_before('build-examples')
if testing.v_build_failing(params, 'examples') {
skip_prefixes := efolders.map(os.real_path(os.join_path_single(vroot, it)))
res := testing.v_build_failing_skipped(params, 'examples', skip_prefixes, fn (mut session testing.TestSession) {
for x in efolders {
pathsegments := x.split_any('/')
session.add(os.real_path(os.join_path(vroot, ...pathsegments)))
}
})
if res {
exit(1)
}
if testing.v_build_failing(params + '-live', os.join_path('examples', 'hot_reload')) {
if testing.v_build_failing_skipped(params + '-live', os.join_path_single('examples',
'hot_reload'), skip_prefixes, fn (mut session testing.TestSession) {})
{
exit(1)
}
}

View File

@@ -56,6 +56,10 @@ fn main() {
}
//
tpath := os.join_path(session.vtmp_dir, texe)
if texe.ends_with('_builder') || texe.ends_with('_builder.exe') {
os.mv_by_cp(tpath, os.join_path(tfolder, 'builders', texe)) or { panic(err) }
continue
}
if tname in tools_in_subfolders {
os.mv_by_cp(tpath, os.join_path(tfolder, tname, texe)) or { panic(err) }
continue

188
cmd/tools/vbump.v Normal file
View File

@@ -0,0 +1,188 @@
// Copyright (c) 2019-2021 Subhomoy Haldar. All rights reserved.
// Use of this source code is governed by an MIT license that can be found in the LICENSE file.
module main
import flag
import os
import regex
import semver
const (
tool_name = os.file_name(os.executable())
tool_version = '0.0.1'
tool_description = '\n Bump the semantic version of the v.mod and/or specified files.
The first instance of a version number is replaced with the new version.
Additionally, the line affected must contain the word "version" in any
form of capitalization. For instance, the following lines will be
recognized by the heuristic:
tool_version = \'1.2.1\'
version: \'0.2.42\'
VERSION = "1.23.8"
Examples:
Bump the patch version in v.mod if it exists
v bump --patch
Bump the major version in v.mod and vls.v
v bump --major v.mod vls.v
Upgrade the minor version in sample.v only
v bump --minor sample.v
'
semver_query = r'((0)|([1-9]\d*)\.){2}(0)|([1-9]\d*)(\-[\w\d\.\-_]+)?(\+[\w\d\.\-_]+)?'
)
struct Options {
show_help bool
major bool
minor bool
patch bool
}
type ReplacementFunction = fn (re regex.RE, input string, start int, end int) string
fn replace_with_increased_patch_version(re regex.RE, input string, start int, end int) string {
version := semver.from(input[start..end]) or { return input }
return version.increment(.patch).str()
}
fn replace_with_increased_minor_version(re regex.RE, input string, start int, end int) string {
version := semver.from(input[start..end]) or { return input }
return version.increment(.minor).str()
}
fn replace_with_increased_major_version(re regex.RE, input string, start int, end int) string {
version := semver.from(input[start..end]) or { return input }
return version.increment(.major).str()
}
fn get_replacement_function(options Options) ReplacementFunction {
if options.patch {
return replace_with_increased_patch_version
} else if options.minor {
return replace_with_increased_minor_version
} else if options.major {
return replace_with_increased_major_version
}
return replace_with_increased_patch_version
}
fn process_file(input_file string, options Options) {
lines := os.read_lines(input_file) or { panic('Failed to read file: $input_file') }
mut re := regex.regex_opt(semver_query) or { panic('Could not create a RegEx parser.') }
repl_fn := get_replacement_function(options)
mut new_lines := []string{cap: lines.len}
mut replacement_complete := false
for line in lines {
// Copy over the remaining lines normally if the replacement is complete
if replacement_complete {
new_lines << line
continue
}
// Check if replacement is necessary
updated_line := if line.to_lower().contains('version') {
replacement_complete = true
re.replace_by_fn(line, repl_fn)
} else {
line
}
new_lines << updated_line
}
// Add a trailing newline
new_lines << ''
backup_file := input_file + '.cache'
// Remove the backup file if it exists.
os.rm(backup_file) or {}
// Rename the original to the backup.
os.mv(input_file, backup_file) or { panic('Failed to copy file: $input_file') }
// Process the old file and write it back to the original.
os.write_file(input_file, new_lines.join_lines()) or {
panic('Failed to write file: $input_file')
}
// Remove the backup file.
os.rm(backup_file) or {}
if replacement_complete {
println('Bumped version in $input_file')
} else {
println('No changes made in $input_file')
}
}
fn main() {
if os.args.len < 2 {
println('Usage: $tool_name [options] [file1 file2 ...]
$tool_description
Try $tool_name -h for more help...')
exit(1)
}
mut fp := flag.new_flag_parser(os.args)
fp.application(tool_name)
fp.version(tool_version)
fp.description(tool_description)
fp.arguments_description('[file1 file2 ...]')
fp.skip_executable()
options := Options{
show_help: fp.bool('help', `h`, false, 'Show this help text.')
patch: fp.bool('patch', `p`, false, 'Bump the patch version.')
minor: fp.bool('minor', `n`, false, 'Bump the minor version.')
major: fp.bool('major', `m`, false, 'Bump the major version.')
}
if options.show_help {
println(fp.usage())
exit(0)
}
validate_options(options) or { panic(err) }
files := os.args[3..]
if files.len == 0 {
if !os.exists('v.mod') {
println('v.mod does not exist. You can create one using "v init".')
exit(1)
}
process_file('v.mod', options)
}
for input_file in files {
if !os.exists(input_file) {
println('File not found: $input_file')
exit(1)
}
process_file(input_file, options)
}
}
fn validate_options(options Options) ? {
if options.patch && options.major {
return error('Cannot specify both --patch and --major.')
}
if options.patch && options.minor {
return error('Cannot specify both --patch and --minor.')
}
if options.major && options.minor {
return error('Cannot specify both --major and --minor.')
}
if !(options.patch || options.major || options.minor) {
return error('Must specify one of --patch, --major, or --minor.')
}
}

95
cmd/tools/vbump_test.v Normal file
View File

@@ -0,0 +1,95 @@
import os
struct BumpTestCase {
file_name string
contents string
line int
expected_patch string
expected_minor string
expected_major string
}
const test_cases = [
BumpTestCase{
file_name: 'v.mod'
contents: "Module {
name: 'Sample'
description: 'Sample project'
version: '1.2.6'
license: 'MIT'
dependencies: []
}
"
line: 3
expected_patch: " version: '1.2.7'"
expected_minor: " version: '1.3.0'"
expected_major: " version: '2.0.0'"
},
BumpTestCase{
file_name: 'random_versions.vv'
contents: "
1.1.2
1.2.5
3.21.73
version = '1.5.1'
"
line: 4
expected_patch: "version = '1.5.2'"
expected_minor: "version = '1.6.0'"
expected_major: "version = '2.0.0'"
},
BumpTestCase{
file_name: 'sample_tool.v'
contents: "// Module comment and copyright information
import os
import flag
const (
tool_name = os.file_name(os.executable())
tool_version = '0.1.33'
)
fn main() {
// stuff
}
"
line: 6
expected_patch: " tool_version = '0.1.34'"
expected_minor: " tool_version = '0.2.0'"
expected_major: " tool_version = '1.0.0'"
},
]
fn run_individual_test(case BumpTestCase) ? {
vexe := @VEXE
temp_dir := os.temp_dir()
test_file := os.join_path_single(temp_dir, case.file_name)
os.rm(test_file) or {}
os.write_file(test_file, case.contents) ?
{
os.execute_or_exit('$vexe bump --patch $test_file')
patch_lines := os.read_lines(test_file) ?
assert patch_lines[case.line] == case.expected_patch
}
{
os.execute_or_exit('$vexe bump --minor $test_file')
minor_lines := os.read_lines(test_file) ?
assert minor_lines[case.line] == case.expected_minor
}
{
os.execute_or_exit('$vexe bump --major $test_file')
major_lines := os.read_lines(test_file) ?
assert major_lines[case.line] == case.expected_major
}
os.rm(test_file) ?
}
fn test_all_bump_cases() {
for case in test_cases {
run_individual_test(case) or { panic(err) }
}
}

View File

@@ -48,27 +48,40 @@ const (
// Snooped from cmd/v/v.v, vlib/v/pref/pref.v
const (
auto_complete_commands = [
auto_complete_commands = [
// simple_cmd
'fmt',
'up',
'vet',
'self',
'tracev',
'symlink',
'bin2v',
'test',
'test-fmt',
'test-self',
'test-cleancode',
'repl',
'complete',
'build-tools',
'build-examples',
'build-vbinaries',
'setup-freetype',
'ast',
'doc',
'vet',
// tools in one .v file
'bin2v',
'bug',
'build-examples',
'build-tools',
'build-vbinaries',
'bump',
'check-md',
'complete',
'compress',
'create',
'doctor',
'fmt',
'gret',
'repl',
'self',
'setup-freetype',
'shader',
'symlink',
'test-all',
'test-cleancode',
'test-fmt',
'test-parser',
'test-self',
'test',
'tracev',
'up',
'watch',
'wipe-cache',
// commands
'help',
'new',
@@ -90,7 +103,7 @@ const (
'build',
'build-module',
]
auto_complete_flags = [
auto_complete_flags = [
'-apk',
'-show-timings',
'-check-syntax',
@@ -149,7 +162,7 @@ const (
'-version',
'--version',
]
auto_complete_flags_doc = [
auto_complete_flags_doc = [
'-all',
'-f',
'-h',
@@ -167,7 +180,7 @@ const (
'-s',
'-l',
]
auto_complete_flags_fmt = [
auto_complete_flags_fmt = [
'-c',
'-diff',
'-l',
@@ -175,7 +188,7 @@ const (
'-debug',
'-verify',
]
auto_complete_flags_bin2v = [
auto_complete_flags_bin2v = [
'-h',
'--help',
'-m',
@@ -185,10 +198,22 @@ const (
'-w',
'--write',
]
auto_complete_flags_self = [
auto_complete_flags_shader = [
'help',
'h',
'force-update',
'u',
'verbose',
'v',
'slang',
'l',
'output',
'o',
]
auto_complete_flags_self = [
'-prod',
]
auto_complete_compilers = [
auto_complete_compilers = [
'cc',
'gcc',
'tcc',
@@ -368,6 +393,9 @@ fn auto_complete_request(args []string) []string {
'self' { // 'v self -<tab>' -> flags.
list = get_flags(auto_complete_flags_self, part)
}
'shader' { // 'v shader -<tab>' -> flags.
list = get_flags(auto_complete_flags_shader, part)
}
else {
for flag in auto_complete_flags {
if flag == part {

44
cmd/tools/vcompress.v Normal file
View File

@@ -0,0 +1,44 @@
module main
import compress.zlib
import os
enum CompressionType {
zlib
}
fn main() {
if os.args.len != 5 {
eprintln('v compress <type> <in> <out>')
eprintln('supported types: zlib')
exit(1)
}
compression_type := match os.args[2] {
'zlib' {
CompressionType.zlib
}
else {
eprintln('unsupported type: ${os.args[1]}')
exit(1)
}
}
path := os.args[3]
content := os.read_bytes(path) or {
eprintln('unable to read "$path": $err')
exit(1)
}
compressed := match compression_type {
.zlib {
zlib.compress(content) or {
eprintln('compression error: $err')
exit(1)
}
}
}
out_path := os.args[4]
os.write_file_array(out_path, compressed) or {
eprintln('failed to write "$out_path": $err')
exit(1)
}
}

View File

@@ -51,7 +51,7 @@ fn vmod_content(c Create) string {
' dependencies: []',
'}',
'',
].join('\n')
].join_lines()
}
fn main_content() string {
@@ -61,7 +61,7 @@ fn main_content() string {
" println('Hello World!')",
'}',
'',
].join('\n')
].join_lines()
}
fn gen_gitignore(name string) string {
@@ -74,18 +74,22 @@ fn gen_gitignore(name string) string {
'*.so',
'*.dylib',
'*.dll',
'vls.log',
'',
].join('\n')
].join_lines()
}
fn gitattributes_content() string {
return [
'*.v linguist-language=V text=auto eol=lf',
'*.vv linguist-language=V text=auto eol=lf',
'',
].join_lines()
}
fn (c &Create) write_vmod(new bool) {
vmod_path := if new { '$c.name/v.mod' } else { 'v.mod' }
mut vmod := os.create(vmod_path) or {
cerror(err.msg)
exit(1)
}
vmod.write_string(vmod_content(c)) or { panic(err) }
vmod.close()
os.write_file(vmod_path, vmod_content(c)) or { panic(err) }
}
fn (c &Create) write_main(new bool) {
@@ -93,12 +97,12 @@ fn (c &Create) write_main(new bool) {
return
}
main_path := if new { '$c.name/${c.name}.v' } else { '${c.name}.v' }
mut mainfile := os.create(main_path) or {
cerror(err.msg)
exit(2)
}
mainfile.write_string(main_content()) or { panic(err) }
mainfile.close()
os.write_file(main_path, main_content()) or { panic(err) }
}
fn (c &Create) write_gitattributes(new bool) {
gitattributes_path := if new { '$c.name/.gitattributes' } else { '.gitattributes' }
os.write_file(gitattributes_path, gitattributes_content()) or { panic(err) }
}
fn (c &Create) create_git_repo(dir string) {
@@ -110,13 +114,9 @@ fn (c &Create) create_git_repo(dir string) {
exit(4)
}
}
if !os.exists('$dir/.gitignore') {
mut fl := os.create('$dir/.gitignore') or {
// We don't really need a .gitignore, it's just a nice-to-have
return
}
fl.write_string(gen_gitignore(c.name)) or { panic(err) }
fl.close()
gitignore_path := '$dir/.gitignore'
if !os.exists(gitignore_path) {
os.write_file(gitignore_path, gen_gitignore(c.name)) or {}
}
}
@@ -150,6 +150,7 @@ fn create(args []string) {
os.mkdir(c.name) or { panic(err) }
c.write_vmod(true)
c.write_main(true)
c.write_gitattributes(true)
c.create_git_repo(c.name)
}
@@ -163,6 +164,7 @@ fn init_project() {
c.description = ''
c.write_vmod(false)
c.write_main(false)
c.write_gitattributes(false)
c.create_git_repo('.')
println('Change the description of your project in `v.mod`')

View File

@@ -12,7 +12,7 @@ fn init_and_check() ? {
" println('Hello World!')",
'}',
'',
].join('\n')
].join_lines()
assert os.read_file('v.mod') ? == [
'Module {',
@@ -23,7 +23,7 @@ fn init_and_check() ? {
' dependencies: []',
'}',
'',
].join('\n')
].join_lines()
assert os.read_file('.gitignore') ? == [
'# Binaries for programs and plugins',
@@ -34,8 +34,15 @@ fn init_and_check() ? {
'*.so',
'*.dylib',
'*.dll',
'vls.log',
'',
].join('\n')
].join_lines()
assert os.read_file('.gitattributes') ? == [
'*.v linguist-language=V text=auto eol=lf',
'*.vv linguist-language=V text=auto eol=lf',
'',
].join_lines()
}
fn test_v_init() ? {

View File

@@ -37,6 +37,7 @@ const (
{{ head_assets }}
</head>
<body>
<div><a id="skip-to-content-link" href="#main-content">Skip to content</a></div>
<div id="page">
<header class="doc-nav hidden">
<div class="heading-container">
@@ -59,7 +60,7 @@ const (
</ul>
</nav>
</header>
<div class="doc-scrollview">
<div class="doc-scrollview" id="main-content">
<div class="doc-container">
<div class="doc-content">
{{ contents }}

View File

@@ -730,3 +730,19 @@ pre {
top: 0;
}
}
#skip-to-content-link {
height: 30px;
left: 50%;
padding: 8px;
position: absolute;
transform: translateY(-100%);
transition: transform 0.3s;
background: var(--links);
color: var(--warn-text);
border-radius: 1px;
}
#skip-to-content-link:focus {
transform: translateY(0%);
z-index: 1000;
}

View File

@@ -149,8 +149,7 @@ fn color_highlight(code string, tb &ast.Table) string {
.string {
use_double_quote := tok.lit.contains("'") && !tok.lit.contains('"')
unescaped_val := tok.lit.replace('\\\\', '\x01').replace_each(["\\'", "'", '\\"',
'"',
])
'"'])
if use_double_quote {
s := unescaped_val.replace_each(['\x01', '\\\\', '"', '\\"'])
lit = term.yellow('"$s"')

View File

@@ -289,11 +289,9 @@ fn (mut vd VDoc) generate_docs_from_file() {
}
}
}
dirs := if cfg.is_multi {
get_modules_list(cfg.input_path, []string{})
} else {
[cfg.input_path]
}
dirs := if cfg.is_multi { get_modules_list(cfg.input_path, []string{}) } else { [
cfg.input_path,
] }
for dirpath in dirs {
vd.vprintln('Generating $out.typ docs for "$dirpath"')
mut dcs := doc.generate(dirpath, cfg.pub_only, true, cfg.platform, cfg.symbol_name) or {
@@ -327,6 +325,10 @@ fn (mut vd VDoc) generate_docs_from_file() {
docs << vd.docs.filter(it.head.name != 'builtin')
vd.docs = docs
}
if dirs.len == 0 && cfg.is_multi {
eprintln('vdoc: -m requires at least 1 module folder')
exit(1)
}
vd.vprintln('Rendering docs...')
if out.path.len == 0 || out.path == 'stdout' {
if out.typ == .html {
@@ -334,7 +336,11 @@ fn (mut vd VDoc) generate_docs_from_file() {
}
outputs := vd.render(out)
if outputs.len == 0 {
eprintln('vdoc: No documentation found for ${dirs[0]}')
if dirs.len == 0 {
eprintln('vdoc: No documentation found')
} else {
eprintln('vdoc: No documentation found for ${dirs[0]}')
}
exit(1)
} else {
first := outputs.keys()[0]

View File

@@ -26,6 +26,7 @@ struct FormatOptions {
is_noerror bool
is_verify bool // exit(1) if the file is not vfmt'ed
is_worker bool // true *only* in the worker processes. NB: workers can crash.
is_backup bool // make a `file.v.bak` copy *before* overwriting a `file.v` in place with `-w`
}
const (
@@ -53,6 +54,7 @@ fn main() {
is_debug: '-debug' in args
is_noerror: '-noerror' in args
is_verify: '-verify' in args
is_backup: '-backup' in args
}
if term_colors {
os.setenv('VCOLORS', 'always', true)
@@ -249,6 +251,10 @@ fn (foptions &FormatOptions) post_process_file(file string, formatted_file_path
}
if foptions.is_w {
if is_formatted_different {
if foptions.is_backup {
file_bak := '${file}.bak'
os.cp(file, file_bak) or {}
}
os.mv_by_cp(formatted_file_path, file) or { panic(err) }
eprintln('Reformatted file: $file')
} else {

View File

@@ -0,0 +1,74 @@
# Defaults
[compare]
method = 'idiff'
flags = ['-p','-fail 0.001','-failpercent 0.2']
[capture]
method = 'gg_record'
flags = [] # ['-prod','-d ...'] etc.
[capture.env]
VGG_STOP_AT_FRAME = '8'
VGG_SCREENSHOT_FOLDER = '$OUT_PATH'
VGG_SCREENSHOT_FRAMES = '5'
# List of apps to run and capture
[[apps]]
path = 'examples/game_of_life/life_gg.v'
[[apps]]
path = 'examples/gg/bezier.v'
[[apps]]
path = 'examples/gg/mandelbrot.v'
[[apps]]
path = 'examples/gg/rectangles.v'
[[apps]]
path = 'examples/gg/raven_text_rendering.v'
[[apps]]
path = 'examples/gg/worker_thread.v'
[[apps]]
path = 'examples/gg/polygons.v'
[[apps]]
path = 'examples/gg/bezier_anim.v'
[[apps]]
path = 'examples/gg/drag_n_drop.v'
[[apps]]
path = 'examples/ttf_font/example_ttf.v'
# Reasons for ex- or inclusion:
#
# 'examples/snek/snek.v' // Inacurrate captures
# 'examples/game_of_life/life_gg.v' // OK
# 'examples/tetris/tetris.v' // Uses random start block
# 'examples/fireworks/fireworks.v' // Uses rand for placement
# 'examples/gg/bezier.v', // OK
# 'examples/gg/mandelbrot.v', // OK
# 'examples/gg/rectangles.v', // OK
# 'examples/gg/set_pixels.v' // Has problem in CI software render (blank, no pixels set)
# 'examples/gg/random.v' // Always random
# 'examples/gg/stars.v' // Uses rand for placement
# 'examples/gg/raven_text_rendering.v', // OK
# 'examples/gg/worker_thread.v', // OK
# 'examples/gg/polygons.v', // OK
# 'examples/gg/bezier_anim.v', // OK
# 'examples/gg/drag_n_drop.v' // OK
# 'examples/2048/2048.v' // Random start tiles
# 'examples/clock/clock.v' // Can only be tested on exact points in time :)
# 'examples/flappylearning/game.v' // Random movement
# 'examples/hot_reload/bounce.v' // Inacurrate captures
# 'examples/hot_reload/graph.v' // Inacurrate captures
# 'examples/ttf_font/example_ttf.v', // OK
# 'examples/sokol/01_cubes/cube.v', // Can pass with a warning and diff at around 1.2%
# 'examples/sokol/02_cubes_glsl/cube_glsl.v', // Inacurrate captures
# 'examples/sokol/03_march_tracing_glsl/rt_glsl.v', // Inacurrate captures
# 'examples/sokol/04_multi_shader_glsl/rt_glsl.v', // Inacurrate captures
# 'examples/sokol/05_instancing_glsl/rt_glsl.v', // Inacurrate captures
# 'examples/sokol/06_obj_viewer/show_obj.v', // Inacurrate captures

422
cmd/tools/vgret.v Normal file
View File

@@ -0,0 +1,422 @@
// Copyright (c) 2021 Lars Pontoppidan. All rights reserved.
// Use of this source code is governed by an MIT license
// that can be found in the LICENSE file.
//
// vgret (V Graphics REgression Tool) aids in generating screenshots of various graphical `gg`
// based V applications, in a structured directory hierarchy, with the intent of either:
// * Generate a directory structure of screenshots/images to test against
// (which, as an example, could later be pushed to a remote git repository)
// * Test for *visual* differences between two, structurally equal, directories
//
// vgret uses features and applications that is currently only available on Linux based distros:
// idiff : `sudo apt install openimageio-tools` to programmatically find *visual* differences between two images.
//
// For developers:
// For a quick overview of the generated images you can use `montage` from imagemagick to generate a "Contact Sheet":
// montage -verbose -label '%f' -font Helvetica -pointsize 10 -background '#000000' -fill 'gray' -define jpeg:size=200x200 -geometry 200x200+2+2 -auto-orient $(fd -t f . /path/to/vgret/out/dir) /tmp/montage.jpg
//
// To generate the reference images locally - or for uploading to a remote repo like `gg-regression-images`
// You can do the following:
// 1. `export DISPLAY=:99` # Start all graphical apps on DISPLAY 99
// 2. `Xvfb $DISPLAY -screen 0 1280x1024x24 &` # Starts a virtual X11 screen buffer
// 3. `v gret -v /tmp/gg-regression-images` # Generate reference images to /tmp/gg-regression-images
// 4. `v gret -v /tmp/test /tmp/gg-regression-images` # Test if the tests can pass locally by comparing to a fresh imageset
// 5. Visually check the images (you can get an overview by running the `montage` command above)
// 6. Upload to GitHub or keep locally for more testing/tweaking
//
// It's a known factor that the images generated on a local machine won't match the images generated on a remote machine by 100%.
// They will most likely differ by a small percentage - the comparison tool can be tweaked to accept these subtle changes,
// at the expense of slightly more inaccurate test results. For non-animated apps the percentage should be > 0.01.
// You can emulate or test these inaccuracies to some extend locally by simply running the test from a terminal using
// your physical X11 session display (Usually DISPLAY=:0).
//
// Read more about the options of `idiff` here: https://openimageio.readthedocs.io/en/latest/idiff.html
//
import os
import flag
import toml
const (
tool_name = os.file_name(os.executable())
tool_version = '0.0.1'
tool_description = '\n Dump and/or compare rendered frames of `gg` based apps
Examples:
Generate screenshots to `/tmp/test`
v gret /tmp/test
Generate and compare screenshots in `/tmp/src` to existing screenshots in `/tmp/dst`
v gret /tmp/src /tmp/dst
Compare screenshots in `/tmp/src` to existing screenshots in `/tmp/dst`
v gret --compare-only /tmp/src /tmp/dst
'
tmp_dir = os.join_path(os.temp_dir(), 'v', tool_name)
runtime_os = os.user_os()
v_root = os.real_path(@VMODROOT)
)
const (
supported_hosts = ['linux']
// External tool executables
v_exe = vexe()
idiff_exe = os.find_abs_path_of_executable('idiff') or { '' }
)
const (
embedded_toml = $embed_file('vgret.defaults.toml', .zlib)
default_toml = embedded_toml.to_string()
empty_toml_array = []toml.Any{}
empty_toml_map = map[string]toml.Any{}
)
struct Config {
path string
mut:
apps []AppConfig
}
struct CompareOptions {
mut:
method string = 'idiff'
flags []string
}
struct CaptureOptions {
mut:
method string = 'gg_record'
flags []string
env map[string]string
}
struct AppConfig {
compare CompareOptions
capture CaptureOptions
path string
abs_path string
mut:
screenshots_path string
screenshots []string
}
struct Options {
verbose bool
compare_only bool
root_path string
mut:
config Config
}
fn main() {
if os.args.len == 1 {
println('Usage: $tool_name PATH \n$tool_description\n$tool_name -h for more help...')
exit(1)
}
mut fp := flag.new_flag_parser(os.args[1..])
fp.application(tool_name)
fp.version(tool_version)
fp.description(tool_description)
fp.arguments_description('PATH [PATH]')
fp.skip_executable()
show_help := fp.bool('help', `h`, false, 'Show this help text.')
if show_help {
println(fp.usage())
exit(0)
}
// Collect tool options
mut opt := Options{
verbose: fp.bool('verbose', `v`, false, "Be verbose about the tool's progress.")
compare_only: fp.bool('compare-only', `c`, false, "Don't generate screenshots - only compare input directories")
root_path: fp.string('root-path', `r`, v_root, 'Root path of the comparison')
}
toml_conf := fp.string('toml-config', `t`, default_toml, 'Path or string with TOML configuration')
ensure_env(opt) or { panic(err) }
arg_paths := fp.finalize() or { panic(err) }
if arg_paths.len == 0 {
println(fp.usage())
println('\nError missing arguments')
exit(1)
}
opt.config = new_config(opt.root_path, toml_conf) ?
gen_in_path := arg_paths[0]
if arg_paths.len >= 1 {
generate_screenshots(mut opt, gen_in_path) ?
}
if arg_paths.len > 1 {
target_path := arg_paths[1]
path := opt.config.path
all_paths_in_use := [path, gen_in_path, target_path]
for path_in_use in all_paths_in_use {
if !os.is_dir(path_in_use) {
panic('`$path_in_use` is not a directory')
}
}
if path == target_path || gen_in_path == target_path || gen_in_path == path {
panic('Compare paths can not be the same directory `$path`/`$target_path`/`$gen_in_path`')
}
compare_screenshots(opt, gen_in_path, target_path) or { panic(err) }
}
}
fn generate_screenshots(mut opt Options, output_path string) ? {
path := opt.config.path
dst_path := output_path.trim_right('/')
if !os.is_dir(path) {
return error('`$path` is not a directory')
}
for mut app_config in opt.config.apps {
file := app_config.path
app_path := app_config.abs_path
mut rel_out_path := ''
if os.is_file(app_path) {
rel_out_path = os.dir(file)
} else {
rel_out_path = file
}
if opt.verbose {
eprintln('Compiling shaders (if needed) for `$file`')
}
sh_result := os.execute('$v_exe shader "$app_path"')
if sh_result.exit_code != 0 {
if opt.verbose {
eprintln('Skipping shader compile for `$file` v shader failed with:\n$sh_result.output')
}
continue
}
if !os.exists(dst_path) {
if opt.verbose {
eprintln('Creating output path `$dst_path`')
}
os.mkdir_all(dst_path) ?
}
screenshot_path := os.join_path(dst_path, rel_out_path)
if !os.exists(screenshot_path) {
os.mkdir_all(screenshot_path) or {
return error('Failed making screenshot path `$screenshot_path`')
}
}
app_config.screenshots_path = screenshot_path
app_config.screenshots = take_screenshots(opt, app_config) or {
return error('Failed taking screenshots of `$app_path`:\n$err.msg')
}
}
}
fn compare_screenshots(opt Options, output_path string, target_path string) ? {
mut fails := map[string]string{}
mut warns := map[string]string{}
for app_config in opt.config.apps {
screenshots := app_config.screenshots
if opt.verbose {
eprintln('Comparing $screenshots.len screenshots in `$output_path` with `$target_path`')
}
for screenshot in screenshots {
relative_screenshot := screenshot.all_after(output_path + os.path_separator)
src := screenshot
target := os.join_path(target_path, relative_screenshot)
if opt.verbose {
eprintln('Comparing `$src` with `$target` with $app_config.compare.method')
}
if app_config.compare.method == 'idiff' {
if idiff_exe == '' {
return error('$tool_name need the `idiff` tool installed. It can be installed on Ubuntu with `sudo apt install openimageio-tools`')
}
diff_file := os.join_path(os.temp_dir(), os.file_name(src).all_before_last('.') +
'.diff.tif')
flags := app_config.compare.flags.join(' ')
diff_cmd := '$idiff_exe $flags -od -o "$diff_file" -abs "$src" "$target"'
result := os.execute(diff_cmd)
if opt.verbose && result.exit_code == 0 {
eprintln('Running: $diff_cmd')
eprintln('$result.output')
}
if result.exit_code != 0 {
eprintln('$result.output')
if result.exit_code == 1 {
warns[src] = target
} else {
fails[src] = target
}
}
}
}
}
if warns.len > 0 {
eprintln('--- WARNINGS ---')
eprintln('The following files had warnings when compared to their targets')
for warn_src, warn_target in warns {
eprintln('$warn_src ~= $warn_target')
}
}
if fails.len > 0 {
eprintln('--- ERRORS ---')
eprintln('The following files did not match their targets')
for fail_src, fail_target in fails {
eprintln('$fail_src != $fail_target')
}
first := fails.keys()[0]
fail_copy := os.join_path(os.temp_dir(), 'fail.' + first.all_after_last('.'))
os.cp(first, fail_copy) or { panic(err) }
eprintln('First failed file `$first` is copied to `$fail_copy`')
diff_file := os.join_path(os.temp_dir(), os.file_name(first).all_before_last('.') +
'.diff.tif')
diff_copy := os.join_path(os.temp_dir(), 'diff.tif')
if os.is_file(diff_file) {
os.cp(diff_file, diff_copy) or { panic(err) }
eprintln('First failed diff file `$diff_file` is copied to `$diff_copy`')
}
exit(1)
}
}
fn take_screenshots(opt Options, app AppConfig) ?[]string {
out_path := app.screenshots_path
if !opt.compare_only {
if opt.verbose {
eprintln('Taking screenshot(s) of `$app.path` to `$out_path`')
}
if app.capture.method == 'gg_record' {
for k, v in app.capture.env {
rv := v.replace('\$OUT_PATH', out_path)
if opt.verbose {
eprintln('Setting ENV `$k` = $rv ...')
}
os.setenv('$k', rv, true)
}
mut flags := app.capture.flags.join(' ')
v_cmd := '$v_exe $flags -d gg_record run "$app.abs_path"'
if opt.verbose {
eprintln('Running `$v_cmd`')
}
result := os.execute('$v_cmd')
if result.exit_code != 0 {
return error('Failed taking screenshot of `$app.abs_path`:\n$result.output')
}
}
}
mut screenshots := []string{}
shots := os.ls(out_path) or { return error('Failed listing dir `$out_path`') }
for shot in shots {
if shot.starts_with(os.file_name(app.path).all_before_last('.')) {
screenshots << os.join_path(out_path, shot)
}
}
return screenshots
}
// ensure_env returns nothing if everything is okay.
fn ensure_env(opt Options) ? {
if !os.exists(tmp_dir) {
os.mkdir_all(tmp_dir) ?
}
if runtime_os !in supported_hosts {
return error('$tool_name is currently only supported on $supported_hosts hosts')
}
}
// vexe returns the absolute path to the V compiler.
fn vexe() string {
mut exe := os.getenv('VEXE')
if os.is_executable(exe) {
return os.real_path(exe)
}
possible_symlink := os.find_abs_path_of_executable('v') or { '' }
if os.is_executable(possible_symlink) {
exe = os.real_path(possible_symlink)
}
return exe
}
fn new_config(root_path string, toml_config string) ?Config {
doc := toml.parse(toml_config) ?
path := os.real_path(root_path).trim_right('/')
compare_method := doc.value('compare.method').default_to('idiff').string()
compare_flags := doc.value('compare.flags').default_to(empty_toml_array).array().as_strings()
default_compare := CompareOptions{
method: compare_method
flags: compare_flags
}
capture_method := doc.value('capture.method').default_to('gg_record').string()
capture_flags := doc.value('capture.flags').default_to(empty_toml_array).array().as_strings()
capture_env := doc.value('capture.env').default_to(empty_toml_map).as_map()
mut env_map := map[string]string{}
for k, v in capture_env {
env_map[k] = v.string()
}
default_capture := CaptureOptions{
method: capture_method
flags: capture_flags
env: env_map
}
apps_any := doc.value('apps').default_to(empty_toml_array).array()
mut apps := []AppConfig{cap: apps_any.len}
for app_any in apps_any {
rel_path := app_any.value('path').string().trim_right('/')
// Merge, per app, overwrites
mut merged_compare := CompareOptions{}
merged_compare.method = app_any.value('compare.method').default_to(default_compare.method).string()
merged_compare_flags := app_any.value('compare.flags').default_to(empty_toml_array).array().as_strings()
if merged_compare_flags.len > 0 {
merged_compare.flags = merged_compare_flags
} else {
merged_compare.flags = default_compare.flags
}
mut merged_capture := CaptureOptions{}
merged_capture.method = app_any.value('capture.method').default_to(default_capture.method).string()
merged_capture_flags := app_any.value('capture.flags').default_to(empty_toml_array).array().as_strings()
if merged_capture_flags.len > 0 {
merged_capture.flags = merged_capture_flags
} else {
merged_capture.flags = default_capture.flags
}
merge_capture_env := app_any.value('capture.env').default_to(empty_toml_map).as_map()
mut merge_env_map := default_capture.env.clone()
for k, v in merge_capture_env {
merge_env_map[k] = v.string()
}
for k, v in merge_env_map {
merged_capture.env[k] = v
}
app_config := AppConfig{
compare: merged_compare
capture: merged_capture
path: rel_path
abs_path: os.join_path(path, rel_path).trim_right('/')
}
apps << app_config
}
return Config{
apps: apps
path: path
}
}

299
cmd/tools/vshader.v Normal file
View File

@@ -0,0 +1,299 @@
// Copyright (c) 2021 Lars Pontoppidan. All rights reserved.
// Use of this source code is governed by an MIT license
// that can be found in the LICENSE file.
//
// vshader aids in generating special shader code C headers via sokol-shdc's 'annotated GLSL' format to any
// supported target formats that sokol_gfx supports internally.
//
// vshader bootstraps itself by downloading it's own dependencies to a system cache directory on first run.
//
// Please see https://github.com/floooh/sokol-tools/blob/master/docs/sokol-shdc.md#feature-overview
// for a more in-depth overview of the specific tool in use.
//
// The shader language used is, as described on the overview page linked above, an 'annotated GLSL'
// and 'modern GLSL' (v450) shader language format.
import os
import io.util
import flag
import net.http
const (
tool_name = os.file_name(os.executable())
tool_version = '0.0.1'
tool_description = "Compile shaders in sokol's annotated GLSL format to C headers for use with sokol based apps"
cache_dir = os.join_path(os.cache_dir(), 'v', tool_name)
runtime_os = os.user_os()
)
const (
supported_hosts = ['linux', 'macos', 'windows']
supported_slangs = [
'glsl330', // desktop GL
'glsl100', // GLES2 / WebGL
'glsl300es', // GLES3 / WebGL2
'hlsl4', // D3D11
'hlsl5', // D3D11
'metal_macos', // Metal on macOS
'metal_ios', // Metal on iOS device
'metal_sim', // Metal on iOS simulator
'wgpu', // WebGPU
]
default_slangs = [
'glsl330',
'glsl100',
'glsl300es',
// 'hlsl4', and hlsl5 can't be used at the same time
'hlsl5',
'metal_macos',
'metal_ios',
'metal_sim',
'wgpu',
]
shdc_version = '33d2e4cc'
shdc_urls = {
'windows': 'https://github.com/floooh/sokol-tools-bin/raw/33d2e4cc26088c6c28eaef5467990f8940d15aab/bin/win32/sokol-shdc.exe'
'macos': 'https://github.com/floooh/sokol-tools-bin/raw/33d2e4cc26088c6c28eaef5467990f8940d15aab/bin/osx/sokol-shdc'
'linux': 'https://github.com/floooh/sokol-tools-bin/raw/33d2e4cc26088c6c28eaef5467990f8940d15aab/bin/linux/sokol-shdc'
}
shdc_version_file = os.join_path(cache_dir, 'sokol-shdc.version')
shdc = shdc_exe()
shdc_exe_name = 'sokol-shdc.exe'
)
struct Options {
show_help bool
verbose bool
force_update bool
slangs []string
}
struct CompileOptions {
verbose bool
slangs []string
invoke_path string
}
fn main() {
if os.args.len == 1 {
println('Usage: $tool_name PATH \n$tool_description\n$tool_name -h for more help...')
exit(1)
}
mut fp := flag.new_flag_parser(os.args[1..])
fp.application(tool_name)
fp.version(tool_version)
fp.description(tool_description)
fp.arguments_description('PATH [PATH]...')
fp.skip_executable()
// Collect tool options
opt := Options{
show_help: fp.bool('help', `h`, false, 'Show this help text.')
force_update: fp.bool('force-update', `u`, false, 'Force update of the sokol-shdc tool.')
verbose: fp.bool('verbose', `v`, false, 'Be verbose about the tools progress.')
slangs: fp.string_multi('slang', `l`, 'Shader dialects to generate code for. Default is all.\n Available dialects: $supported_slangs')
}
if opt.show_help {
println(fp.usage())
exit(0)
}
ensure_external_tools(opt) or { panic(err) }
input_paths := fp.finalize() or { panic(err) }
for path in input_paths {
if os.exists(path) {
compile_shaders(opt, path) or { panic(err) }
}
}
}
// shader_program_name returns the name of the program from `shader_file`.
// shader_program_name returns a blank string if no @program entry could be found.
fn shader_program_name(shader_file string) string {
shader_program := os.read_lines(shader_file) or { return '' }
for line in shader_program {
if line.contains('@program ') {
return line.all_after('@program ').all_before(' ')
}
}
return ''
}
// validate_shader_file returns an error if `shader_file` isn't valid.
fn validate_shader_file(shader_file string) ? {
shader_program := os.read_lines(shader_file) or {
return error('shader program at "$shader_file" could not be opened for reading')
}
mut has_program_directive := false
for line in shader_program {
if line.contains('@program ') {
has_program_directive = true
break
}
}
if !has_program_directive {
return error('shader program at "$shader_file" is missing a "@program" directive.')
}
}
// compile_shaders compiles all `*.glsl` files found in `input_path`
// to their C header file representatives.
fn compile_shaders(opt Options, input_path string) ? {
mut path := os.real_path(input_path)
path = path.trim_right('/')
if os.is_file(path) {
path = os.dir(path)
}
mut shader_files := []string{}
collect(path, mut shader_files)
if shader_files.len == 0 {
if opt.verbose {
eprintln('$tool_name found no shader files to compile for "$path"')
}
return
}
for shader_file in shader_files {
// It could be the user has WIP shader files lying around not used,
// so we just report that there's something wrong
validate_shader_file(shader_file) or {
eprintln(err)
continue
}
co := CompileOptions{
verbose: opt.verbose
slangs: opt.slangs
invoke_path: path
}
// Currently sokol-shdc allows for multiple --input flags
// - 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
compile_shader(co, shader_file) ?
}
}
// compile_shader compiles `shader_file` to a C header file.
fn compile_shader(opt CompileOptions, shader_file string) ? {
path := opt.invoke_path
// The output convetion, for now, is to use the name of the .glsl file
mut out_file := os.file_name(shader_file).all_before_last('.') + '.h'
out_file = os.join_path(path, out_file)
mut slangs := opt.slangs.clone()
if opt.slangs.len == 0 {
slangs = default_slangs.clone()
}
header_name := os.file_name(out_file)
if opt.verbose {
eprintln('$tool_name generating shader code for $slangs in header "$header_name" in "$path" from $shader_file')
}
cmd := '$shdc --input "$shader_file" --output "$out_file" --slang "' + slangs.join(':') + '"'
if opt.verbose {
eprintln('$tool_name executing:\n$cmd')
}
res := os.execute(cmd)
if res.exit_code != 0 {
eprintln('$tool_name failed generating shader includes:\n $res.output\n $cmd')
exit(1)
}
if opt.verbose {
program_name := shader_program_name(shader_file)
eprintln('$tool_name usage example in V:\n\nimport sokol.gfx\n\n#include "$header_name"\n\nfn C.${program_name}_shader_desc(gfx.Backend) &C.sg_shader_desc\n')
}
}
// collect recursively collects `.glsl` file entries from `path` in `list`.
fn collect(path string, mut list []string) {
if !os.is_dir(path) {
return
}
mut files := os.ls(path) or { return }
for file in files {
p := os.join_path(path, file)
if os.is_dir(p) && !os.is_link(p) {
collect(p, mut list)
} else if os.exists(p) {
if os.file_ext(p) == '.glsl' {
list << os.real_path(p)
}
}
}
return
}
// ensure_external_tools returns nothing if the external
// tools can be setup or is already in place.
fn ensure_external_tools(opt Options) ? {
if !os.exists(cache_dir) {
os.mkdir_all(cache_dir) ?
}
if opt.force_update {
download_shdc(opt) ?
return
}
is_shdc_available := os.is_file(shdc)
is_shdc_executable := os.is_executable(shdc)
if is_shdc_available && is_shdc_executable {
if opt.verbose {
version := os.read_file(shdc_version_file) or { 'unknown' }
eprintln('$tool_name using sokol-shdc version $version at "$shdc"')
}
return
}
download_shdc(opt) ?
}
// shdc_exe returns an absolute path to the `sokol-shdc` tool.
// Please note that the tool isn't guaranteed to actually be present, nor is
// it guaranteed that it can be invoked.
fn shdc_exe() string {
return os.join_path(cache_dir, shdc_exe_name)
}
// download_shdc downloads the `sokol-shdc` tool to an OS specific cache directory.
fn download_shdc(opt Options) ? {
// We want to use the same, runtime, OS type as this tool is invoked on.
download_url := shdc_urls[runtime_os] or { '' }
if download_url == '' {
return error('$tool_name failed to download an external dependency "sokol-shdc" for ${runtime_os}.\nThe supported host platforms for shader compilation is $supported_hosts')
}
update_to_shdc_version := os.read_file(shdc_version_file) or { shdc_version }
file := shdc_exe()
if opt.verbose {
if shdc_version != update_to_shdc_version && os.exists(file) {
eprintln('$tool_name updating sokol-shdc to version $update_to_shdc_version ...')
} else {
eprintln('$tool_name installing sokol-shdc version $update_to_shdc_version ...')
}
}
if os.exists(file) {
os.rm(file) ?
}
mut dtmp_file, dtmp_path := util.temp_file(util.TempFileOptions{ path: os.dir(file) }) ?
dtmp_file.close()
if opt.verbose {
eprintln('$tool_name downloading sokol-shdc from $download_url')
}
http.download_file(download_url, dtmp_path) or {
os.rm(dtmp_path) ?
return error('$tool_name failed to download sokol-shdc needed for shader compiling: $err')
}
// Make it executable
os.chmod(dtmp_path, 0o775) ?
// Move downloaded file in place
os.mv(dtmp_path, file) ?
if runtime_os in ['linux', 'macos'] {
// Use the .exe file ending to minimize platform friction.
os.mv(file, shdc) ?
}
// Update internal version file
os.write_file(shdc_version_file, update_to_shdc_version) ?
}

View File

@@ -70,7 +70,7 @@ fn setup_symlink_windows(vexe string) {
if os.exists(vsymlink) {
os.rm(vsymlink) or { panic(err) }
}
os.write_file(vsymlink, '@echo off\n$vexe %*') or { panic(err) }
os.write_file(vsymlink, '@echo off\n"$vexe" %*') or { panic(err) }
eprintln('$vsymlink file written.')
}
if !os.exists(vsymlink) {

View File

@@ -67,10 +67,43 @@ fn get_all_commands() []Command {
line: '$vexe -o - examples/hello_world.v | grep "#define V_COMMIT_HASH" > /dev/null'
okmsg: 'V prints the generated source code to stdout with `-o -` .'
}
}
res << Command{
line: '$vexe run examples/v_script.vsh'
okmsg: 'V can run the .VSH script file examples/v_script.vsh'
res << Command{
line: '$vexe run examples/v_script.vsh > /dev/null'
okmsg: 'V can run the .VSH script file examples/v_script.vsh'
}
$if linux {
res << Command{
line: '$vexe -b native run examples/native/hello_world.v > /dev/null'
okmsg: 'V compiles and runs examples/native/hello_world.v on the native backend for linux'
}
}
// only compilation:
res << Command{
line: '$vexe -os linux -b native -o hw.linux examples/hello_world.v'
okmsg: 'V compiles hello_world.v on the native backend for linux'
rmfile: 'hw.linux'
}
res << Command{
line: '$vexe -os macos -b native -o hw.macos examples/hello_world.v'
okmsg: 'V compiles hello_world.v on the native backend for macos'
rmfile: 'hw.macos'
}
res << Command{
line: '$vexe -os windows -b native -o hw.exe examples/hello_world.v'
okmsg: 'V compiles hello_world.v on the native backend for windows'
rmfile: 'hw.exe'
}
//
res << Command{
line: '$vexe -b js -o hw.js examples/hello_world.v'
okmsg: 'V compiles hello_world.v on the JS backend'
rmfile: 'hw.js'
}
res << Command{
line: '$vexe -skip-unused -b js -o hw_skip_unused.js examples/hello_world.v'
okmsg: 'V compiles hello_world.v on the JS backend, with -skip-unused'
rmfile: 'hw_skip_unused.js'
}
}
res << Command{
line: '$vexe -o vtmp cmd/v'
@@ -148,7 +181,7 @@ fn get_all_commands() []Command {
}
$if macos || linux {
res << Command{
line: '$vexe -o v.c cmd/v && cc -Werror v.c && rm -rf a.out'
line: '$vexe -o v.c cmd/v && cc -Werror -I "$vroot/thirdparty/stdatomic/nix" v.c -lpthread -lm && rm -rf a.out'
label: 'v.c should be buildable with no warnings...'
okmsg: 'v.c can be compiled without warnings. This is good :)'
rmfile: 'v.c'

View File

@@ -28,12 +28,8 @@ const (
'vlib/gg/m4/graphic.v',
'vlib/gg/m4/m4_test.v',
'vlib/gg/m4/matrix.v',
'vlib/sqlite/orm.v' /* mut c &int -> mut c int */,
'vlib/builtin/int_test.v' /* special number formatting that should be tested */,
// TODOs and unfixed vfmt bugs
'vlib/builtin/int.v' /* TODO byteptr: vfmt converts `pub fn (nn byteptr) str() string {` to `nn &byte` and that conflicts with `nn byte` */,
'vlib/builtin/string_charptr_byteptr_helpers.v' /* TODO byteptr: a temporary shim to ease the byteptr=>&byte transition */,
'vlib/v/tests/interop_test.v', /* bad comment formatting */
'vlib/v/gen/js/tests/js.v', /* local `hello` fn, gets replaced with module `hello` aliased as `hl` */
]
vfmt_verify_list = [
@@ -44,8 +40,6 @@ const (
]
vfmt_known_failing_exceptions = arrays.merge(verify_known_failing_exceptions, [
'vlib/regex/regex_test.v' /* contains meaningfull formatting of the test case data */,
'vlib/readline/readline_test.v' /* vfmt eats `{ Readline }` from `import readline { Readline }` */,
'vlib/glm/glm.v' /* `mut res &f32` => `mut res f32`, which then fails to compile */,
'vlib/crypto/sha512/sha512block_generic.v' /* formatting of large constant arrays wraps to too many lines */,
'vlib/crypto/aes/const.v' /* formatting of large constant arrays wraps to too many lines */,
])

View File

@@ -8,6 +8,7 @@ const github_job = os.getenv('GITHUB_JOB')
const (
skip_test_files = [
'vlib/context/onecontext/onecontext_test.v',
'vlib/context/deadline_test.v' /* sometimes blocks */,
'vlib/mysql/mysql_orm_test.v' /* mysql not installed */,
'vlib/pg/pg_orm_test.v' /* pg not installed */,
@@ -69,6 +70,7 @@ const (
]
skip_on_musl = [
'vlib/v/tests/profile/profile_test.v',
'vlib/gg/draw_fns_api_test.v',
]
skip_on_ubuntu_musl = [
//'vlib/v/gen/js/jsgen_test.v',
@@ -91,6 +93,7 @@ const (
'vlib/net/http/header_test.v',
'vlib/net/http/server_test.v',
'vlib/net/http/response_test.v',
'vlib/builtin/js/array_test.js.v',
]
skip_on_linux = [
'do_not_remove',
@@ -99,9 +102,14 @@ const (
'do_not_remove',
]
skip_on_windows = [
'vlib/context/cancel_test.v',
'vlib/context/deadline_test.v',
'vlib/context/empty_test.v',
'vlib/context/value_test.v',
'vlib/orm/orm_test.v',
'vlib/v/tests/orm_sub_struct_test.v',
'vlib/v/tests/closure_test.v',
'vlib/v/tests/closure_generator_test.v',
'vlib/net/websocket/ws_test.v',
'vlib/net/unix/unix_test.v',
'vlib/net/websocket/websocket_test.v',
@@ -109,6 +117,8 @@ const (
'vlib/vweb/request_test.v',
'vlib/net/http/request_test.v',
'vlib/vweb/route_test.v',
'vlib/sync/many_times_test.v',
'vlib/sync/once_test.v',
]
skip_on_non_windows = [
'do_not_remove',
@@ -122,8 +132,20 @@ const (
skip_on_amd64 = [
'do_not_remove',
]
skip_on_non_amd64 = [
'vlib/v/tests/closure_test.v' /* not implemented yet */,
skip_on_arm64 = [
'vlib/v/tests/closure_generator_test.v',
'do_not_remove',
]
skip_on_non_amd64_or_arm64 = [
// closures aren't implemented yet:
'vlib/v/tests/closure_test.v',
'vlib/context/cancel_test.v',
'vlib/context/deadline_test.v',
'vlib/context/empty_test.v',
'vlib/context/value_test.v',
'vlib/context/onecontext/onecontext_test.v',
'vlib/sync/once_test.v',
'vlib/sync/many_times_test.v',
'do_not_remove',
]
)
@@ -138,12 +160,23 @@ fn main() {
args_string := args[1..].join(' ')
cmd_prefix := args_string.all_before('test-self')
title := 'testing vlib'
all_test_files := os.walk_ext(os.join_path(vroot, 'vlib'), '_test.v')
mut all_test_files := os.walk_ext(os.join_path(vroot, 'vlib'), '_test.v')
test_js_files := os.walk_ext(os.join_path(vroot, 'vlib'), '_test.js.v')
all_test_files << test_js_files
testing.eheader(title)
mut tsession := testing.new_test_session(cmd_prefix, true)
tsession.files << all_test_files.filter(!it.contains('testdata' + os.path_separator))
tsession.skip_files << skip_test_files
if !testing.is_node_present {
testroot := vroot + os.path_separator
tsession.skip_files << test_js_files.map(it.replace(testroot, ''))
}
testing.find_started_process('mysqld') or {
tsession.skip_files << 'vlib/mysql/mysql_orm_test.v'
}
testing.find_started_process('postgres') or { tsession.skip_files << 'vlib/pg/pg_orm_test.v' }
if github_job == 'windows-tcc' {
// TODO: fix these ASAP
tsession.skip_files << 'vlib/net/tcp_test.v'
@@ -205,12 +238,15 @@ fn main() {
if os.getenv('V_CI_UBUNTU_MUSL').len > 0 {
tsession.skip_files << skip_on_ubuntu_musl
}
$if !amd64 {
$if !amd64 && !arm64 {
tsession.skip_files << skip_on_non_amd64
}
$if amd64 {
tsession.skip_files << skip_on_amd64
}
$if arm64 {
tsession.skip_files << skip_on_arm64
}
$if !linux {
tsession.skip_files << skip_on_non_linux
}

View File

@@ -5,6 +5,13 @@ import os.cmdline
import testing
import v.pref
struct Context {
mut:
verbose bool
fail_fast bool
run_only []string
}
fn main() {
args := os.args.clone()
if os.args.last() == 'test' {
@@ -12,9 +19,14 @@ fn main() {
return
}
args_to_executable := args[1..]
args_before := cmdline.options_before(args_to_executable, ['test'])
args_after := cmdline.options_after(args_to_executable, ['test'])
if args_after.join(' ') == 'v' {
mut args_before := cmdline.options_before(args_to_executable, ['test'])
mut args_after := cmdline.options_after(args_to_executable, ['test'])
mut ctx := Context{}
ctx.fail_fast = extract_flag_bool('-fail-fast', mut args_after, testing.fail_fast)
ctx.verbose = extract_flag_bool('-v', mut args_after, false)
ctx.run_only = extract_flag_string_array('-run-only', mut args_after, testing.test_only_fn)
os.setenv('VTEST_ONLY_FN', ctx.run_only.join(','), true)
if args_after == ['v'] {
eprintln('`v test v` has been deprecated.')
eprintln('Use `v test-all` instead.')
exit(1)
@@ -23,20 +35,25 @@ fn main() {
backend := if backend_pos == -1 { '.c' } else { args_before[backend_pos + 1] } // this giant mess because closures are not implemented
mut ts := testing.new_test_session(args_before.join(' '), true)
ts.fail_fast = ctx.fail_fast
for targ in args_after {
if os.is_dir(targ) {
// Fetch all tests from the directory
files, skip_files := should_test_dir(targ.trim_right(os.path_separator), backend)
files, skip_files := ctx.should_test_dir(targ.trim_right(os.path_separator),
backend)
ts.files << files
ts.skip_files << skip_files
continue
} else if os.exists(targ) {
match should_test(targ, backend) {
match ctx.should_test(targ, backend) {
.test {
ts.files << targ
continue
}
.skip {
if ctx.run_only.len > 0 {
continue
}
ts.files << targ
ts.skip_files << targ
continue
@@ -69,7 +86,7 @@ fn show_usage() {
println('')
}
pub fn should_test_dir(path string, backend string) ([]string, []string) { // return is (files, skip_files)
pub fn (mut ctx Context) should_test_dir(path string, backend string) ([]string, []string) { // return is (files, skip_files)
mut files := os.ls(path) or { return []string{}, []string{} }
mut local_path_separator := os.path_separator
if path.ends_with(os.path_separator) {
@@ -83,15 +100,18 @@ pub fn should_test_dir(path string, backend string) ([]string, []string) { // re
if file == 'testdata' {
continue
}
ret_files, ret_skip_files := should_test_dir(p, backend)
ret_files, ret_skip_files := ctx.should_test_dir(p, backend)
res_files << ret_files
skip_files << ret_skip_files
} else if os.exists(p) {
match should_test(p, backend) {
match ctx.should_test(p, backend) {
.test {
res_files << p
}
.skip {
if ctx.run_only.len > 0 {
continue
}
res_files << p
skip_files << p
}
@@ -103,14 +123,34 @@ pub fn should_test_dir(path string, backend string) ([]string, []string) { // re
}
enum ShouldTestStatus {
test // do test
skip
ignore
test // do test, print OK or FAIL, depending on if it passes
skip // print SKIP for the test
ignore // just ignore the file, so it will not be printed at all in the list of tests
}
fn should_test(path string, backend string) ShouldTestStatus {
fn (mut ctx Context) should_test(path string, backend string) ShouldTestStatus {
if path.ends_with('mysql_orm_test.v') {
testing.find_started_process('mysqld') or { return .skip }
}
if path.ends_with('pg_orm_test.v') {
testing.find_started_process('postgres') or { return .skip }
}
if path.ends_with('onecontext_test.v') {
return .skip
}
$if tinyc {
if path.ends_with('naked_attr_test.amd64.v') {
return .skip
}
}
if path.ends_with('_test.v') {
return .test
return ctx.should_test_when_it_contains_matching_fns(path, backend)
}
if path.ends_with('_test.js.v') {
if testing.is_node_present {
return ctx.should_test_when_it_contains_matching_fns(path, backend)
}
return .skip
}
if path.ends_with('.v') && path.count('.') == 2 {
if !path.all_before_last('.v').all_before_last('.').ends_with('_test') {
@@ -119,13 +159,21 @@ fn should_test(path string, backend string) ShouldTestStatus {
backend_arg := path.all_before_last('.v').all_after_last('.')
arch := pref.arch_from_string(backend_arg) or { pref.Arch._auto }
if arch == pref.get_host_arch() {
return .test
return ctx.should_test_when_it_contains_matching_fns(path, backend)
} else if arch == ._auto {
if backend_arg == 'c' { // .c.v
return if backend == 'c' { ShouldTestStatus.test } else { ShouldTestStatus.skip }
return if backend == 'c' {
ctx.should_test_when_it_contains_matching_fns(path, backend)
} else {
ShouldTestStatus.skip
}
}
if backend_arg == 'js' {
return if backend == 'js' { ShouldTestStatus.test } else { ShouldTestStatus.skip }
return if backend == 'js' {
ctx.should_test_when_it_contains_matching_fns(path, backend)
} else {
ShouldTestStatus.skip
}
}
} else {
return .skip
@@ -133,3 +181,53 @@ fn should_test(path string, backend string) ShouldTestStatus {
}
return .ignore
}
fn (mut ctx Context) should_test_when_it_contains_matching_fns(path string, backend string) ShouldTestStatus {
if ctx.run_only.len == 0 {
// no filters set, so just compile and test
return .test
}
lines := os.read_lines(path) or { return .ignore }
for line in lines {
if line.match_glob('fn test_*') || line.match_glob('pub fn test_*') {
tname := line.replace_each(['pub fn ', '', 'fn ', '']).all_before('(')
for pattern in ctx.run_only {
mut pat := pattern.clone()
if pat.contains('.') {
pat = pat.all_after_last('.')
}
if tname.match_glob(pat) {
if ctx.verbose {
println('> compiling path: $path, since test fn `$tname` matches glob pattern `$pat`')
}
return .test
}
}
}
}
return .ignore
}
fn extract_flag_bool(flag_name string, mut after []string, flag_default bool) bool {
mut res := flag_default
orig_after := after.clone() // workaround for after.filter() codegen bug, when `mut after []string`
matches_after := orig_after.filter(it != flag_name)
if matches_after.len < after.len {
after = matches_after.clone()
res = true
}
return res
}
fn extract_flag_string_array(flag_name string, mut after []string, flag_default []string) []string {
mut res := flag_default.clone()
mut found := after.index(flag_name)
if found > -1 {
if found + 1 < after.len {
res = after[found + 1].split_any(',')
after.delete(found)
}
after.delete(found)
}
return res
}

View File

@@ -61,7 +61,7 @@ fn get_scan_timeout_seconds() int {
struct VFileStat {
path string
mtime int
mtime i64
}
[unsafe]
@@ -300,7 +300,6 @@ const ccontext = Context{
}
fn main() {
dump(scan_timeout_s)
mut context := unsafe { &Context(voidptr(&ccontext)) }
context.pid = os.getpid()
context.vexe = os.getenv('VEXE')
@@ -314,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.arguments_description('[--silent] [--clear] [--ignore .db] [--add /path/to/a/file.v] [run] program.v')
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.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.')

View File

@@ -119,7 +119,12 @@ see also `v help build`.
explicitly supported platforms without source changes.
-m32, -m64
Specify whether 32-bit or 64-bit machine code is generated.
Whether 32-bit or 64-bit machine code will be generated.
NB: if you need to produce 32-bit code, *and* you are cross compiling
to another OS, you may need to also set the environment variable
VCROSS_COMPILER_NAME, in order to override the default cross compiler,
that V will use (`x86_64-w64-mingw32-gcc` for targeting Windows, and
`clang` for targeting Linux from other operating systems).
-sanitize
Pass flags related to sanitization to the C compiler.
@@ -153,6 +158,9 @@ see also `v help build`.
https://github.com/ivmai/bdwgc
On Mac OS, it can be installed using homebrew (https://homebrew.sh/) with
`brew install libgc`.
Note, `-gc boehm` is complementary to -autofree. The Boehm garbage
collector is conservative, and it may make your program significantly
slower if it does many small allocations in a loop. This option
@@ -238,7 +246,7 @@ see also `v help build`.
compiler, on the command line, without writing an .rsp file first.
-no-std
By default, V passes -std=c99 to the C backend, but some compilers do
By default, V passes -std=gnu99(linux)/-std=c99 to the C backend, but some compilers do
not support that, even though they may be able to compile the produced
code, or have other options that can be tuned to allow it.
Passing -no-std will remove that flag, and you can then use -cflags ''

View File

@@ -2,9 +2,17 @@ Usage: v -b js [-options] ['run'] <target.v|target_directory> [run options]
This command compiles the given target, along with their dependencies, into an Javascript source file.
Note that `js` defaults to the `node` codegen backend but it's also possible to pick another:
* `js_browser` - V outputs JS source code ready for the browser.
* `js_node` - V outputs JS source code to run with nodejs.
* `js_freestanding` - V outputs JS source code with no hard runtime dependency.
For more general build help, see also `v help build`.
# Interfacing the Javascript Backend code generation, passing options to it:
-es5
Compile V to ES5 compatible code possibly shrinking output. Note that this flag might limit some types capabilities.
-prod
Do not create any JS Doc comments
@@ -19,4 +27,4 @@ For more general build help, see also `v help build`.
Include the orginal V source files into the generated source map
(default false, all files in the source map are currently referenced by their absolute system file path)
The supported targets for the JS backend are: ES5 strict
The supported targets for the JS backend are: ES6 strict

View File

@@ -90,9 +90,18 @@ NB: the build flags are shared with the run command too:
The checker will abort prematurely once this limit has been reached.
Setting this to 0 or a negative value, will disable the limit.
-no-parallel
Do not run the compiler in parallel (currently only the cgen stage has parallelization).
-profile-no-inline
Skip [inline] functions when profiling.
-skip-unused
Skip generating C/JS code for functions, that are provably not used by your project.
This speeds up compilation, and reduces the generated output size.
It is still experimental, due to historical reasons, but please do try it,
and report issues, if compilation breaks with that option for your program.
-stats
Enable more detailed statistics reporting, while compiling test files.
You can use that with `v test` too, for example:

28
cmd/v/help/bump.txt Normal file
View File

@@ -0,0 +1,28 @@
Usage: v bump [options] [file1 file2 ...]
Description:
Bump the semantic version of the v.mod and/or specified files.
The first instance of a version number is replaced with the new version.
Additionally, the line affected must contain the word "version" in any
form of capitalization. For instance, the following lines will be
recognized by the heuristic:
tool_version = '1.2.1'
version: '0.2.42'
VERSION = "1.23.8"
Examples:
Bump the patch version in v.mod if it exists
v bump --patch
Bump the major version in v.mod and vls.v
v bump --major v.mod vls.v
Upgrade the minor version in sample.v only
v bump --minor sample.v
Options:
-h, --help Show this help text.
-m, --major Bump the major version.
-n, --minor Bump the minor version.
-p, --patch Bump the patch version.

View File

@@ -18,6 +18,9 @@ Options:
-l List files whose formatting differs from vfmt.
-w Write result to (source) file(s) instead of to stdout.
-backup In combination with `-w`, copy the original `file.v` to a `file.v.bak` backup,
before overwriting the original source file.
-debug Print the kinds of encountered AST statements/expressions on stderr.

19
cmd/v/help/gret.txt Normal file
View File

@@ -0,0 +1,19 @@
Usage:
v gret [options] PATH [PATH]
Description:
Dump and/or compare rendered frames of `gg` based apps
Examples:
Generate screenshots to `/tmp/test`
v gret /tmp/test
Generate and compare screenshots in `/tmp/src` to existing screenshots in `/tmp/dst`
v gret /tmp/src /tmp/dst
Compare screenshots in `/tmp/src` to existing screenshots in `/tmp/dst`
v gret --compare-only /tmp/src /tmp/dst
Options:
-h, --help Show this help text.
-v, --verbose Be verbose about the tool's progress.
-c, --compare-only Don't generate screenshots - only compare input directories

17
cmd/v/help/shader.txt Normal file
View File

@@ -0,0 +1,17 @@
Usage:
v shader [options] [DIRECTORY / FILE]
Examples:
v shader .
v shader examples/sokol/02_cubes_glsl/cube_glsl.glsl
Compile shaders in sokol's annotated GLSL format to C headers for use with sokol based apps.
Sokol based apps include all apps using V's gg module.
Options:
-h, --help Show this help text.
-v, --verbose Be verbose about the tools progress.
-u, --force-update Force update of the sokol-shdc tool.
-l, --slang <multiple strings> Shader dialects to generate code for. Default is all.
Available: 'glsl330', 'glsl100', 'glsl300es', 'hlsl4', 'hlsl5', 'metal_macos', 'metal_ios', 'metal_sim', 'wgpu'

View File

@@ -1,18 +1,62 @@
Usage:
v [-stats] test FILE|DIRECTORY[...]
Runs test functions in the given FILEs and DIRECTORYs
v [-stats] test FILE|DIRECTORY[...] [-run-only GPATTERN1[,...]]
Runs test functions in the given FILEs and DIRECTORYs.
If '-stats' is given, more statistics about the tests are printed along
with a report of passes/failures
If you give `-run-only GPATTERN`, then *only* test functions, that do
match by name the given glob pattern `GPATTERN` will run. You can separate
multiple glob patterns with `,`.
If a _test.v file lacks matching functions for all of the glob patterns, it
will be ignored completely, so you can do in effect:
`v test . -run-only test_your_fn_name`
... and V will run only that test function, no matter how many _test.v
files you have, and how many other test_ functions exist in them.
NB: glob patterns support `*` which matches anything, and `?`, that
matches any single character. They are *NOT* regular expressions however.
NB 1: very frequently, when you work on a module you can cd into its folder,
and then you can perform:
v test .
v test .
... to run all the module's '_test.v' files.
NB 2: V builtin testing requires you to name your files with a _test.v
suffix, and to name your test functions with test_ prefix. Each 'test_'
function in a '_test.v' file will be called automatically by the test
framework. You can use `assert condition` inside each 'test_' function.
If the asserted condition fails, then v will record that and produce a
more detailed error message about where the failure was.
suffix, and to name your test functions with test_ prefix. Each function,
that starts with 'fn test_', and that is in a '_test.v' file will be called
automatically by the test framework.
NB 3: You can use `assert condition` inside each 'test_' function. If the
asserted condition fails, then v will record that, and produce a more detailed
error message, about where the failure was.
NB 4: Alternative test runners (for IDE integrations):
You can use several alternative test result formats, using `-test-runner name`,
or by setting VTEST_RUNNER (the command line option has higher priority).
The names of the available test runners are:
`simple` Fastest, does not import additional modules, does no processing.
`tap` Format the output as required by the Test Anything Protocol (TAP).
`normal` Supports color output, nicest/most human readable, the default.
You can also implement your own custom test runner, by providing the path to
your .v file, that implements it to this option. For example, see:
vlib/v/preludes/test_runner_tap.v .
NB 5: Filtering only specific _test.v files by name:
You can set the environment variable `VTEST_ONLY` to a list of strings, that
will have to be contained in the paths of the _test.v files.
Example:
`VTEST_ONLY=complex,stats v test . -run-only *sin*`
This will find all _test.v files that have either `complex` or `stats`
in their path, then for these test files, V test will find all that contain
`test_` functions that glob match `*sin*`, and run only them, so you
should see something like this:
```
OK [1/2] 164.671 ms vlib/math/stats/stats_test.v
OK [2/2] 184.842 ms vlib/math/complex/complex_test.v
------------------------------------------------------------------------------------------
Summary for all V _test.v files: 2 passed, 2 total. Runtime: 185 ms, on 2 parallel jobs.
```

View File

@@ -10,22 +10,28 @@ import v.pref
import v.util
import v.util.version
import v.builder
import v.builder.cbuilder
const (
external_tools = [
'ast',
'bin2v',
'bug',
'build-examples',
'build-tools',
'build-vbinaries',
'bump',
'check-md',
'complete',
'compress',
'doc',
'doctor',
'fmt',
'gret',
'repl',
'self',
'setup-freetype',
'shader',
'symlink',
'test',
'test-all', /* runs most of the tests and other checking tools, that will be run by the CI */
@@ -38,7 +44,6 @@ const (
'vet',
'wipe-cache',
'watch',
'ast',
]
list_of_flags_that_allow_duplicates = ['cc', 'd', 'define', 'cf', 'cflags']
)
@@ -48,7 +53,7 @@ fn main() {
$if time_v ? {
timers_should_print = true
}
mut timers := util.new_timers(timers_should_print)
mut timers := util.new_timers(should_print: timers_should_print, label: 'main')
timers.start('v total')
defer {
timers.show('v total')
@@ -57,10 +62,9 @@ fn main() {
timers.show('v start')
timers.start('parse_CLI_args')
args := os.args[1..]
// args = 123
if args.len == 0 || args[0] in ['-', 'repl'] {
// Running `./v` without args launches repl
if args.len == 0 {
// Running `./v` without args launches repl
if os.is_atty(0) != 0 {
cmd_exit := term.highlight_command('exit')
cmd_help := term.highlight_command('v help')
@@ -72,14 +76,15 @@ fn main() {
} else {
mut args_and_flags := util.join_env_vflags_and_os_args()[1..].clone()
args_and_flags << ['run', '-']
pref.parse_args(external_tools, args_and_flags)
pref.parse_args_and_show_errors(external_tools, args_and_flags, true)
}
}
util.launch_tool(false, 'vrepl', os.args[1..])
return
}
args_and_flags := util.join_env_vflags_and_os_args()[1..]
prefs, command := pref.parse_args(external_tools, args_and_flags)
mut args_and_flags := util.join_env_vflags_and_os_args()[1..]
prefs, command := pref.parse_args_and_show_errors(external_tools, args_and_flags,
true)
if prefs.use_cache && os.user_os() == 'windows' {
eprintln('-usecache is currently disabled on windows')
exit(1)
@@ -111,6 +116,9 @@ fn main() {
'vlib-docs' {
util.launch_tool(prefs.is_verbose, 'vdoc', ['doc', 'vlib'])
}
'interpret' {
util.launch_tool(prefs.is_verbose, 'builders/interpret_builder', os.args[1..])
}
'get' {
eprintln('V Error: Use `v install` to install modules from vpm.vlang.io')
exit(1)
@@ -124,7 +132,27 @@ fn main() {
if command in ['run', 'build', 'build-module'] || command.ends_with('.v') || os.exists(command) {
// println('command')
// println(prefs.path)
builder.compile(command, prefs)
match prefs.backend {
.c {
$if no_bootstrapv ? {
// TODO: improve the bootstrapping with a split C backend here.
// C code generated by `VEXE=v cmd/tools/builders/c_builder -os cross -o c.c cmd/tools/builders/c_builder.v`
// is enough to bootstrap the C backend, and thus the rest, but currently bootstrapping relies on
// `v -os cross -o v.c cmd/v` having a functional C codegen inside instead.
util.launch_tool(prefs.is_verbose, 'builders/c_builder', os.args[1..])
}
builder.compile('build', prefs, cbuilder.compile_c)
}
.js_node, .js_freestanding, .js_browser {
util.launch_tool(prefs.is_verbose, 'builders/js_builder', os.args[1..])
}
.native {
util.launch_tool(prefs.is_verbose, 'builders/native_builder', os.args[1..])
}
.interpret {
util.launch_tool(prefs.is_verbose, 'builders/interpret_builder', os.args[1..])
}
}
return
}
if prefs.is_help {

View File

@@ -65,6 +65,7 @@ For more details and troubleshooting, please visit the [vab GitHub repository](h
* [Comments](#comments)
* [Functions](#functions)
* [Returning multiple values](#returning-multiple-values)
* [Hoistings](#hoistings)
* [Symbol visibility](#symbol-visibility)
* [Variables](#variables)
* [V types](#v-types)
@@ -95,13 +96,12 @@ For more details and troubleshooting, please visit the [vab GitHub repository](h
* [Mutable arguments](#mutable-arguments)
* [Variable number of arguments](#variable-number-of-arguments)
* [Anonymous & higher-order functions](#anonymous--higher-order-functions)
* [Closures](#closures)
* [References](#references)
* [Constants](#constants)
* [Builtin functions](#builtin-functions)
* [Printing custom types](#printing-custom-types)
* [Modules](#modules)
* [Manage Packages](#manage-packages)
* [Publish package](#publish-package)
* [Type Declarations](#type-declarations)
* [Interfaces](#interfaces)
* [Enums](#enums)
@@ -124,7 +124,10 @@ For more details and troubleshooting, please visit the [vab GitHub repository](h
* [Writing documentation](#writing-documentation)
* [Tools](#tools)
* [v fmt](#v-fmt)
* [v shader](#v-shader)
* [Profiling](#profiling)
* [Package Management](#package-management)
* [Publish package](#publish-package)
* [Advanced Topics](#advanced-topics)
* [Dumping expressions at runtime](#dumping-expressions-at-runtime)
* [Memory-unsafe code](#memory-unsafe-code)
@@ -264,6 +267,8 @@ Again, the type comes after the argument's name.
Just like in Go and C, functions cannot be overloaded.
This simplifies the code and improves maintainability and readability.
### Hoistings
Functions can be used before their declaration:
`add` and `sub` are declared after `main`, but can still be called from `main`.
This is true for all declarations in V and eliminates the need for header files
@@ -475,7 +480,18 @@ windows_newline := '\r\n' // escape special characters like in C
assert windows_newline.len == 2
```
In V, a string is a read-only array of bytes. String data is encoded using UTF-8.
In V, a string is a read-only array of bytes. String data is encoded using UTF-8:
```v
s := 'hello 🌎' // emoji takes 4 bytes
assert s.len == 10
arr := s.bytes() // convert `string` to `[]byte`
assert arr.len == 10
s2 := arr.bytestr() // convert `[]byte` to `string`
assert s2 == s
```
String values are immutable. You cannot mutate elements:
```v failcompile
@@ -484,8 +500,8 @@ s[0] = `H` // not allowed
```
> error: cannot assign to `s[i]` since V strings are immutable
Note that indexing a string will produce a `byte`, not a `rune` nor another `string`.
Indexes correspond to bytes in the string, not Unicode code points. If you want to
Note that indexing a string will produce a `byte`, not a `rune` nor another `string`.
Indexes correspond to bytes in the string, not Unicode code points. If you want to
convert the `byte` to a `string`, use the `ascii_str()` method:
```v
@@ -688,6 +704,7 @@ arrays there is a second initialization syntax:
```v
mut a := []int{len: 10000, cap: 30000, init: 3}
```
This creates an array of 10000 `int` elements that are all initialized with `3`. Memory
space is reserved for 30000 elements. The parameters `len`, `cap` and `init` are optional;
`len` defaults to `0` and `init` to the default initialization of the element type (`0`
@@ -717,6 +734,13 @@ for i in 0 .. 1000 {
Note: The above code uses a [range `for`](#range-for) statement and a
[push operator (`<<`)](#array-operations).
You can initialize the array by accessing the `it` variable as shown here:
```v
mut square := []int{len: 6, init: it * it}
// square == [0, 1, 4, 9, 16, 25]
```
#### Array Types
An array can be of these types:
@@ -1029,7 +1053,7 @@ println(typeof(fnums).name) // => [3]int
fnums2 := [1, 10, 100]! // short init syntax that does the same (the syntax will probably change)
anums := fnums[0..fnums.len]
anums := fnums[..] // same as `anums := fnums[0..fnums.len]`
println(anums) // => [1, 10, 100]
println(typeof(anums).name) // => []int
```
@@ -1090,6 +1114,10 @@ The same optional check applies to arrays:
arr := [1, 2, 3]
large_index := 999
val := arr[large_index] or { panic('out of bounds') }
println(val)
// you can also do this, if you want to *propagate* the access error:
val2 := arr[333] ?
println(val2)
```
## Module imports
@@ -1300,7 +1328,7 @@ if mut x is MyStruct {
// same with match
match mut x {
MyStruct {
// x is casted to MyStruct even it's mutable
// x is casted to MyStruct even if it's mutable
// without the mut keyword that wouldn't work
println(x)
}
@@ -1816,7 +1844,6 @@ mut p := Point{
x: 10
y: 20
}
// you can omit the struct name when it's already known
p = Point{
x: 30
y: 4
@@ -1837,6 +1864,7 @@ V doesn't have default function arguments or named arguments, for that trailing
literal syntax can be used instead:
```v
[params]
struct ButtonConfig {
text string
is_disabled bool
@@ -1871,6 +1899,13 @@ new_button(ButtonConfig{text:'Click me', width:100})
This only works for functions that take a struct for the last argument.
NB: the `[params]` tag is used to tell V, that the trailing struct parameter
can be omitted *entirely*, so that you can write `button := new_button()`.
Without it, you have to specify *at least* one of the field names, even if it
has its default value, otherwise the compiler will produce this error message,
when you call the function with no parameters:
`error: expected 1 arguments, but got 0`.
### Access modifiers
Struct fields are private and immutable by default (making structs immutable as well).
@@ -2041,16 +2076,14 @@ println(nums)
Note, that you have to add `mut` before `nums` when calling this function. This makes
it clear that the function being called will modify the value.
It is preferable to return values instead of modifying arguments.
It is preferable to return values instead of modifying arguments,
e.g. `user = register(user)` (or `user.register()`) instead of `register(mut user)`.
Modifying arguments should only be done in performance-critical parts of your application
to reduce allocations and copying.
For this reason V doesn't allow the modification of arguments with primitive types (e.g. integers).
Only more complex types such as arrays and maps may be modified.
Use `user.register()` or `user = register(user)`
instead of `register(mut user)`.
#### Struct update syntax
V makes it easy to return a modified version of an object:
@@ -2137,6 +2170,8 @@ fn main() {
}
```
### Closures
V supports closures too.
This means that anonymous functions can inherit variables from the scope they were created in.
They must do so explicitly by listing all variables that are inherited.
@@ -2460,157 +2495,6 @@ fn init() {
The `init` function cannot be public - it will be called automatically. This feature is
particularly useful for initializing a C library.
### Manage Packages
Briefly:
```powershell
v [module option] [param]
```
###### module options:
```
install Install a module from VPM.
remove Remove a module that was installed from VPM.
search Search for a module from VPM.
update Update an installed module from VPM.
upgrade Upgrade all the outdated modules.
list List all installed modules.
outdated Show installed modules that need updates.
```
Read more:
You can also install modules already created by someone else with [VPM](https://vpm.vlang.io/):
```powershell
v install [module]
```
**Example:**
```powershell
v install ui
```
Modules could install directly from git or mercurial repositories.
```powershell
v install [--git|--hg] [url]
```
**Example:**
```powershell
v install --git https://github.com/vlang/markdown
```
Removing a module with v:
```powershell
v remove [module]
```
**Example:**
```powershell
v remove ui
```
Updating an installed module from [VPM](https://vpm.vlang.io/):
```powershell
v update [module]
```
**Example:**
```powershell
v update ui
```
Or you can update all your modules:
```powershell
v update
```
To see all the modules you have installed, you can use:
```powershell
v list
```
**Example:**
```powershell
> v list
Installed modules:
markdown
ui
```
To see all the modules you have installed, you can use:
outdated Show installed modules that need updates.
```powershell
v outdated
```
**Example:**
```powershell
> v outdated
Modules are up to date.
```
### Publish package
1. Put a `v.mod` file inside the toplevel folder of your module (if you
created your module with the command `v new mymodule` or `v init` you already have a v.mod file).
```sh
v new mymodule
Input your project description: My nice module.
Input your project version: (0.0.0) 0.0.1
Input your project license: (MIT)
Initialising ...
Complete!
```
Example `v.mod`:
```v ignore
Module {
name: 'mymodule'
description: 'My nice module.'
version: '0.0.1'
license: 'MIT'
dependencies: []
}
```
Minimal file structure:
```
v.mod
mymodule.v
```
Check that your module name is used in `mymodule.v`:
```v
module mymodule
pub fn hello_world() {
println('Hello World!')
}
```
2. Create a git repository in the folder with the `v.mod` file
(this is not required if you used `v new` or `v init`):
```sh
git init
git add .
git commit -m "INIT"
````
3. Create a public repository on github.com.
4. Connect your local repository to the remote repository and push the changes.
5. Add your module to the public V module registry VPM:
https://vpm.vlang.io/new
You will have to login with your Github account to register the module.
**Warning:** _Currently it is not possibility to edit your entry after submiting.
Check your module name and github url twice as this cannot be changed by you later._
6. The final module name is a combination of your github account and
the module name you provided e.g. `mygithubname.mymodule`.
**Optional:** tag your V module with `vlang` and `vlang-module` on github.com
to allow a better search experiance.
## Type Declarations
### Interfaces
@@ -2649,9 +2533,54 @@ for item in arr {
}
```
#### Implement an interface
A type implements an interface by implementing its methods and fields.
There is no explicit declaration of intent, no "implements" keyword.
An interface can have a `mut:` section. Implementing types will need
to have a `mut` receiver, for methods declared in the `mut:` section
of an interface.
```v
module main
pub interface Foo {
write(string) string
}
// => the method signature of a type, implementing interface Foo should be:
// `pub fn (s Type) write(a string) string`
pub interface Bar {
mut:
write(string) string
}
// => the method signature of a type, implementing interface Bar should be:
// `pub fn (mut s Type) write(a string) string`
struct MyStruct {}
// MyStruct implements the interface Foo, but *not* interface Bar
pub fn (s MyStruct) write(a string) string {
return a
}
fn main() {
s1 := MyStruct{}
fn1(s1)
// fn2(s1) -> compile error, since MyStruct does not implement Bar
}
fn fn1(s Foo) {
println(s.write('Foo'))
}
// fn fn2(s Bar) { // does not match
// println(s.write('Foo'))
// }
```
#### Casting an interface
We can test the underlying type of an interface using dynamic cast operators:
@@ -2707,6 +2636,31 @@ fn main() {
}
```
#### Embedded interface
Interfaces support embedding, just like structs:
```v
pub interface Reader {
mut:
read(mut buf []byte) ?int
}
pub interface Writer {
mut:
write(buf []byte) ?int
}
// ReaderWriter embeds both Reader and Writer.
// The effect is the same as copy/pasting all of the
// Reader and all of the Writer methods/fields into
// ReaderWriter.
pub interface ReaderWriter {
Reader
Writer
}
```
### Function Types
You can use type aliases for naming specific function signatures - for
@@ -2830,7 +2784,7 @@ println('Grocery IDs: $g1, $g2, $g3')
Output: `Grocery IDs: 0, 5, 6`.
Operations are not allowed on enum variables; they must be explicity cast to `int`.
Operations are not allowed on enum variables; they must be explicitly cast to `int`.
### Sum types
@@ -3452,7 +3406,7 @@ fn main() {
go fn (the_channel chan f64) {
_ := <-the_channel
}(ch3)
//
select {
a := <-ch {
// do something with `a`
@@ -3478,7 +3432,7 @@ fn main() {
The timeout branch is optional. If it is absent `select` waits for an unlimited amount of time.
It is also possible to proceed immediately if no channel is ready in the moment `select` is called
by adding an `else { ... }` branch. `else` and `> timeout` are mutually exclusive.
by adding an `else { ... }` branch. `else` and `<timeout>` are mutually exclusive.
The `select` command can be used as an *expression* of type `bool`
that becomes `false` if all channels are closed:
@@ -3535,7 +3489,7 @@ using `rlock` for read-only and `lock` for read/write access.
```v
struct St {
mut:
x int // data to shared
x int // data to be shared
}
fn (shared b St) g() {
@@ -3639,9 +3593,9 @@ fn main() {
```
```v failcompile
// hello_test.v
module main
// hello_test.v
fn test_hello() {
assert hello() == 'Hello world'
}
@@ -3667,7 +3621,7 @@ just like `hello.v`, i.e. both are part of the same module. Note also that
since `module main` is a regular module like the others, internal tests can
be used to test private functions in your main program .v files too.
You can also define special test functions in a test file:
You can also define these special test functions in a test file:
* `testsuite_begin` which will be run *before* all other test functions.
* `testsuite_end` which will be run *after* all other test functions.
@@ -3692,7 +3646,7 @@ option to see more details about the individual tests run.
You can put additional test data, including .v source files in a folder, named
`testdata`, right next to your _test.v files. V's test framework will *ignore*
such folders, while scanning for tests to run. This is usefull, if you want to
such folders, while scanning for tests to run. This is useful, if you want to
put .v files with invalid V source code, or other tests, including known
failing ones, that should be run in a specific way/options by a parent _test.v
file.
@@ -4056,8 +4010,9 @@ V's ORM provides a number of benefits:
```v
import sqlite
// sets a custom table name. Default is struct name (case-sensitive)
[table: 'customers']
struct Customer {
// struct name has to be the same as the table name (for now)
id int [primary; sql: serial] // a field named `id` of integer type must be the first field
name string [nonull]
nr_orders int
@@ -4077,7 +4032,7 @@ sql db {
create table Customer
}
// select count(*) from Customer
// select count(*) from customers
nr_customers := sql db {
select count from Customer
}
@@ -4146,7 +4101,7 @@ Comments spanning multiple lines are merged together using spaces, unless
- the line is empty
- the line ends with a `.` (end of sentence)
- the line is contains purely of at least 3 of `-`, `=`, `_`, `*`, `~` (horizontal rule)
- the line is purely of at least 3 of `-`, `=`, `_`, `*`, `~` (horizontal rule)
- the line starts with at least one `#` followed by a space (header)
- the line starts and ends with a `|` (table)
- the line starts with `- ` (list)
@@ -4167,6 +4122,19 @@ A vfmt run is usually pretty cheap (takes <30ms).
Always run `v fmt -w file.v` before pushing your code.
### v shader
You can use GPU shaders with V graphical apps. You write your shaders in an
[annotated GLSL dialect](https://github.com/vlang/v/blob/1d8ece7/examples/sokol/02_cubes_glsl/cube_glsl.glsl)
and use `v shader` to compile them for all supported target platforms.
```shell
v shader /path/to/project/dir/or/file.v
```
Currently you need to [include a header and declare a glue function](https://github.com/vlang/v/blob/c14c324/examples/sokol/02_cubes_glsl/cube_glsl.v#L43-L46) before
using the shader in your code.
### Profiling
V has good support for profiling your programs: `v -profile profile.txt run file.v`
@@ -4192,6 +4160,153 @@ fn main() {
}
```
## Package management
```powershell
v [module option] [param]
```
###### module options:
```
install Install a module from VPM.
remove Remove a module that was installed from VPM.
search Search for a module from VPM.
update Update an installed module from VPM.
upgrade Upgrade all the outdated modules.
list List all installed modules.
outdated Show installed modules that need updates.
```
You can install modules already created by someone else with [VPM](https://vpm.vlang.io/):
```powershell
v install [module]
```
**Example:**
```powershell
v install ui
```
Modules can be installed directly from git or mercurial repositories.
```powershell
v install [--git|--hg] [url]
```
**Example:**
```powershell
v install --git https://github.com/vlang/markdown
```
Removing a module with v:
```powershell
v remove [module]
```
**Example:**
```powershell
v remove ui
```
Updating an installed module from [VPM](https://vpm.vlang.io/):
```powershell
v update [module]
```
**Example:**
```powershell
v update ui
```
Or you can update all your modules:
```powershell
v update
```
To see all the modules you have installed, you can use:
```powershell
v list
```
**Example:**
```powershell
> v list
Installed modules:
markdown
ui
```
To see all the modules that need updates:
```powershell
v outdated
```
**Example:**
```powershell
> v outdated
Modules are up to date.
```
### Publish package
1. Put a `v.mod` file inside the toplevel folder of your module (if you
created your module with the command `v new mymodule` or `v init` you already have a v.mod file).
```sh
v new mymodule
Input your project description: My nice module.
Input your project version: (0.0.0) 0.0.1
Input your project license: (MIT)
Initialising ...
Complete!
```
Example `v.mod`:
```v ignore
Module {
name: 'mymodule'
description: 'My nice module.'
version: '0.0.1'
license: 'MIT'
dependencies: []
}
```
Minimal file structure:
```
v.mod
mymodule.v
```
The name of your module should be used with the `module` directive
at the top of all files in your module. For `mymodule.v`:
```v
module mymodule
pub fn hello_world() {
println('Hello World!')
}
```
2. Create a git repository in the folder with the `v.mod` file
(this is not required if you used `v new` or `v init`):
```sh
git init
git add .
git commit -m "INIT"
````
3. Create a public repository on github.com.
4. Connect your local repository to the remote repository and push the changes.
5. Add your module to the public V module registry VPM:
https://vpm.vlang.io/new
You will have to login with your Github account to register the module.
**Warning:** _Currently it is not possible to edit your entry after submitting.
Check your module name and github url twice as this cannot be changed by you later._
6. The final module name is a combination of your github account and
the module name you provided e.g. `mygithubname.mymodule`.
**Optional:** tag your V module with `vlang` and `vlang-module` on github.com
to allow for a better search experience.
# Advanced Topics
## Dumping expressions at runtime
@@ -4591,7 +4706,7 @@ If no flags are passed it will add `--cflags` and `--libs`, both lines below do
The `.pc` files are looked up into a hardcoded list of default pkg-config paths, the user can add
extra paths by using the `PKG_CONFIG_PATH` environment variable. Multiple modules can be passed.
To check the existance of a pkg-config use `$pkgconfig('pkg')` as a compile time if condition to
To check the existence of a pkg-config use `$pkgconfig('pkg')` as a compile time "if" condition to
check if a pkg-config exists. If it exists the branch will be created. Use `$else` or `$else $if`
to handle other cases.
@@ -4768,7 +4883,7 @@ use `v help`, `v help build` and `v help build-c`.
1. compile your binary with debugging info `v -g hello.v`
2. debug with [lldb](https://lldb.llvm.org) or [GDB](https://www.gnu.org/software/gdb/) e.g. `lldb hello`
Troubleshooting (debugging) executables [created with V in GDB](https://github.com/vlang/v/wiki/Troubleshooting-(debugging)-executables-created-with-V-in-GDB)
[Troubleshooting (debugging) executables created with V in GDB](https://github.com/vlang/v/wiki/Troubleshooting-(debugging)-executables-created-with-V-in-GDB)
**Visual debugging Setup:**
* [Visual Studio Code](vscode.md)
@@ -4780,7 +4895,7 @@ native backend (flag: `-b native`).
### Javascript Backend
To debug the generated Javascript output you can active source maps:
To debug the generated Javascript output you can activate source maps:
`v -b js -sourcemap hello.v -o hello.js`
For all supported options check the latest help:
@@ -4841,7 +4956,7 @@ Full list of builtin options:
| `windows`, `linux`, `macos` | `gcc`, `tinyc` | `amd64`, `arm64` | `debug`, `prod`, `test` |
| `mac`, `darwin`, `ios`, | `clang`, `mingw` | `x64`, `x32` | `js`, `glibc`, `prealloc` |
| `android`,`mach`, `dragonfly` | `msvc` | `little_endian` | `no_bounds_checking`, `freestanding` |
| `gnu`, `hpux`, `haiku`, `qnx` | `cplusplus` | `big_endian` |
| `gnu`, `hpux`, `haiku`, `qnx` | `cplusplus` | `big_endian` | `no_segfault_handler`, `no_backtrace`, `no_main` |
| `solaris` | | | |
#### `$embed_file`
@@ -4858,15 +4973,26 @@ V can embed arbitrary files into the executable with the `$embed_file(<path>)`
compile time call. Paths can be absolute or relative to the source file.
When you do not use `-prod`, the file will not be embedded. Instead, it will
be loaded *the first time* your program calls `f.data()` at runtime, making
be loaded *the first time* your program calls `embedded_file.data()` at runtime, making
it easier to change in external editor programs, without needing to recompile
your executable.
When you compile with `-prod`, the file *will be embedded inside* your
executable, increasing your binary size, but making it more self contained
and thus easier to distribute. In this case, `f.data()` will cause *no IO*,
and thus easier to distribute. In this case, `embedded_file.data()` will cause *no IO*,
and it will always return the same data.
`$embed_file` supports compression of the embedded file when compiling with `-prod`.
Currently only one compression type is supported: `zlib`
```v ignore
import os
fn main() {
embedded_file := $embed_file('v.png', .zlib) // compressed using zlib
os.write_file('exported.png', embedded_file.to_string()) ?
}
```
#### `$tmpl` for embedding and parsing V template files
V has a simple template language for text and html templates, and they can easily
@@ -5040,7 +5166,7 @@ but may impact the size of your executable.
`[direct_array_access]` - in functions tagged with `[direct_array_access]`
the compiler will translate array operations directly into C array operations -
omiting bounds checking. This may save a lot of time in a function that iterates
omitting bounds checking. This may save a lot of time in a function that iterates
over an array but at the cost of making the function unsafe - unless
the boundaries will be checked by the user.
@@ -5059,39 +5185,27 @@ the boolean expression is highly improbable. In the JS backend, that does nothin
Having built-in JSON support is nice, but V also allows you to create efficient
serializers for any data format. V has compile-time `if` and `for` constructs:
```v wip
// TODO: not fully implemented
```v
struct User {
name string
age int
name string
age int
}
// Note: T should be passed a struct name only
fn decode<T>(data string) T {
mut result := T{}
// compile-time `for` loop
// T.fields gives an array of a field metadata type
$for field in T.fields {
$if field.typ is string {
// $(string_expr) produces an identifier
result.$(field.name) = get_string(data, field.name)
} $else $if field.typ is int {
result.$(field.name) = get_int(data, field.name)
}
}
return result
fn main() {
$for field in User.fields {
$if field.typ is string {
println('$field.name is of type string')
}
}
}
// `decode<User>` generates:
fn decode_User(data string) User {
mut result := User{}
result.name = get_string(data, 'name')
result.age = get_int(data, 'age')
return result
}
// Output:
// name is of type string
```
See [`examples/compiletime/reflection.v`](/examples/compiletime/reflection.v)
for a more complete example.
## Limited operator overloading
```v
@@ -5132,14 +5246,14 @@ operator overloading is an important feature to have in order to improve readabi
To improve safety and maintainability, operator overloading is limited:
- It's only possible to overload `+, -, *, /, %, <, >, ==, !=, <=, >=` operators.
- `==` and `!=` are self generated by the compiler but can be overriden.
- `==` and `!=` are self generated by the compiler but can be overridden.
- Calling other functions inside operator functions is not allowed.
- Operator functions can't modify their arguments.
- When using `<` and `==` operators, the return type must be `bool`.
- `!=`, `>`, `<=` and `>=` are auto generated when `==` and `<` are defined.
- Both arguments must have the same type (just like with all operators in V).
- Assignment operators (`*=`, `+=`, `/=`, etc)
are auto generated when the operators are defined though they must return the same type.
are auto generated when the corresponding operators are defined and operands are of the same type.
## Inline assembly
<!-- ignore because it doesn't pass fmt test (why?) -->
@@ -5202,7 +5316,7 @@ This will generate a directory `libsodium` with a V module.
Example of a C2V generated libsodium wrapper:
https://github.com/medvednikov/libsodium
https://github.com/vlang/libsodium
<br>
@@ -5344,14 +5458,23 @@ enum BitField {
other
}
fn example_enum_as_bitfield_use() {
fn main() {
assert 1 == int(BitField.read)
assert 2 == int(BitField.write)
mut bf := BitField.read
assert bf.has(.read | .other) // test if *at least one* of the flags is set
assert !bf.all(.read | .other) // test if *all* of the flags is set
bf.set(.write | .other)
assert bf.has(.read | .write | .other)
assert bf.all(.read | .write | .other)
bf.toggle(.other)
assert bf == BitField.read | .write
assert bf.all(.read | .write)
assert !bf.has(.other)
}
```
```v
// Calling this function will result in a deprecation warning
[deprecated]
fn old_function() {
@@ -5372,7 +5495,9 @@ fn legacy_function() {}
[deprecated: 'use new_function2() instead']
[deprecated_after: '2021-05-27']
fn legacy_function2() {}
```
```v nofmt
// This function's calls will be inlined.
[inline]
fn inlined_function() {
@@ -5418,7 +5543,7 @@ fn C.my_external_function(voidptr, int, voidptr) int
// Calls to following function must be in unsafe{} blocks.
// Note that the code in the body of `risky_business()` will still be
// checked, unless you also wrap it in `unsafe {}` blocks.
// This is usefull, when you want to have an `[unsafe]` function that
// This is useful, when you want to have an `[unsafe]` function that
// has checks before/after a certain unsafe operation, that will still
// benefit from V's safety features.
[unsafe]
@@ -5453,7 +5578,7 @@ fn C.DefWindowProc(hwnd int, msg int, lparam int, wparam int)
// Windows only:
// If a default graphics library is imported (ex. gg, ui), then the graphical window takes
// priority and no console window is created, effectively disabling println() statements.
// Use to explicity create console window. Valid before main() only.
// Use to explicitly create console window. Valid before main() only.
[console]
fn main() {
}
@@ -5530,6 +5655,7 @@ type
typeof
union
unsafe
volatile
__offsetof
```
See also [V Types](#v-types).
@@ -5557,10 +5683,11 @@ This lists operators for [primitive types](#primitive-types) only.
<< left shift integer << unsigned integer
>> right shift integer >> unsigned integer
>>> unsigned right shift integer >> unsigned integer
Precedence Operator
5 * / % << >> &
5 * / % << >> >>> &
4 + - | ^
3 == != < <= > >=
2 &&
@@ -5570,5 +5697,5 @@ Precedence Operator
Assignment Operators
+= -= *= /= %=
&= |= ^=
>>= <<=
>>= <<= >>>=
```

View File

@@ -19,19 +19,19 @@ provides V language support for Visual Studio Code.
* Linter (Workspace files only).
[more](https://marketplace.visualstudio.com/items?itemName=vlanguage.vscode-vlang)
**Hint:** This extention will not add the V compiler! Information on how to
**Hint:** This extension will not add the V compiler! Information on how to
[install V compiler](https://github.com/vlang/v/blob/master/doc/docs.md#install-from-source)
on your operating system.
### Setup Extention
### Setup Extension
Install [V VS Code Extention](https://marketplace.visualstudio.com/items?itemName=vlanguage.vscode-vlang).
Install [V VS Code Extension](https://marketplace.visualstudio.com/items?itemName=vlanguage.vscode-vlang).
## Visual Debugging
![screenshot visual debugger](https://github.com/vlang/v/blob/master/doc/img/vscode-debugger.png?raw=true)
The [C/C++ Extention](https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools)
The [C/C++ Extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools)
for Visual Studio Code provides visual conditional debugging.
**Features:**
@@ -47,13 +47,16 @@ edit the variable.
### Setup Debugging
1. Install the [C/C++ Extention](https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools)
#### Step1: Configure the launch.json file
1. Install the [C/C++ Extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools)
2. Open `RUN AND DEBUG` panel (Debug Icon in left panel).
3. Click on `Show` all automatic debug configurations.
4. Select `Add config`.
5. Select environment `C++ (GDB/LLDB)`.
6. Change the line `"program": "Enter the program name, e.g. \"${workspaceFolder}/a.out\"",`
to point to your compiled application e.g. `"program": "${workspaceFolder}/hello",`.
to point to your compiled application e.g. `"program": "${workspaceFolder}/hello",`
or a more flexible one `"program": "${fileDirname}/${fileBasenameNoExtension}",`
when you want to debug the current opened file.
This will add a block to your `.workspace` file,
or create the file `.vscode/launch.json`:
@@ -62,7 +65,7 @@ or create the file `.vscode/launch.json`:
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit:
// https://go.microsoft.com/fwlink/?linkid=830387
// https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
@@ -75,7 +78,8 @@ or create the file `.vscode/launch.json`:
"cwd": "${fileDirname}",
"environment": [],
"externalConsole": false,
"MIMode": "lldb"
"MIMode": "lldb",
"preLaunchTask": "build"
}
]
}
@@ -84,24 +88,55 @@ or create the file `.vscode/launch.json`:
**Optional:** use `"program": "${fileDirname}/${fileBasenameNoExtension}"` to debug
any current open source file with an existing binary with the same name but without any extension.
#### Step2: Configure the tasks.json file
Generally, you can manually compile the application with: `v -b c -g hello.v -o hello`,
or for short: `v -g hello.v`, and then call the debugger.
The `-g` option will add the needed debugging information.
You can find more debugging options in the [docs](docs.md#debugging).
VS Code provides a hook called `preLaunchTask`, which can be used to compile
the application automatially every time you call the debugger.
[preLaunchTask](https://code.visualstudio.com/docs/editor/debugging#_launchjson-attributes) launches
a task before the start of a debug session, set this attribute to the label of a task specified
in [task.json](https://code.visualstudio.com/docs/editor/tasks) (in the workspace's .vscode folder).
Or, this can be set to `${defaultBuildTask}`, to use your default build task.
As explained, the `"preLaunchTask": "build"` needs to work with a `.vscode/tasks.json`
with a label named `build`.
```json
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
"tasks": [
{
"label": "build",
"type": "shell",
"command": "v",
"args": [
"-g", // add more compiler options here if necessary
"${relativeFile}" // or modify it according to your requirements
],
"group": "build",
"presentation": {
"reveal": "silent"
},
"problemMatcher": "$gcc"
}
]
}
```
### Usage
To allow your compiled application to be debugged.
The application needs to include additional debugging information
([DWARF](https://en.wikipedia.org/wiki/DWARF)).
**1. Compile with debugging information:**
`v -b c -g hello.v -o hello` or short `v -g hello.v`
The `-g` option will add the needed debugging informations.
More Options are explained in the [docs](docs.md#debugging).
**2. Start Debugging**
1. Open your source code and set the required break points
2. Click on the Debug Icon in the left Icon panel and click
`> (lldb) Start`, or use `F5` to launch your application in debug mode.
For all options look at the official
[C/C++ Extention documentation](https://code.visualstudio.com/docs/cpp/cpp-debug).
[C/C++ Extension documentation](https://code.visualstudio.com/docs/cpp/cpp-debug).

3
examples/.gitignore vendored
View File

@@ -1,2 +1,3 @@
*.js
*.log
*.ppm
*.js

View File

@@ -788,7 +788,7 @@ fn (mut app App) on_key_down(key gg.KeyCode) {
// these keys are independent from the game state:
match key {
.a { app.is_ai_mode = !app.is_ai_mode }
.escape { exit(0) }
.escape { app.gg.quit() }
.n, .r { app.new_game() }
.backspace { app.undo() }
.enter { app.next_tile_format() }
@@ -910,7 +910,7 @@ fn (mut app App) showfps() {
fn main() {
mut app := &App{}
app.new_game()
mut font_path := os.resource_abs_path(os.join_path('../assets/fonts/', 'RobotoMono-Regular.ttf'))
mut font_path := os.resource_abs_path(os.join_path('..', 'assets', 'fonts', 'RobotoMono-Regular.ttf'))
$if android {
font_path = 'fonts/RobotoMono-Regular.ttf'
}

View File

Before

Width:  |  Height:  |  Size: 4.2 KiB

After

Width:  |  Height:  |  Size: 4.2 KiB

View File

@@ -1,42 +1,41 @@
// Binary Search Tree example by @SleepyRoy
// TODO: make Node.value generic once it's robust enough
struct Empty {}
struct Node {
value f64
left Tree
right Tree
struct Node<T> {
value T
left Tree<T>
right Tree<T>
}
type Tree = Empty | Node
type Tree<T> = Empty | Node<T>
// return size(number of nodes) of BST
fn size(tree Tree) int {
fn (tree Tree<T>) size<T>() int {
return match tree {
Empty { 0 }
Node { 1 + size(tree.left) + size(tree.right) }
Node<T> { 1 + tree.left.size() + tree.right.size() }
}
}
// insert a value to BST
fn insert(tree Tree, x f64) Tree {
fn (tree Tree<T>) insert<T>(x T) Tree<T> {
return match tree {
Empty {
Node{x, tree, tree}
Node<T>{x, tree, tree}
}
Node {
Node<T> {
if x == tree.value {
tree
} else if x < tree.value {
Node{
Node<T>{
...tree
left: insert(tree.left, x)
left: tree.left.insert(x)
}
} else {
Node{
Node<T>{
...tree
right: insert(tree.right, x)
right: tree.right.insert(x)
}
}
}
@@ -44,80 +43,80 @@ fn insert(tree Tree, x f64) Tree {
}
// whether able to find a value in BST
fn search(tree Tree, x f64) bool {
fn (tree Tree<T>) search<T>(x T) bool {
return match tree {
Empty {
false
}
Node {
Node<T> {
if x == tree.value {
true
} else if x < tree.value {
search(tree.left, x)
tree.left.search(x)
} else {
search(tree.right, x)
tree.right.search(x)
}
}
}
}
// find the minimal value of a BST
fn min(tree Tree) f64 {
fn (tree Tree<T>) min<T>() T {
return match tree {
Empty {
1e100
T(1e9)
}
Node {
if tree.value < min(tree.left) {
Node<T> {
if tree.value < tree.left.min() {
tree.value
} else {
min(tree.left)
tree.left.min()
}
}
}
}
// delete a value in BST (if nonexistant do nothing)
fn delete(tree Tree, x f64) Tree {
fn (tree Tree<T>) delete<T>(x T) Tree<T> {
return match tree {
Empty {
tree
}
Node {
if tree.left is Node && tree.right is Node {
Node<T> {
if tree.left !is Empty && tree.right !is Empty {
if x < tree.value {
Node{
Node<T>{
...tree
left: delete(tree.left, x)
left: tree.left.delete(x)
}
} else if x > tree.value {
Node{
Node<T>{
...tree
right: delete(tree.right, x)
right: tree.right.delete(x)
}
} else {
Node{
Node<T>{
...tree
value: min(tree.right)
right: delete(tree.right, min(tree.right))
value: tree.right.min()
right: tree.right.delete(tree.right.min())
}
}
} else if tree.left is Node {
} else if tree.left !is Empty {
if x == tree.value {
tree.left
} else {
Node{
Node<T>{
...tree
left: delete(tree.left, x)
left: tree.left.delete(x)
}
}
} else {
if x == tree.value {
tree.right
} else {
Node{
Node<T>{
...tree
right: delete(tree.right, x)
right: tree.right.delete(x)
}
}
}
@@ -126,46 +125,22 @@ fn delete(tree Tree, x f64) Tree {
}
fn main() {
$if !freestanding {
mut tree := Tree(Empty{})
input := [0.3, 0.2, 0.5, 0.0, 0.6, 0.8, 0.9, 1.0, 0.1, 0.4, 0.7]
for i in input {
tree = insert(tree, i)
}
println('[1] after insertion tree size is ${size(tree)}') // 11
del := [-0.3, 0.0, 0.3, 0.6, 1.0, 1.5]
for i in del {
tree = delete(tree, i)
}
print('[2] after deletion tree size is ${size(tree)}, ') // 7
print('and these elements were deleted: ') // 0.0 0.3 0.6 1.0
for i in input {
if !search(tree, i) {
print('$i ')
}
}
println('')
} $else {
mut tree := Tree(Empty{})
input := [0.3, 0.2, 0.5, 0.0, 0.6, 0.8, 0.9, 1.0, 0.1, 0.4, 0.7]
for i in input {
tree = insert(tree, i)
}
print('[1] after insertion tree size is ') // 11
println(size(tree))
del := [-0.3, 0.0, 0.3, 0.6, 1.0, 1.5]
for i in del {
tree = delete(tree, i)
}
print('[2] after deletion tree size is ') // 7
print(size(tree))
print(', and these elements were deleted: ') // 0.0 0.3 0.6 1.0
for i in input {
if !search(tree, i) {
print(i)
print(' ')
}
}
println('')
mut tree := Tree<f64>(Empty{})
vals := [0.2, 0.0, 0.5, 0.3, 0.6, 0.8, 0.9, 1.0, 0.1, 0.4, 0.7]
for i in vals {
tree = tree.insert(i)
}
println('[1] after insertion tree size is $tree.size()') // 11
del_vals := [-0.3, 0.0, 0.3, 0.6, 1.0, 1.5]
for i in del_vals {
tree = tree.delete(i)
}
print('[2] after deletion tree size is $tree.size(), ') // 7
print('and these elements were deleted: ') // 0.0 0.3 0.6 1.0
for i in vals {
if !tree.search(i) {
print('$i ')
}
}
println('')
}

View File

@@ -88,11 +88,12 @@ fn on_frame(mut app App) {
}
// Rotate a polygon round the centerpoint
[manualfree]
fn draw_convex_poly_rotate(mut ctx gg.Context, dpi_scale f32, points []f32, c gx.Color, angle f32) {
sa := math.sin(math.pi * angle / 180.0)
ca := math.cos(math.pi * angle / 180.0)
mut rotated_points := []f32{}
mut rotated_points := []f32{cap: points.len}
for i := 0; i < points.len / 2; i++ {
x := points[2 * i]
y := points[2 * i + 1]
@@ -102,6 +103,7 @@ fn draw_convex_poly_rotate(mut ctx gg.Context, dpi_scale f32, points []f32, c gx
rotated_points << (yn + center) * dpi_scale
}
ctx.draw_convex_poly(rotated_points, c)
unsafe { rotated_points.free() }
}
fn (mut app App) resize() {
@@ -133,7 +135,7 @@ fn on_event(e &gg.Event, mut app App) {
.q {
println('Good bye.')
// do we need to free anything here?
exit(0)
app.gg.quit()
}
else {}
}
@@ -142,11 +144,15 @@ fn on_event(e &gg.Event, mut app App) {
}
}
fn on_init(mut app App) {
app.resize()
}
// is needed for easier diagnostics on windows
[console]
fn main() {
println("Press 'q' to quit.")
mut font_path := os.resource_abs_path(os.join_path('../assets/fonts/', 'RobotoMono-Regular.ttf'))
mut font_path := os.resource_abs_path(os.join_path('..', 'assets', 'fonts', 'RobotoMono-Regular.ttf'))
$if android {
font_path = 'fonts/RobotoMono-Regular.ttf'
}
@@ -161,6 +167,7 @@ fn main() {
user_data: app
frame_fn: on_frame
event_fn: on_event
init_fn: on_init
font_path: font_path
)

View File

@@ -0,0 +1,49 @@
// An example deserializer implementation
struct User {
name string
age int
}
fn main() {
data := 'name=Alice\nage=18'
user := decode<User>(data)
println(user)
}
fn decode<T>(data string) T {
mut result := T{}
// compile-time `for` loop
// T.fields gives an array of a field metadata type
$for field in T.fields {
$if field.typ is string {
// $(string_expr) produces an identifier
result.$(field.name) = get_string(data, field.name)
} $else $if field.typ is int {
result.$(field.name) = get_int(data, field.name)
}
}
return result
}
fn get_string(data string, field_name string) string {
for line in data.split_into_lines() {
key_val := line.split('=')
if key_val[0] == field_name {
return key_val[1]
}
}
return ''
}
fn get_int(data string, field string) int {
return get_string(data, field).int()
}
// `decode<User>` generates:
// fn decode_User(data string) User {
// mut result := User{}
// result.name = get_string(data, 'name')
// result.age = get_int(data, 'age')
// return result
// }

View File

@@ -12,7 +12,7 @@ struct Module {
struct User {
id int [primary; sql: serial]
age int [unique: 'user']
age u32 [unique: 'user']
name string [sql: 'username'; unique]
is_customer bool [sql: 'abc'; unique: 'user']
skipped_string string [skip]

View File

@@ -1,18 +1,17 @@
// This program displays the fibonacci sequence
// import os
import os
fn main() {
// Check for user input
// if os.args.len != 2 {
// println('usage: fibonacci [rank]')
if os.args.len != 2 {
println('usage: fibonacci [rank]')
// Exit
// return
// }
return
}
// Parse first argument and cast it to int
// stop := os.args[1].int()
stop := 23
stop := os.args[1].int()
// Can only calculate correctly until rank 92
if stop > 92 {
println('rank must be 92 or less')
@@ -20,9 +19,9 @@ fn main() {
}
// Three consecutive terms of the sequence
mut a := 0
mut b := 0
mut c := 1
mut a := i64(0)
mut b := i64(0)
mut c := i64(1)
println(a + c + c)
for _ in 0 .. stop {
// Set a and b to the next term

View File

@@ -96,7 +96,7 @@ fn (mut app App) resize() {
// is needed for easier diagnostics on windows
[console]
fn main() {
mut font_path := os.resource_abs_path(os.join_path('../assets/fonts/', 'RobotoMono-Regular.ttf'))
mut font_path := os.resource_abs_path(os.join_path('..', 'assets', 'fonts', 'RobotoMono-Regular.ttf'))
$if android {
font_path = 'fonts/RobotoMono-Regular.ttf'
}

View File

@@ -177,7 +177,7 @@ fn main() {
mut app := &App{
gg: 0
}
mut font_path := os.resource_abs_path(os.join_path('../assets/fonts/', 'RobotoMono-Regular.ttf'))
mut font_path := os.resource_abs_path(os.join_path('..', 'assets', 'fonts', 'RobotoMono-Regular.ttf'))
$if android {
font_path = 'fonts/RobotoMono-Regular.ttf'
}
@@ -274,7 +274,7 @@ fn (mut app App) key_down(key gg.KeyCode) {
// global keys
match key {
.escape {
exit(0)
app.gg.quit()
}
._0 {
app.timer_period_ms = 0

View File

@@ -1,25 +1,85 @@
module main
import term
import rand
import time
import automaton
fn print_automaton(a &automaton.Automaton) {
for y := 1; y < a.field.maxy; y++ {
mut s := ' '
for x := 1; x < a.field.maxx; x++ {
cell := a.field.get(x, y)
s += if cell == 1 { '@' } else { '.' }
}
println(s)
const (
cell = ''
nothing = ' '
switches = {
cell: nothing
nothing: cell
}
println('')
transformers = [nothing, cell]
)
struct Game {
mut:
grid [][]string
}
fn (g Game) get_surrounding_alive_count(x int, y int) int {
mut count := 0
for i := x - 1; i <= x + 1; i++ {
for j := y - 1; j <= y + 1; j++ {
if (i != x || j != y) && i >= 0 && j >= 0 && i < g.grid.len && j < g.grid[x].len {
if g.grid[i][j] == cell {
count++
}
}
}
}
return count
}
fn (mut g Game) evolve() {
mut temp_grid := [][]string{}
for x in 0 .. g.grid.len {
temp_grid << []string{}
for y in 0 .. g.grid[x].len {
count := g.get_surrounding_alive_count(x, y)
if count == 3 || ((g.grid[x][y] == cell) && count == 2) {
temp_grid[x] << cell
} else {
temp_grid[x] << nothing
}
}
}
g.grid = temp_grid
}
fn (mut g Game) display() {
for y in 0 .. g.grid[0].len {
mut line := ''
for x in 0 .. g.grid.len {
line += g.grid[x][y]
}
println(line)
}
}
fn new_game() Game {
w, h := term.get_terminal_size()
mut grid := [][]string{}
for x in 0 .. w {
grid << []string{}
for _ in 0 .. h {
is_live := rand.f64() > 0.82
icon := transformers[int(is_live)]
grid[x] << icon
}
}
return Game{grid}
}
fn main() {
mut a := automaton.gun()
mut g := new_game()
g.display()
for {
a.update()
print_automaton(a)
g.evolve()
term.erase_clear()
g.display()
time.sleep(100 * time.millisecond)
}
}

View File

@@ -23,7 +23,6 @@ pub fn (a &A2D) set(x int, y int, newval int) {
mut e := &int(0)
e = a.data + y * a.maxx + x
*e = newval
_ = e // TODO compiler bug, this is not necessary
}
}

View File

@@ -18,7 +18,7 @@ mut:
}
fn main() {
mut font_path := os.resource_abs_path(os.join_path('../assets/fonts/', 'RobotoMono-Regular.ttf'))
mut font_path := os.resource_abs_path(os.join_path('..', 'assets', 'fonts', 'RobotoMono-Regular.ttf'))
mut app := &App{
gg: 0
}

View File

@@ -3,32 +3,22 @@ module main
import gg
import gx
struct App {
mut:
gg &gg.Context
}
fn main() {
mut app := &App{
gg: 0
}
app.gg = gg.new_context(
mut context := gg.new_context(
bg_color: gx.rgb(174, 198, 255)
width: 600
height: 400
window_title: 'Polygons'
frame_fn: frame
user_data: app
)
app.gg.run()
context.run()
}
fn frame(mut app App) {
app.gg.begin()
app.gg.draw_convex_poly([f32(100.0), 100.0, 200.0, 100.0, 300.0, 200.0, 200.0, 300.0, 100.0,
300.0,
], gx.blue)
app.gg.draw_empty_poly([f32(50.0), 50.0, 70.0, 60.0, 90.0, 80.0, 70.0, 110.0], gx.black)
app.gg.draw_triangle(450, 142, 530, 280, 370, 280, gx.red)
app.gg.end()
fn frame(mut ctx gg.Context) {
ctx.begin()
ctx.draw_convex_poly([f32(100.0), 100.0, 200.0, 100.0, 300.0, 200.0, 200.0, 300.0, 100.0, 300.0],
gx.blue)
ctx.draw_empty_poly([f32(50.0), 50.0, 70.0, 60.0, 90.0, 80.0, 70.0, 110.0], gx.black)
ctx.draw_triangle(450, 142, 530, 280, 370, 280, gx.red)
ctx.end()
}

View File

@@ -75,7 +75,7 @@ fn main() {
width: win_width
height: win_height
create_window: true
window_title: 'Empty window'
window_title: 'Raven text'
user_data: app
bg_color: bg_color
frame_fn: frame

View File

@@ -29,7 +29,8 @@ fn main() {
user_data: app
init_fn: init_images
)
app.image = app.gg.create_image(os.resource_abs_path('logo.png'))
mut logo_path := os.resource_abs_path(os.join_path('..', 'assets', 'logo.png'))
app.image = app.gg.create_image(logo_path)
app.gg.run()
}

View File

@@ -5,12 +5,28 @@ import gx
struct App {
mut:
gg &gg.Context
gg &gg.Context
pixels []f32
}
fn main() {
mut pixels := []f32{}
density := 4
for x in 30 .. 60 {
if x % density == 0 {
continue
}
for y in 30 .. 60 {
if y % density == 0 {
continue
}
pixels << f32(x + density)
pixels << f32(y + density)
}
}
mut app := &App{
gg: 0
pixels: pixels
}
app.gg = gg.new_context(
bg_color: gx.rgb(174, 198, 255)
@@ -24,16 +40,13 @@ fn main() {
}
fn frame(mut app App) {
mut pixels := []f32{}
for x in 30 .. 60 {
for y in 30 .. 60 {
pixels << f32(x)
pixels << f32(y)
}
}
app.gg.begin()
app.gg.set_pixels(pixels, gx.red)
// Set a blue pixel near each corner. (Find your magnifying glass)
app.gg.set_pixel(2, 2, gx.blue)
app.gg.set_pixel(app.gg.width - 2, 2, gx.blue)
app.gg.set_pixel(app.gg.width - 2, app.gg.height - 2, gx.blue)
app.gg.set_pixel(2, app.gg.height - 2, gx.blue)
// Set pixels in a grid-like pattern.
app.gg.set_pixels(app.pixels, gx.red)
app.gg.end()
}

View File

@@ -81,7 +81,8 @@ fn main() {
}
fn init_images(mut app App) {
app.image = app.gg.create_image(os.resource_abs_path('logo.png'))
mut logo_path := os.resource_abs_path(os.join_path('..', 'assets', 'logo.png'))
app.image = app.gg.create_image(logo_path)
}
fn frame(mut app App) {

View File

@@ -0,0 +1,7 @@
Interactive 3D cube using DOM & WebGL API.
# Compiling
```
v -b js_browser examples/js_dom_cube/cube.js.v
```
Then you can open `index.html` with your favourite browser.

View File

@@ -0,0 +1,452 @@
import js.dom
import math
const (
vert_code = 'attribute vec3 position;uniform mat4 Pmatrix;uniform mat4 Vmatrix;uniform mat4 Mmatrix;attribute vec3 color;varying vec3 vColor;void main(void) {gl_Position = Pmatrix * Vmatrix * Mmatrix * vec4(position,1.);vColor = color;}
'
frag_code = 'precision mediump float;varying vec3 vColor;void main(void) {gl_FragColor = vec4(vColor, 1.);}
'
vertices = [
f32(-1),
-1,
-1,
1,
-1,
-1,
1,
1,
-1,
-1,
1,
-1,
-1,
-1,
1,
1,
-1,
1,
1,
1,
1,
-1,
1,
1,
-1,
-1,
-1,
-1,
1,
-1,
-1,
1,
1,
-1,
-1,
1,
1,
-1,
-1,
1,
1,
-1,
1,
1,
1,
1,
-1,
1,
-1,
-1,
-1,
-1,
-1,
1,
1,
-1,
1,
1,
-1,
-1,
-1,
1,
-1,
-1,
1,
1,
1,
1,
1,
1,
1,
-1,
]
colors = [
f32(5),
3,
7,
5,
3,
7,
5,
3,
7,
5,
3,
7,
1,
1,
3,
1,
1,
3,
1,
1,
3,
1,
1,
3,
0,
0,
1,
0,
0,
1,
0,
0,
1,
0,
0,
1,
1,
0,
0,
1,
0,
0,
1,
0,
0,
1,
0,
0,
1,
1,
0,
1,
1,
0,
1,
1,
0,
1,
1,
0,
0,
1,
0,
0,
1,
0,
0,
1,
0,
0,
1,
0,
]
indices = [
u16(0),
1,
2,
0,
2,
3,
4,
5,
6,
4,
6,
7,
8,
9,
10,
8,
10,
11,
12,
13,
14,
12,
14,
15,
16,
17,
18,
16,
18,
19,
20,
21,
22,
20,
22,
23,
]
amortization = 0.95
)
fn get_webgl() (&JS.HTMLCanvasElement, JS.WebGLRenderingContext) {
JS.console.log(dom.document)
elem := dom.document.getElementById('myCanvas'.str) or { panic('cannot get canvas') }
match elem {
JS.HTMLCanvasElement {
webgl := elem.getContext('experimental-webgl'.str, js_undefined()) or {
panic('context not found')
}
match webgl {
JS.WebGLRenderingContext {
return elem, webgl
}
else {
panic('cannot get webgl')
}
}
}
else {
panic('not an canvas')
}
}
}
fn get_projection(angle f64, a f64, z_min f64, z_max f64) []f64 {
ang := math.tan((angle * 0.5) * math.pi / 180)
return [
0.5 / ang,
0,
0,
0,
0,
0.5 * a / ang,
0,
0,
0,
0,
-(z_max + z_min) / (z_max - z_min),
-1,
0,
0,
(-2 * z_max * z_min) / (z_max - z_min),
0,
]
}
fn JS.Math.cos(JS.Number) JS.Number
fn JS.Math.sin(JS.Number) JS.Number
fn rotate_x(mut m []f64, angle f64) {
c := math.cos(angle)
s := math.sin(angle)
mv1 := m[1]
mv5 := m[5]
mv9 := m[9]
m[1] = m[1] * c - m[2] * s
m[5] = m[5] * c - m[6] * s
m[9] = m[9] * c - m[10] * s
m[2] = m[2] * c + mv1 * s
m[6] = m[6] * c + mv5 * s
m[10] = m[10] * c + mv9 * s
}
fn rotate_y(mut m []f64, angle f64) {
c := math.cos(angle)
s := math.sin(angle)
mv0 := m[0]
mv4 := m[4]
mv8 := m[8]
m[0] = c * m[0] + s * m[2]
m[4] = c * m[4] + s * m[6]
m[8] = c * m[8] + s * m[10]
m[2] = c * m[2] - s * mv0
m[6] = c * m[6] - s * mv4
m[10] = c * m[10] - s * mv8
}
struct State {
mut:
drag bool
gl JS.WebGLRenderingContext
canvas JS.HTMLCanvasElement
old_x f64
old_y f64
dx f64
dy f64
theta f64
phi f64
time_old f64
mo_matrix []f64
view_matrix []f64
proj_matrix []f64
pmatrix JS.WebGLUniformLocation
vmatrix JS.WebGLUniformLocation
mmatrix JS.WebGLUniformLocation
index_buffer JS.WebGLBuffer
}
fn animate(mut state State, time f64) {
if !state.drag {
state.dx = state.dx * amortization
state.dy = state.dy * amortization
state.theta += state.dx
state.phi += state.dy
}
state.mo_matrix[0] = 1
state.mo_matrix[1] = 0
state.mo_matrix[2] = 0
state.mo_matrix[3] = 0
state.mo_matrix[4] = 0
state.mo_matrix[5] = 1
state.mo_matrix[6] = 0
state.mo_matrix[7] = 0
state.mo_matrix[8] = 0
state.mo_matrix[9] = 0
state.mo_matrix[10] = 1
state.mo_matrix[11] = 0
state.mo_matrix[12] = 0
state.mo_matrix[13] = 0
state.mo_matrix[14] = 0
state.mo_matrix[15] = 1
// println('${state.theta} ${state.phi}')
rotate_x(mut state.mo_matrix, state.phi)
rotate_y(mut state.mo_matrix, state.theta)
state.time_old = time
state.gl.enable(dom.gl_depth_test())
state.gl.clearColor(0.5, 0.5, 0.5, 0.9)
state.gl.clearDepth(1.0)
state.gl.viewport(0.0, 0.0, state.canvas.width, state.canvas.height)
state.gl.clear(JS.Number(int(dom.gl_color_buffer_bit()) | int(dom.gl_depth_buffer_bit())))
state.gl.uniformMatrix4fv(state.pmatrix, JS.Boolean(false), state.proj_matrix.to_number_array())
state.gl.uniformMatrix4fv(state.vmatrix, JS.Boolean(false), state.view_matrix.to_number_array())
state.gl.uniformMatrix4fv(state.mmatrix, JS.Boolean(false), state.mo_matrix.to_number_array())
state.gl.bindBuffer(dom.gl_element_array_buffer(), state.index_buffer)
state.gl.drawElements(dom.gl_triangles(), indices.len, dom.gl_unsigned_short(), 0)
dom.window().requestAnimationFrame(fn [mut state] (time JS.Number) {
animate(mut state, f64(time))
})
}
fn main() {
canvas, gl := get_webgl()
vertex_buffer := gl.createBuffer() ?
gl.bindBuffer(dom.gl_array_buffer(), vertex_buffer)
gl.bufferData(dom.gl_array_buffer(), float32_array(vertices), dom.gl_static_draw())
color_buffer := gl.createBuffer() ?
gl.bindBuffer(dom.gl_array_buffer(), color_buffer)
gl.bufferData(dom.gl_array_buffer(), float32_array(colors), dom.gl_static_draw())
index_buffer := gl.createBuffer() ?
gl.bindBuffer(dom.gl_element_array_buffer(), index_buffer)
gl.bufferData(dom.gl_element_array_buffer(), uint16_array(indices), dom.gl_static_draw())
vert_shader := gl.createShader(dom.gl_vertex_shader()) ?
gl.shaderSource(vert_shader, vert_code.str)
gl.compileShader(vert_shader)
if !bool(JS.Boolean(gl.getShaderParameter(vert_shader, dom.gl_compile_status()))) {
panic('An error occurred when compiling vertex shader: ${string(gl.getShaderInfoLog(vert_shader))}')
}
frag_shader := gl.createShader(dom.gl_fragment_shader()) ?
gl.shaderSource(frag_shader, frag_code.str)
gl.compileShader(frag_shader)
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))}')
}
shader_program := gl.createProgram() ?
gl.attachShader(shader_program, vert_shader)
gl.attachShader(shader_program, frag_shader)
gl.linkProgram(shader_program)
if !bool(JS.Boolean(gl.getProgramParameter(shader_program, dom.gl_link_status()))) {
panic('unable to initialize the shader program: ${string(gl.getProgramInfoLog(shader_program))}')
}
pmatrix := gl.getUniformLocation(shader_program, 'Pmatrix'.str) ?
vmatrix := gl.getUniformLocation(shader_program, 'Vmatrix'.str) ?
mmatrix := gl.getUniformLocation(shader_program, 'Mmatrix'.str) ?
gl.bindBuffer(dom.gl_array_buffer(), vertex_buffer)
position := gl.getAttribLocation(shader_program, 'position'.str)
gl.vertexAttribPointer(position, JS.Number(3), dom.gl_float(), JS.Boolean(false),
JS.Number(0), JS.Number(0))
gl.enableVertexAttribArray(position)
gl.bindBuffer(dom.gl_array_buffer(), color_buffer)
color := gl.getAttribLocation(shader_program, 'color'.str)
gl.vertexAttribPointer(color, JS.Number(3), dom.gl_float(), JS.Boolean(false), JS.Number(0),
JS.Number(0))
gl.enableVertexAttribArray(color)
gl.useProgram(shader_program)
mut proj_matrix := get_projection(40.0, f64(canvas.width) / f64(canvas.height), 1.0,
100.0)
mut mo_matrix := [f64(1), 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]
mut view_matrix := [f64(1), 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]
view_matrix[14] = view_matrix[14] - 6
mut state := State{false, gl, canvas, 0, 0, 0, 0, 0, 0, 0, mo_matrix, view_matrix, proj_matrix, pmatrix, vmatrix, mmatrix, index_buffer}
canvas.addEventListener('mousedown'.str, fn [mut state] (e JS.Event) {
state.drag = true
match e {
JS.MouseEvent {
state.old_x = f64(e.pageX)
state.old_y = f64(e.pageY)
e.preventDefault()
}
else {}
}
}, JS.EventListenerOptions{})
canvas.addEventListener('mouseup'.str, fn [mut state] (e JS.Event) {
state.drag = false
}, JS.EventListenerOptions{})
canvas.addEventListener('mouseout'.str, fn [mut state] (e JS.Event) {
state.drag = false
}, JS.EventListenerOptions{})
canvas.addEventListener('mousemove'.str, fn [mut state] (e JS.Event) {
if !state.drag {
return
}
match e {
JS.MouseEvent {
state.dx = (f64(e.pageX) - state.old_x) * 2.0 * math.pi / f64(state.canvas.width)
state.dy = (f64(e.pageY) - state.old_y) * 2.0 * math.pi / f64(state.canvas.height)
state.theta += state.dx
state.phi += state.dy
state.old_x = f64(e.pageX)
state.old_y = f64(e.pageY)
e.preventDefault()
}
else {
panic('not a mouse event??')
}
}
}, JS.EventListenerOptions{})
animate(mut state, 0)
}

View File

@@ -0,0 +1,6 @@
<body>
<canvas width="570" height="570" id="myCanvas"></canvas>
<script src="cube.js">
</script>
</body>

View File

@@ -0,0 +1,7 @@
Drawing with mouse events using DOM API. Adopted from MDN examples.
# Compiling
```
v -b js_browser examples/js_dom_draw/draw.js.v
```
Then you can open `index.html` with your favourite browser.

View File

@@ -0,0 +1,90 @@
import js.dom
fn get_canvas(elem JS.HTMLElement) &JS.HTMLCanvasElement {
match elem {
JS.HTMLCanvasElement {
return elem
}
else {
panic('Not a canvas')
}
}
}
fn draw_line(mut context JS.CanvasRenderingContext2D, x1 int, y1 int, x2 int, y2 int) {
context.beginPath()
context.strokeStyle = 'black'.str
context.lineWidth = JS.Number(1)
context.moveTo(x1, y1)
context.lineTo(x2, y2)
context.stroke()
context.closePath()
}
struct DrawState {
mut:
context JS.CanvasRenderingContext2D
drawing bool
x int
y int
}
fn main() {
window := dom.window()
document := dom.document
clear_btn := document.getElementById('clearButton'.str) ?
canvas_elem := document.getElementById('canvas'.str) ?
canvas := get_canvas(canvas_elem)
ctx := canvas.getContext('2d'.str, js_undefined()) ?
context := match ctx {
JS.CanvasRenderingContext2D {
ctx
}
else {
panic('can not get 2d context')
}
}
mut state := DrawState{context, false, 0, 0}
canvas.addEventListener('mousedown'.str, fn [mut state] (event JS.Event) {
state.drawing = true
match event {
JS.MouseEvent {
state.x = int(event.offsetX)
state.y = int(event.offsetY)
}
else {}
}
}, JS.EventListenerOptions{})
canvas.addEventListener('mousemove'.str, fn [mut state] (event JS.Event) {
if state.drawing {
match event {
JS.MouseEvent {
draw_line(mut state.context, state.x, state.y, int(event.offsetX),
int(event.offsetY))
state.x = int(event.offsetX)
state.y = int(event.offsetY)
}
else {}
}
}
}, JS.EventListenerOptions{})
window.addEventListener('mouseup'.str, fn [mut state] (event JS.Event) {
if state.drawing {
match event {
JS.MouseEvent {
draw_line(mut state.context, state.x, state.y, int(event.offsetX),
int(event.offsetY))
}
else {}
}
state.x = 0
state.y = 0
state.drawing = false
}
}, JS.EventListenerOptions{})
clear_btn.addEventListener('click'.str, fn [mut state, canvas] (_ JS.Event) {
state.context.clearRect(0, 0, canvas.width, canvas.height)
}, JS.EventListenerOptions{})
}

View File

@@ -0,0 +1,7 @@
<body class="main">
<title>Drawing with mouse events</title>
<input type="button" id="clearButton" value="Clear canvas">
<canvas style="border: 1px solid black;" width="720" height="480" id="canvas"></canvas>
<script type="text/javascript" src="draw.js"></script>
</body>

View File

@@ -11,8 +11,14 @@ fn main() {
l.info('info')
l.warn('warn')
l.error('error')
l.debug('no debug')
l.debug('no output for debug')
l.set_level(.debug)
l.debug('debug')
l.fatal('fatal')
l.debug('debug now')
l.set_level(log.level_from_tag('INFO') or { log.Level.disabled }) // set level from string, sample
l.info('info again')
l.set_level(log.level_from_tag('') or { log.Level.disabled }) // set level from string, sample
l.error('no output anymore')
l.fatal('fatal') // panic, next statements won't be executed
l.set_level(.info)
l.warn('warn')
}

View File

@@ -1,20 +1,18 @@
// fn println(s string) { }
// fn test_fn() {
// println('test fn')
//}
fn test_fn() {
println('test fn')
}
fn main() {
println('native test')
// i := 0
// for i < 5 {
for _ in 1 .. 5 {
println('Hello world from V native machine code generator!')
// i++
mut i := 0
for i < 5 {
println('Hello world from V native machine code generator, in a while style for loop!')
i++
}
for _ in 1 .. 5 {
println('Hello world from V native machine code generator, in a range loop!')
}
/*
println('Hello again!')
//test_fn()
test_fn()
println('done')
*/
}

View File

@@ -166,135 +166,159 @@ fn (sp Sphere) intersect(r Ray) f64 {
const (
cen = Vec{50, 40.8, -860} // used by scene 1
spheres = [
[/* scene 0 cornnel box */ Sphere{
rad: 1e+5
p: Vec{1e+5 + 1, 40.8, 81.6}
e: Vec{}
c: Vec{.75, .25, .25}
refl: .diff
}, /* Left */ Sphere{
rad: 1e+5
p: Vec{-1e+5 + 99, 40.8, 81.6}
e: Vec{}
c: Vec{.25, .25, .75}
refl: .diff
}, /* Rght */ Sphere{
rad: 1e+5
p: Vec{50, 40.8, 1e+5}
e: Vec{}
c: Vec{.75, .75, .75}
refl: .diff
}, /* Back */ Sphere{
rad: 1e+5
p: Vec{50, 40.8, -1e+5 + 170}
e: Vec{}
c: Vec{}
refl: .diff
}, /* Frnt */ Sphere{
rad: 1e+5
p: Vec{50, 1e+5, 81.6}
e: Vec{}
c: Vec{.75, .75, .75}
refl: .diff
}, /* Botm */ Sphere{
rad: 1e+5
p: Vec{50, -1e+5 + 81.6, 81.6}
e: Vec{}
c: Vec{.75, .75, .75}
refl: .diff
}, /* Top */ Sphere{
rad: 16.5
p: Vec{27, 16.5, 47}
e: Vec{}
c: Vec{1, 1, 1}.mult_s(.999)
refl: .spec
}, /* Mirr */ Sphere{
rad: 16.5
p: Vec{73, 16.5, 78}
e: Vec{}
c: Vec{1, 1, 1}.mult_s(.999)
refl: .refr
}, /* Glas */ Sphere{
rad: 600
p: Vec{50, 681.6 - .27, 81.6}
e: Vec{12, 12, 12}
c: Vec{}
refl: .diff
} /* Lite */],
[/* scene 1 sunset */ Sphere{
rad: 1600
p: Vec{1.0, 0.0, 2.0}.mult_s(3000)
e: Vec{1.0, .9, .8}.mult_s(1.2e+1 * 1.56 * 2)
c: Vec{}
refl: .diff
}, /* sun */ Sphere{
rad: 1560
p: Vec{1, 0, 2}.mult_s(3500)
e: Vec{1.0, .5, .05}.mult_s(4.8e+1 * 1.56 * 2)
c: Vec{}
refl: .diff
}, /* horizon sun2 */ Sphere{
rad: 10000
p: cen + Vec{0, 0, -200}
e: Vec{0.00063842, 0.02001478, 0.28923243}.mult_s(6e-2 * 8)
c: Vec{.7, .7, 1}.mult_s(.25)
refl: .diff
}, /* sky */ Sphere{
rad: 100000
p: Vec{50, -100000, 0}
e: Vec{}
c: Vec{.3, .3, .3}
refl: .diff
}, /* grnd */ Sphere{
rad: 110000
p: Vec{50, -110048.5, 0}
e: Vec{.9, .5, .05}.mult_s(4)
c: Vec{}
refl: .diff
}, /* horizon brightener */ Sphere{
rad: 4e+4
p: Vec{50, -4e+4 - 30, -3000}
e: Vec{}
c: Vec{.2, .2, .2}
refl: .diff
}, /* mountains */ Sphere{
rad: 26.5
p: Vec{22, 26.5, 42}
e: Vec{}
c: Vec{1, 1, 1}.mult_s(.596)
refl: .spec
}, /* white Mirr */ Sphere{
rad: 13
p: Vec{75, 13, 82}
e: Vec{}
c: Vec{.96, .96, .96}.mult_s(.96)
refl: .refr
}, /* Glas */ Sphere{
rad: 22
p: Vec{87, 22, 24}
e: Vec{}
c: Vec{.6, .6, .6}.mult_s(.696)
refl: .refr
} /* Glas2 */],
[/* scene 3 Psychedelic */ Sphere{
rad: 150
p: Vec{50 + 75, 28, 62}
e: Vec{1, 1, 1}.mult_s(0e-3)
c: Vec{1, .9, .8}.mult_s(.93)
refl: .refr
}, Sphere{
rad: 28
p: Vec{50 + 5, -28, 62}
e: Vec{1, 1, 1}.mult_s(1e+1)
c: Vec{1, 1, 1}.mult_s(0)
refl: .diff
}, Sphere{
rad: 300
p: Vec{50, 28, 62}
e: Vec{1, 1, 1}.mult_s(0e-3)
c: Vec{1, 1, 1}.mult_s(.93)
refl: .spec
}],
[// scene 0 cornnel box
Sphere{
rad: 1e+5
p: Vec{1e+5 + 1, 40.8, 81.6}
e: Vec{}
c: Vec{.75, .25, .25}
refl: .diff
}, /* Left */
Sphere{
rad: 1e+5
p: Vec{-1e+5 + 99, 40.8, 81.6}
e: Vec{}
c: Vec{.25, .25, .75}
refl: .diff
}, /* Rght */
Sphere{
rad: 1e+5
p: Vec{50, 40.8, 1e+5}
e: Vec{}
c: Vec{.75, .75, .75}
refl: .diff
}, /* Back */
Sphere{
rad: 1e+5
p: Vec{50, 40.8, -1e+5 + 170}
e: Vec{}
c: Vec{}
refl: .diff
}, /* Frnt */
Sphere{
rad: 1e+5
p: Vec{50, 1e+5, 81.6}
e: Vec{}
c: Vec{.75, .75, .75}
refl: .diff
}, /* Botm */
Sphere{
rad: 1e+5
p: Vec{50, -1e+5 + 81.6, 81.6}
e: Vec{}
c: Vec{.75, .75, .75}
refl: .diff
}, /* Top */
Sphere{
rad: 16.5
p: Vec{27, 16.5, 47}
e: Vec{}
c: Vec{1, 1, 1}.mult_s(.999)
refl: .spec
}, /* Mirr */
Sphere{
rad: 16.5
p: Vec{73, 16.5, 78}
e: Vec{}
c: Vec{1, 1, 1}.mult_s(.999)
refl: .refr
}, /* Glas */
Sphere{
rad: 600
p: Vec{50, 681.6 - .27, 81.6}
e: Vec{12, 12, 12}
c: Vec{}
refl: .diff
} /* Lite */,
],
[// scene 1 sunset
Sphere{
rad: 1600
p: Vec{1.0, 0.0, 2.0}.mult_s(3000)
e: Vec{1.0, .9, .8}.mult_s(1.2e+1 * 1.56 * 2)
c: Vec{}
refl: .diff
}, /* sun */
Sphere{
rad: 1560
p: Vec{1, 0, 2}.mult_s(3500)
e: Vec{1.0, .5, .05}.mult_s(4.8e+1 * 1.56 * 2)
c: Vec{}
refl: .diff
}, /* horizon sun2 */
Sphere{
rad: 10000
p: cen + Vec{0, 0, -200}
e: Vec{0.00063842, 0.02001478, 0.28923243}.mult_s(6e-2 * 8)
c: Vec{.7, .7, 1}.mult_s(.25)
refl: .diff
}, /* sky */
Sphere{
rad: 100000
p: Vec{50, -100000, 0}
e: Vec{}
c: Vec{.3, .3, .3}
refl: .diff
}, /* grnd */
Sphere{
rad: 110000
p: Vec{50, -110048.5, 0}
e: Vec{.9, .5, .05}.mult_s(4)
c: Vec{}
refl: .diff
}, /* horizon brightener */
Sphere{
rad: 4e+4
p: Vec{50, -4e+4 - 30, -3000}
e: Vec{}
c: Vec{.2, .2, .2}
refl: .diff
}, /* mountains */
Sphere{
rad: 26.5
p: Vec{22, 26.5, 42}
e: Vec{}
c: Vec{1, 1, 1}.mult_s(.596)
refl: .spec
}, /* white Mirr */
Sphere{
rad: 13
p: Vec{75, 13, 82}
e: Vec{}
c: Vec{.96, .96, .96}.mult_s(.96)
refl: .refr
}, /* Glas */
Sphere{
rad: 22
p: Vec{87, 22, 24}
e: Vec{}
c: Vec{.6, .6, .6}.mult_s(.696)
refl: .refr
} /* Glas2 */,
],
[// scene 3 Psychedelic
Sphere{
rad: 150
p: Vec{50 + 75, 28, 62}
e: Vec{1, 1, 1}.mult_s(0e-3)
c: Vec{1, .9, .8}.mult_s(.93)
refl: .refr
},
Sphere{
rad: 28
p: Vec{50 + 5, -28, 62}
e: Vec{1, 1, 1}.mult_s(1e+1)
c: Vec{1, 1, 1}.mult_s(0)
refl: .diff
},
Sphere{
rad: 300
p: Vec{50, 28, 62}
e: Vec{1, 1, 1}.mult_s(0e-3)
c: Vec{1, 1, 1}.mult_s(.93)
refl: .spec
},
],
] // end of scene array
)

100
examples/rule110.v Normal file
View File

@@ -0,0 +1,100 @@
import os
import rand
fn main() {
mut arg := '31'
if os.args.len != 2 {
println('Usage: rule110 [<n>]')
println('Using default `n` value: 31')
} else {
arg = os.args[1]
}
mut n := arg.int()
if n > 200 || n < 3 {
eprintln('`n` must be between 3 and 200!')
exit(1)
}
print('\n')
title := ' Rule 110 V Implementation '
title_len := title.len
if n > title_len {
for _ in 0 .. (n - title_len) / 2 {
print('=')
}
print(title)
for _ in 0 .. (n - title_len) / 2 {
print('=')
}
} else {
println(title[1..(title_len - 1)])
}
mut generation_bin := []int{len: n}
for i in 0 .. n {
generation_bin[i] = rand.intn(2)
}
print('\n')
// println('Random generated first automaton content: $generation_bin')
for _ in 0 .. n {
print_generation(generation_bin)
next_generation(mut generation_bin)
}
}
fn print_generation(arr []int) {
symbols := [' ', '*']!
for i in 0 .. arr.len {
print(symbols[arr[i]])
}
print('\n')
}
fn next_generation(mut gen []int) {
mut arr := gen.clone()
mut prev := 0
mut curr := 0
mut next := 0
for i in 0 .. arr.len {
if (i - 1) % gen.len < 0 {
prev = gen[gen.len - 1]
} else {
prev = gen[(i - 1) % gen.len]
}
curr = gen[i]
next = gen[(i + 1) % gen.len]
if prev == 1 {
if curr == 1 {
if next == 1 { // 111
arr[i] = 0
} else { // 110
arr[i] = 1
}
} else {
if next == 1 { // 101
arr[i] = 1
} else { // 100
arr[i] = 0
}
}
} else {
if curr == 1 {
if next == 1 { // 011
arr[i] = 1
} else { // 010
arr[i] = 1
}
} else {
if next == 1 { // 001
arr[i] = 1
} else { // 000
arr[i] = 0
}
}
}
}
gen = arr.clone()
}

View File

@@ -55,6 +55,7 @@ mut:
best HighScore
snake []Pos
dir Direction
last_dir Direction
food Pos
start_time i64
last_tick i64
@@ -70,6 +71,7 @@ fn (mut app App) reset_game() {
Pos{0, 8},
]
app.dir = .right
app.last_dir = app.dir
app.food = Pos{10, 8}
app.start_time = time.ticks()
app.last_tick = time.ticks()
@@ -91,22 +93,22 @@ fn (mut app App) move_food() {
fn on_keydown(key gg.KeyCode, mod gg.Modifier, mut app App) {
match key {
.w, .up {
if app.dir != .down {
if app.last_dir != .down {
app.dir = .up
}
}
.s, .down {
if app.dir != .up {
if app.last_dir != .up {
app.dir = .down
}
}
.a, .left {
if app.dir != .right {
if app.last_dir != .right {
app.dir = .left
}
}
.d, .right {
if app.dir != .left {
if app.last_dir != .left {
app.dir = .right
}
}
@@ -150,6 +152,8 @@ fn on_frame(mut app App) {
}
app.snake << app.snake.last() + app.snake.last() - app.snake[app.snake.len - 2]
}
app.last_dir = app.dir
}
// drawing snake
for pos in app.snake {

View File

@@ -7,25 +7,8 @@
* that can be found in the LICENSE file.
*
* HOW TO COMPILE SHADERS:
* - download the sokol shader convertor tool from https://github.com/floooh/sokol-tools-bin
*
* - compile the .glsl shader with:
* linux : sokol-shdc --input cube_glsl.glsl --output cube_glsl.h --slang glsl330
* windows: sokol-shdc.exe --input cube_glsl.glsl --output cube_glsl.h --slang glsl330
*
* --slang parameter can be:
* - glsl330: desktop GL
* - glsl100: GLES2 / WebGL
* - glsl300es: GLES3 / WebGL2
* - hlsl4: D3D11
* - hlsl5: D3D11
* - metal_macos: Metal on macOS
* - metal_ios: Metal on iOS device
* - metal_sim: Metal on iOS simulator
* - wgpu: WebGPU
*
* you can have multiple platforms at the same time passing prameter like this: --slang glsl330:hlsl5:metal_macos
* for further infos have a look at the sokol shader tool docs.
* Run `v shader .` in this directory to compile the shaders.
* For more info and help with shader compilation see `docs.md` and `v help shader`.
*
* TODO:
* - add instancing
@@ -41,7 +24,7 @@ import gg.m4
// GLSL Include and functions
#flag -I @VMODROOT/.
#include "cube_glsl.h" #Please use sokol-shdc to generate the necessary cube_glsl.h file from cube_glsl.glsl (see the instructions at the top of this file)
#include "cube_glsl.h" # Should be generated with `v shader .` (see the instructions at the top of this file)
fn C.cube_shader_desc(gfx.Backend) &C.sg_shader_desc

View File

@@ -7,25 +7,8 @@
* that can be found in the LICENSE file.
*
* HOW TO COMPILE SHADERS:
* - download the sokol shader convertor tool from https://github.com/floooh/sokol-tools-bin
*
* - compile the .glsl shader with:
* linux : sokol-shdc --input rt_glsl.glsl --output rt_glsl.h --slang glsl330
* windows: sokol-shdc.exe --input rt_glsl.glsl --output rt_glsl.h --slang glsl330
*
* --slang parameter can be:
* - glsl330: desktop GL
* - glsl100: GLES2 / WebGL
* - glsl300es: GLES3 / WebGL2
* - hlsl4: D3D11
* - hlsl5: D3D11
* - metal_macos: Metal on macOS
* - metal_ios: Metal on iOS device
* - metal_sim: Metal on iOS simulator
* - wgpu: WebGPU
*
* you can have multiple platforms at the same time passing parameters like this: --slang glsl330:hlsl5:metal_macos
* for further infos have a look at the sokol shader tool docs.
* Run `v shader .` in this directory to compile the shaders.
* For more info and help with shader compilation see `docs.md` and `v help shader`.
*
* TODO:
* - frame counter
@@ -42,7 +25,7 @@ import time
// GLSL Include and functions
#flag -I @VMODROOT/.
#include "rt_glsl.h" #Please use sokol-shdc to generate the necessary rt_glsl.h file from rt_glsl.glsl (see the instructions at the top of this file)
#include "rt_glsl.h" # Should be generated with `v shader .` (see the instructions at the top of this file)
fn C.rt_shader_desc(gfx.Backend) &C.sg_shader_desc

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