ci: separate workflow for docs line len check (#6653)
parent
5c93f942be
commit
d881185d79
|
@ -1,7 +1,16 @@
|
||||||
name: CI
|
name: CI
|
||||||
on: [push, pull_request]
|
|
||||||
jobs:
|
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
paths-ignore:
|
||||||
|
- "doc/**"
|
||||||
|
- "CHANGELOG.md"
|
||||||
|
pull_request:
|
||||||
|
paths-ignore:
|
||||||
|
- "doc/**"
|
||||||
|
- "CHANGELOG.md"
|
||||||
|
|
||||||
|
jobs:
|
||||||
code-formatting:
|
code-formatting:
|
||||||
runs-on: ubuntu-18.04
|
runs-on: ubuntu-18.04
|
||||||
env:
|
env:
|
||||||
|
@ -461,15 +470,6 @@ jobs:
|
||||||
# - name: v2 self compilation
|
# - name: v2 self compilation
|
||||||
# run: .\v.exe -o v2.exe cmd/v && .\v2.exe -o v3.exe cmd/v
|
# run: .\v.exe -o v2.exe cmd/v && .\v2.exe -o v3.exe cmd/v
|
||||||
|
|
||||||
docs-line-len-check:
|
|
||||||
runs-on: ubuntu-18.04
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
- name: Build
|
|
||||||
run: make
|
|
||||||
- name: Check docs line length
|
|
||||||
run: ./v run cmd/tools/check-md.v doc/docs.md CHANGELOG.md
|
|
||||||
|
|
||||||
|
|
||||||
compilable-v-c-and-v-win-c:
|
compilable-v-c-and-v-win-c:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
name: Docs CI
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
paths:
|
||||||
|
- "cmd/tools/check-md.v"
|
||||||
|
- "doc/**"
|
||||||
|
- "CHANGELOG.md"
|
||||||
|
pull_request:
|
||||||
|
paths:
|
||||||
|
- "cmd/tools/check-md.v"
|
||||||
|
- "doc/**"
|
||||||
|
- "CHANGELOG.md"
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
docs-line-len-check:
|
||||||
|
runs-on: ubuntu-18.04
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- name: Build V
|
||||||
|
run: make
|
||||||
|
- name: Check docs line length
|
||||||
|
run: ./v run cmd/tools/check-md.v doc/docs.md doc/upcoming.md CHANGELOG.md
|
44
CHANGELOG.md
44
CHANGELOG.md
|
@ -1,7 +1,8 @@
|
||||||
## V 0.1.27
|
## V 0.1.27
|
||||||
*5 May 2020*
|
*5 May 2020*
|
||||||
|
|
||||||
- vfmt has been re-written from scratch using the new AST parser. It's much faster, cleaner, and can format
|
- vfmt has been re-written from scratch using the new AST parser.
|
||||||
|
It's much faster, cleaner, and can format
|
||||||
files with compilation errors.
|
files with compilation errors.
|
||||||
- `strconv`, `sprintf`, and `printf` in native V, without any libc calls.
|
- `strconv`, `sprintf`, and `printf` in native V, without any libc calls.
|
||||||
- Interfaces are now a lot more stable and have all expected features.
|
- Interfaces are now a lot more stable and have all expected features.
|
||||||
|
@ -10,13 +11,13 @@ files with compilation errors.
|
||||||
- New `[]int{cap:cap, len:len}` syntax for initializing array length and capacity.
|
- New `[]int{cap:cap, len:len}` syntax for initializing array length and capacity.
|
||||||
- New `is` keyword for checking the type of sum types and interfaces.
|
- New `is` keyword for checking the type of sum types and interfaces.
|
||||||
- `as` can now be used to cast interfaces and sum types.
|
- `as` can now be used to cast interfaces and sum types.
|
||||||
- Profiling with `-profile`. Prints a nice table with detailed information about every single function call:
|
- Profiling with `-profile`. Prints a nice table with details about every single function call:
|
||||||
number of calls, average time per call, total time per function.
|
number of calls, average time per call, total time per function
|
||||||
- `import(xxx)` syntax has been removed in favor of `import xxx` for simplicity and greppability.
|
- `import(xxx)` syntax has been removed in favor of `import xxx` for simplicity and greppability.
|
||||||
- Lots of fixes and improvements in the type checker.
|
- Lots of fixes and improvements in the type checker.
|
||||||
- `time.StopWatch`
|
- `time.StopWatch`
|
||||||
- `dl` module for dynamic loading.
|
- `dl` module for dynamic loading.
|
||||||
- Automatic `str()` method generation for every single type, including all arrays and fixed size arrays.
|
- Automatic `str()` method generation for every single type, including all arrays.
|
||||||
- Short struct initialization syntax for imitating named function args: `foo(bar:0, baz:1)`.
|
- Short struct initialization syntax for imitating named function args: `foo(bar:0, baz:1)`.
|
||||||
- New operator `!in`.
|
- New operator `!in`.
|
||||||
- Performance improvements in critical parts of the builtin data structures (array, map).
|
- Performance improvements in critical parts of the builtin data structures (array, map).
|
||||||
|
@ -37,13 +38,15 @@ number of calls, average time per call, total time per function.
|
||||||
## V 0.1.25
|
## V 0.1.25
|
||||||
*1 Apr 2020*
|
*1 Apr 2020*
|
||||||
|
|
||||||
- The entire compiler has been re-written with an AST parser. The code is now a lot cleaner and more maintainable. ~15k lines of old compiler code were removed.
|
- The entire compiler has been re-written with an AST parser.
|
||||||
|
The code is now a lot cleaner and more maintainable.
|
||||||
|
~15k lines of old compiler code were removed.
|
||||||
|
|
||||||
## V 0.1.24
|
## V 0.1.24
|
||||||
*31 Dec 2019*
|
*31 Dec 2019*
|
||||||
|
|
||||||
- A new parser/generator built on top of an AST that simplifies code greatly and allows to implement new
|
- A new parser/generator built on top of an AST that simplifies code greatly
|
||||||
backends much faster.
|
and allows to implement new backends much faster.
|
||||||
- Sum types (`type Expr = IfExpr | MatchExpr | IntegerLiteral`).
|
- Sum types (`type Expr = IfExpr | MatchExpr | IntegerLiteral`).
|
||||||
- B-tree map (sped up the V compiler by ~10%).
|
- B-tree map (sped up the V compiler by ~10%).
|
||||||
- `v fmt -w`.
|
- `v fmt -w`.
|
||||||
|
@ -54,7 +57,7 @@ number of calls, average time per call, total time per function.
|
||||||
- os: `is_link()`, `is_dir()`, `exists()`.
|
- os: `is_link()`, `is_dir()`, `exists()`.
|
||||||
- Ranging through fixed size arrays.
|
- Ranging through fixed size arrays.
|
||||||
- Lots of fixes in ORM and vweb.
|
- Lots of fixes in ORM and vweb.
|
||||||
- The first tutorial: [building a simple web application with vweb](https://github.com/vlang/v/blob/master/tutorials/building-a-simple-web-blog-with-vweb.md).
|
- The first tutorial: [building a simple web application with vweb](https://github.com/vlang/v/blob/master/tutorials/building-a-simple-web-blog-with-vweb.md)
|
||||||
- Match expressions now must be exhaustive.
|
- Match expressions now must be exhaustive.
|
||||||
- freestanding: `malloc()`/`free()`.
|
- freestanding: `malloc()`/`free()`.
|
||||||
- `++` is now required instead of `+= 1` for consistency.
|
- `++` is now required instead of `+= 1` for consistency.
|
||||||
|
@ -76,13 +79,14 @@ number of calls, average time per call, total time per function.
|
||||||
## V 0.1.23
|
## V 0.1.23
|
||||||
*30 Nov 2019*
|
*30 Nov 2019*
|
||||||
|
|
||||||
- [Direct x64 machine code generation](https://github.com/vlang/v/issues/2849). Hello world being built in 3 milliseconds.
|
- [Direct x64 machine code generation](https://github.com/vlang/v/issues/2849).
|
||||||
- Bare metal support via the `-freestanding` flag, allowing to build programs without linking to libc.
|
Hello world being built in 3 milliseconds.
|
||||||
|
- Bare metal support via the `-freestanding` flag, to build programs without linking to libc.
|
||||||
- Prebuilt V packages for Linux, macOS, and Windows.
|
- Prebuilt V packages for Linux, macOS, and Windows.
|
||||||
- `string.index()` now returns `?int` instead of `int/-1`.
|
- `string.index()` now returns `?int` instead of `int/-1`.
|
||||||
- Lots of fixes in Generics.
|
- Lots of fixes in Generics.
|
||||||
- vweb framework for developing web applications is back.
|
- vweb framework for developing web applications is back.
|
||||||
- Vorum, the forum/blogging software written in V/vweb, can now be compiled and has been added to CI.
|
- Vorum, the forum/blogging software written in vweb, can now be compiled and has been added to CI.
|
||||||
- REPL, `v up` have been split up into separate applications to keep the core V compiler small.
|
- REPL, `v up` have been split up into separate applications to keep the core V compiler small.
|
||||||
- V now enforces short enum syntax (`.green` instead of `Color.green`) when it's enough.
|
- V now enforces short enum syntax (`.green` instead of `Color.green`) when it's enough.
|
||||||
- V UI for macOS.
|
- V UI for macOS.
|
||||||
|
@ -90,7 +94,8 @@ number of calls, average time per call, total time per function.
|
||||||
- `os.cp()` for copying files and directores.
|
- `os.cp()` for copying files and directores.
|
||||||
- Additional compile-time flags: `$if clang, msvc, mingw, x32, x64, big_endian, little_endian {`.
|
- Additional compile-time flags: `$if clang, msvc, mingw, x32, x64, big_endian, little_endian {`.
|
||||||
- All C functions now have to be declared, all missing C functions have been defined.
|
- All C functions now have to be declared, all missing C functions have been defined.
|
||||||
- Global variables (only with the `--enable-globals` flag) for low level applications like kernels and drivers.
|
- Global variables (only with the `--enable-globals` flag)
|
||||||
|
for low level applications like kernels and drivers.
|
||||||
- Nothing can be cast to bool (previously code like `if bool(1) {` worked).
|
- Nothing can be cast to bool (previously code like `if bool(1) {` worked).
|
||||||
- `<<` and `>>` now work with all integer types.
|
- `<<` and `>>` now work with all integer types.
|
||||||
- V detects Cygwin and shows an error (V supports Windows natively).
|
- V detects Cygwin and shows an error (V supports Windows natively).
|
||||||
|
@ -116,7 +121,7 @@ number of calls, average time per call, total time per function.
|
||||||
- `malloc/free` on bare metal.
|
- `malloc/free` on bare metal.
|
||||||
- `utf8` helper functions (`to_lower()`, `to_upper()`, etc).
|
- `utf8` helper functions (`to_lower()`, `to_upper()`, etc).
|
||||||
- Optimization of `for c in str {`.
|
- Optimization of `for c in str {`.
|
||||||
- `string/array.left/right/slice/substr` were removed (`[a..b]` slicing syntax should be used instead).
|
- `string/array.left/right/slice/substr` were removed (use `[a..b]` slicing syntax instead).
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -128,8 +133,7 @@ number of calls, average time per call, total time per function.
|
||||||
- Optimized `array.filter()` and `array.map()`.
|
- Optimized `array.filter()` and `array.map()`.
|
||||||
- `sqlite` module.
|
- `sqlite` module.
|
||||||
- Cached modules for faster compilation.
|
- Cached modules for faster compilation.
|
||||||
- Dramatic compilation optimizations: [V now compiles itself in
|
- Dramatic compilation optimizations: [V now compiles itself in 0.10 - 0.30 seconds](https://github.com/vlang/v/wiki/The-V-language-now-compiles-itself-in-0.09-seconds)
|
||||||
0.10 - 0.30 seconds](https://github.com/vlang/v/wiki/The-V-language-now-compiles-itself-in-0.09-seconds).
|
|
||||||
- V scripts (simpler and cross-platform alternative to Bash).
|
- V scripts (simpler and cross-platform alternative to Bash).
|
||||||
- Infinite multi-dimensional arrays (`[][][]int`).
|
- Infinite multi-dimensional arrays (`[][][]int`).
|
||||||
- `unsafe`.
|
- `unsafe`.
|
||||||
|
@ -296,7 +300,7 @@ this backend.
|
||||||
## V 0.1.15
|
## V 0.1.15
|
||||||
*15 Jul 2019*
|
*15 Jul 2019*
|
||||||
- FreeBSD, OpenBSD, NetBSD, DragonFly support.
|
- FreeBSD, OpenBSD, NetBSD, DragonFly support.
|
||||||
- Hot code reloading now works with graphical applications: [bounce.v](https://github.com/vlang/v/blob/master/examples/hot_code_reloading/bounce.v).
|
- Hot reloading now works with graphical applications: [bounce.v](examples/hot_reload/bounce.v)
|
||||||
- VROOT was removed, the installation process is now much simpler.
|
- VROOT was removed, the installation process is now much simpler.
|
||||||
- `defer` statement.
|
- `defer` statement.
|
||||||
- map.v was re-written. It's now much faster.
|
- map.v was re-written. It's now much faster.
|
||||||
|
@ -310,7 +314,7 @@ this backend.
|
||||||
## V 0.1.14
|
## V 0.1.14
|
||||||
*12 Jul 2019*
|
*12 Jul 2019*
|
||||||
- `gg` module Windows support, V Tetris runs on Windows.
|
- `gg` module Windows support, V Tetris runs on Windows.
|
||||||
- `glad` and `cJSON` are now compiled only once, this makes compilation of programs using `gg` and `json` a bit faster.
|
- Compile `glad` and `cJSON` only once. Programs using `gg` or `json` compile a bit faster.
|
||||||
- `v.c` has been cleaned up and minimized (~16k => ~10k lines of code).
|
- `v.c` has been cleaned up and minimized (~16k => ~10k lines of code).
|
||||||
- `type` aliases can now have methods.
|
- `type` aliases can now have methods.
|
||||||
- Const overflow check during compilation (`byte(1000)` will no longer compile).
|
- Const overflow check during compilation (`byte(1000)` will no longer compile).
|
||||||
|
@ -332,8 +336,10 @@ this backend.
|
||||||
## V 0.1.12
|
## V 0.1.12
|
||||||
*4 Jul 2019*
|
*4 Jul 2019*
|
||||||
- V can finally compile itself on Windows (https://github.com/vlang/v#mingw-w64).
|
- V can finally compile itself on Windows (https://github.com/vlang/v#mingw-w64).
|
||||||
- `os` module now uses optionals in all functions that return `File`. Lots of bugs with optionals fixed.
|
- `os` module now uses optionals in all functions that return `File`.
|
||||||
- `println` was optimized. It no longer results in allocations. Now it also works correctly with all integer types.
|
- Lots of bugs with optionals were fixed.
|
||||||
|
- `println` was optimized. It no longer results in allocations.
|
||||||
|
Now it also works correctly with all integer types.
|
||||||
- Lots of `vfmt` fixes, it will be enabled tomorrow.
|
- Lots of `vfmt` fixes, it will be enabled tomorrow.
|
||||||
- New `strings` module.
|
- New `strings` module.
|
||||||
- Lots of other fixes and improvements, thanks to all the contributors.
|
- Lots of other fixes and improvements, thanks to all the contributors.
|
||||||
|
|
|
@ -8,23 +8,36 @@ const (
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
files_paths := os.args[1..]
|
files_paths := os.args[1..]
|
||||||
|
mut warnings := 0
|
||||||
mut errors := 0
|
mut errors := 0
|
||||||
for file_path in files_paths {
|
for file_path in files_paths {
|
||||||
real_path := os.real_path(file_path)
|
real_path := os.real_path(file_path)
|
||||||
lines := os.read_lines(real_path) or {
|
lines := os.read_lines(real_path) or {
|
||||||
|
println('"$file_path" does not exist')
|
||||||
|
warnings++
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
for i, line in lines {
|
for i, line in lines {
|
||||||
if line.len > too_long_line_length {
|
if line.len > too_long_line_length {
|
||||||
eprintln('$real_path:${i+1}:${line.len+1}: line too long')
|
linetrace_msg := '$file_path:${i + 1}:${line.len + 1}: '
|
||||||
|
if line.starts_with('|') {
|
||||||
|
println(linetrace_msg + 'long table (warn)')
|
||||||
|
warnings++
|
||||||
|
} else if line.contains('https') {
|
||||||
|
println(linetrace_msg + 'long link (warn)')
|
||||||
|
warnings++
|
||||||
|
} else {
|
||||||
|
eprintln(linetrace_msg + 'line too long')
|
||||||
errors++
|
errors++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// TODO: uncomment this AFTER doc/docs.md line lengths are fixed
|
}
|
||||||
/*
|
if warnings > 0 || errors > 0 {
|
||||||
|
println('\nWarnings | Errors')
|
||||||
|
println('$warnings\t | $errors')
|
||||||
|
}
|
||||||
if errors > 0 {
|
if errors > 0 {
|
||||||
exit(1)
|
exit(1)
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
185
doc/docs.md
185
doc/docs.md
|
@ -255,7 +255,8 @@ println(age)
|
||||||
```
|
```
|
||||||
|
|
||||||
To change the value of the variable use `=`. In V, variables are
|
To change the value of the variable use `=`. In V, variables are
|
||||||
immutable by default. To be able to change the value of the variable, you have to declare it with `mut`.
|
immutable by default.
|
||||||
|
To be able to change the value of the variable, you have to declare it with `mut`.
|
||||||
|
|
||||||
Try compiling the program above after removing `mut` from the first line.
|
Try compiling the program above after removing `mut` from the first line.
|
||||||
|
|
||||||
|
@ -281,8 +282,10 @@ fn main() {
|
||||||
|
|
||||||
### Declaration errors
|
### Declaration errors
|
||||||
|
|
||||||
In development mode the compiler will warn you that you haven't used the variable (you'll get an "unused variable" warning).
|
In development mode the compiler will warn you that you haven't used the variable
|
||||||
In production mode (enabled by passing the `-prod` flag to v – `v -prod foo.v`) it will not compile at all (like in Go).
|
(you'll get an "unused variable" warning).
|
||||||
|
In production mode (enabled by passing the `-prod` flag to v – `v -prod foo.v`)
|
||||||
|
it will not compile at all (like in Go).
|
||||||
|
|
||||||
```v
|
```v
|
||||||
fn main() {
|
fn main() {
|
||||||
|
@ -294,7 +297,8 @@ fn main() {
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Unlike most languages, variable shadowing is not allowed. Declaring a variable with a name that is already used in a parent scope will cause a compilation error.
|
Unlike most languages, variable shadowing is not allowed. Declaring a variable with a name
|
||||||
|
that is already used in a parent scope will cause a compilation error.
|
||||||
|
|
||||||
## Types
|
## Types
|
||||||
|
|
||||||
|
@ -393,8 +397,9 @@ println('Hello, $name!') // Hello, Bob!
|
||||||
It also works with fields: `'age = $user.age'`.
|
It also works with fields: `'age = $user.age'`.
|
||||||
If you need more complex expressions, use `${}`: `'can register = ${user.age > 13}'`.
|
If you need more complex expressions, use `${}`: `'can register = ${user.age > 13}'`.
|
||||||
|
|
||||||
Format specifiers similar to those in C's `printf()` are also supported. `f`, `g`, `x`, etc. are optional
|
Format specifiers similar to those in C's `printf()` are also supported.
|
||||||
and specify the output format. The compiler takes care of the storage size, so there is no `hd` or `llu`.
|
`f`, `g`, `x`, etc. are optional and specify the output format.
|
||||||
|
The compiler takes care of the storage size, so there is no `hd` or `llu`.
|
||||||
|
|
||||||
```v
|
```v
|
||||||
x := 123.4567
|
x := 123.4567
|
||||||
|
@ -503,8 +508,10 @@ The type of an array is determined by the first element:
|
||||||
* `[1, 2, 3]` is an array of ints (`[]int`).
|
* `[1, 2, 3]` is an array of ints (`[]int`).
|
||||||
* `['a', 'b']` is an array of strings (`[]string`).
|
* `['a', 'b']` is an array of strings (`[]string`).
|
||||||
|
|
||||||
If V is unable to infer the type of an array, the user can explicitly specify it for the first element: `[byte(16), 32, 64, 128]`.
|
If V is unable to infer the type of an array,
|
||||||
V arrays are homogeneous (all elements must have the same type). This means that code like `[1, 'a']` will not compile.
|
the user can explicitly specify it for the first element: `[byte(16), 32, 64, 128]`.
|
||||||
|
V arrays are homogeneous (all elements must have the same type).
|
||||||
|
This means that code like `[1, 'a']` will not compile.
|
||||||
|
|
||||||
The `.len` field returns the length of the array. Note that it's a read-only field,
|
The `.len` field returns the length of the array. Note that it's a read-only field,
|
||||||
and it can't be modified by the user. Exported fields are read-only by default in V.
|
and it can't be modified by the user. Exported fields are read-only by default in V.
|
||||||
|
@ -543,7 +550,8 @@ and the default element (`init`):
|
||||||
arr := []int{ len: 5, init: -1 } // `[-1, -1, -1, -1, -1]`
|
arr := []int{ len: 5, init: -1 } // `[-1, -1, -1, -1, -1]`
|
||||||
```
|
```
|
||||||
|
|
||||||
Setting the capacity improves performance of insertions, as it reduces the number of reallocations needed:
|
Setting the capacity improves performance of insertions,
|
||||||
|
as it reduces the number of reallocations needed:
|
||||||
|
|
||||||
```v
|
```v
|
||||||
mut numbers := []int{ cap: 1000 }
|
mut numbers := []int{ cap: 1000 }
|
||||||
|
@ -731,7 +739,8 @@ if a < b {
|
||||||
```
|
```
|
||||||
|
|
||||||
`if` statements are pretty straightforward and similar to most other languages.
|
`if` statements are pretty straightforward and similar to most other languages.
|
||||||
Unlike other C-like languages, there are no parentheses surrounding the condition, and the braces are always required.
|
Unlike other C-like languages,
|
||||||
|
there are no parentheses surrounding the condition and the braces are always required.
|
||||||
|
|
||||||
`if` can be used as an expression:
|
`if` can be used as an expression:
|
||||||
|
|
||||||
|
@ -767,7 +776,8 @@ if x is Abc {
|
||||||
If you have a struct field which should be checked, there is also a way to name a alias.
|
If you have a struct field which should be checked, there is also a way to name a alias.
|
||||||
```v
|
```v
|
||||||
if x.bar is MyStruct as bar {
|
if x.bar is MyStruct as bar {
|
||||||
// x.bar cannot be cast automatically, you must explicitly state "as bar" to create a variable with the MyStruct type
|
// x.bar cannot be cast automatically
|
||||||
|
// you must explicitly state "as bar" to create a variable with the MyStruct type
|
||||||
println(bar)
|
println(bar)
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
@ -797,7 +807,8 @@ if parser.token in [.plus, .minus, .div, .mult] {
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
V optimizes such expressions, so both `if` statements above produce the same machine code and no arrays are created.
|
V optimizes such expressions,
|
||||||
|
so both `if` statements above produce the same machine code and no arrays are created.
|
||||||
|
|
||||||
### For loop
|
### For loop
|
||||||
|
|
||||||
|
@ -819,7 +830,8 @@ for i, name in names {
|
||||||
The `for value in arr` form is used for going through elements of an array.
|
The `for value in arr` form is used for going through elements of an array.
|
||||||
If an index is required, an alternative form `for index, value in arr` can be used.
|
If an index is required, an alternative form `for index, value in arr` can be used.
|
||||||
|
|
||||||
Note, that the value is read-only. If you need to modify the array while looping, you have to use indexing:
|
Note, that the value is read-only.
|
||||||
|
If you need to modify the array while looping, you have to use indexing:
|
||||||
|
|
||||||
```v
|
```v
|
||||||
mut numbers := [0, 1, 2]
|
mut numbers := [0, 1, 2]
|
||||||
|
@ -982,7 +994,8 @@ Note: `match` as an expression is not usable in `for` loop and `if` statements.
|
||||||
|
|
||||||
### Defer
|
### Defer
|
||||||
|
|
||||||
A defer statement defers the execution of a block of statements until the surrounding function returns.
|
A defer statement defers the execution of a block of statements
|
||||||
|
until the surrounding function returns.
|
||||||
|
|
||||||
```v
|
```v
|
||||||
fn read_log() {
|
fn read_log() {
|
||||||
|
@ -1061,7 +1074,8 @@ struct Foo {
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
All struct fields are zeroed by default during the creation of the struct. Array and map fields are allocated.
|
All struct fields are zeroed by default during the creation of the struct.
|
||||||
|
Array and map fields are allocated.
|
||||||
|
|
||||||
It's also possible to define custom default values.
|
It's also possible to define custom default values.
|
||||||
|
|
||||||
|
@ -1158,7 +1172,8 @@ fn main() {
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
This means that defining public readonly fields is very easy in V, no need in getters/setters or properties.
|
This means that defining public readonly fields is very easy in V,
|
||||||
|
no need in getters/setters or properties.
|
||||||
|
|
||||||
### Methods
|
### Methods
|
||||||
|
|
||||||
|
@ -1190,11 +1205,11 @@ but a short, preferably one letter long, name.
|
||||||
|
|
||||||
### Pure functions by default
|
### Pure functions by default
|
||||||
|
|
||||||
V functions are pure by default, meaning that their return values are a function of their arguments only,
|
V functions are pure by default, meaning that their return values are a function of their
|
||||||
and their evaluation has no side effects (besides I/O).
|
arguments only, and their evaluation has no side effects (besides I/O).
|
||||||
|
|
||||||
This is achieved by a lack of global variables and all function arguments being immutable by default,
|
This is achieved by a lack of global variables and all function arguments being
|
||||||
even when [references](#references) are passed.
|
immutable by default, even when [references](#references) are passed.
|
||||||
|
|
||||||
V is not a purely functional language however.
|
V is not a purely functional language however.
|
||||||
|
|
||||||
|
@ -1243,7 +1258,8 @@ It is preferable to return values instead of modifying arguments.
|
||||||
Modifying arguments should only be done in performance-critical parts of your application
|
Modifying arguments should only be done in performance-critical parts of your application
|
||||||
to reduce allocations and copying.
|
to reduce allocations and copying.
|
||||||
|
|
||||||
For this reason V doesn't allow the modification of arguments with primitive types such as integers. Only more complex types such as arrays and maps may be modified.
|
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)`
|
Use `user.register()` or `user = register(user)`
|
||||||
instead of `register(mut user)`.
|
instead of `register(mut user)`.
|
||||||
|
@ -1542,7 +1558,8 @@ match color {
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Enum match must be exhaustive or have an `else` branch. This ensures that if a new enum field is added, it's handled everywhere in the code.
|
Enum match must be exhaustive or have an `else` branch.
|
||||||
|
This ensures that if a new enum field is added, it's handled everywhere in the code.
|
||||||
|
|
||||||
### Sum types
|
### Sum types
|
||||||
|
|
||||||
|
@ -1673,7 +1690,8 @@ V combines `Option` and `Result` into one type, so you don't need to decide whic
|
||||||
The amount of work required to "upgrade" a function to an optional function is minimal;
|
The amount of work required to "upgrade" a function to an optional function is minimal;
|
||||||
you have to add a `?` to the return type and return an error when something goes wrong.
|
you have to add a `?` to the return type and return an error when something goes wrong.
|
||||||
|
|
||||||
If you don't need to return an error message, you can simply `return none` (this is a more efficient equivalent of `return error("")`).
|
If you don't need to return an error message, you can simply `return none`
|
||||||
|
(this is a more efficient equivalent of `return error("")`).
|
||||||
|
|
||||||
This is the primary mechanism for error handling in V. They are still values, like in Go,
|
This is the primary mechanism for error handling in V. They are still values, like in Go,
|
||||||
but the advantage is that errors can't be unhandled, and handling them is a lot less verbose.
|
but the advantage is that errors can't be unhandled, and handling them is a lot less verbose.
|
||||||
|
@ -1728,16 +1746,18 @@ user := repo.find_user_by_id(7) or {
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Here, you can either call `panic()` or `exit()`, which will stop the execution of the entire program,
|
Here, you can either call `panic()` or `exit()`, which will stop the execution of the
|
||||||
or use a control flow statement (`return`, `break`, `continue`, etc) to break from the current block.
|
entire program, or use a control flow statement (`return`, `break`, `continue`, etc)
|
||||||
|
to break from the current block.
|
||||||
Note that `break` and `continue` can only be used inside a `for` loop.
|
Note that `break` and `continue` can only be used inside a `for` loop.
|
||||||
|
|
||||||
V does not have a way to forcibly "unwrap" an optional (as other languages do, for instance Rust's `unwrap()`
|
V does not have a way to forcibly "unwrap" an optional (as other languages do,
|
||||||
or Swift's `!`). To do this, use `or { panic(err) }` instead.
|
for instance Rust's `unwrap()` or Swift's `!`). To do this, use `or { panic(err) }` instead.
|
||||||
|
|
||||||
---
|
---
|
||||||
The third method is to provide a default value at the end of the `or` block. In case of an error,
|
The third method is to provide a default value at the end of the `or` block.
|
||||||
that value would be assigned instead, so it must have the same type as the content of the `Option` being handled.
|
In case of an error, that value would be assigned instead,
|
||||||
|
so it must have the same type as the content of the `Option` being handled.
|
||||||
|
|
||||||
```v
|
```v
|
||||||
fn do_something(s string) ?string {
|
fn do_something(s string) ?string {
|
||||||
|
@ -1911,8 +1931,9 @@ y := <-ch2 ?
|
||||||
|
|
||||||
#### Channel Select
|
#### Channel Select
|
||||||
|
|
||||||
The `select` command allows monitoring several channels at the same time without noticeable CPU load. It consists
|
The `select` command allows monitoring several channels at the same time
|
||||||
of a list of possible transfers and associated branches of statements - similar to the [match](#match) command:
|
without noticeable CPU load. It consists of a list of possible transfers and associated branches
|
||||||
|
of statements - similar to the [match](#match) command:
|
||||||
```v
|
```v
|
||||||
select {
|
select {
|
||||||
a := <-ch {
|
a := <-ch {
|
||||||
|
@ -1934,7 +1955,8 @@ The timeout branch is optional. If it is absent `select` waits for an unlimited
|
||||||
It is also possible to proceed immediately if no channel is ready in the moment `select` is called
|
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:
|
The `select` command can be used as an *expression* of type `bool`
|
||||||
|
that becomes `false` if all channels are closed:
|
||||||
```v
|
```v
|
||||||
if select {
|
if select {
|
||||||
ch <- a {
|
ch <- a {
|
||||||
|
@ -1956,14 +1978,15 @@ res2 := ch2.try_pop(mut b) // try to perform `b = <-ch2
|
||||||
l := ch.len // number of elements in queue
|
l := ch.len // number of elements in queue
|
||||||
c := ch.cap // maximum queue length
|
c := ch.cap // maximum queue length
|
||||||
```
|
```
|
||||||
The `try_push/pop()` methods will return immediately with one of the results `.success`, `.not_ready`
|
The `try_push/pop()` methods will return immediately with one of the results
|
||||||
or `.closed` - dependent on whether the object has been transferred or the reason why not. Usage
|
`.success`, `.not_ready` or `.closed` - dependent on whether the object has been transferred or
|
||||||
of these methods and properties in production is not recommended - algorithms based on them are often subject
|
the reason why not.
|
||||||
to race conditions. Use `select` instead.
|
Usage of these methods and properties in production is not recommended -
|
||||||
|
algorithms based on them are often subject to race conditions. Use `select` instead.
|
||||||
|
|
||||||
Data can be exchanged between a coroutine
|
Data can be exchanged between a coroutine and the calling thread via a shared variable.
|
||||||
and the calling thread via a shared variable. This variable should be created as reference and passed to
|
This variable should be created as reference and passed to the coroutine as `mut`.
|
||||||
the coroutine as `mut`. The underlying `struct` should also contain a `mutex` to lock concurrent access:
|
The underlying `struct` should also contain a `mutex` to lock concurrent access:
|
||||||
|
|
||||||
```v
|
```v
|
||||||
import sync
|
import sync
|
||||||
|
@ -2035,10 +2058,12 @@ println(foos[1].x)
|
||||||
|
|
||||||
Because of the ubiquitous nature of JSON, support for it is built directly into V.
|
Because of the ubiquitous nature of JSON, support for it is built directly into V.
|
||||||
|
|
||||||
The `json.decode` function takes two arguments: the first argument of the `json.decode` function is the type into which the JSON value should be decoded and the second is a string containing the JSON data.
|
The `json.decode` function takes two arguments:
|
||||||
|
the first is the type into which the JSON value should be decoded and
|
||||||
|
the second is a string containing the JSON data.
|
||||||
|
|
||||||
V generates code for JSON encoding and decoding. No runtime reflection is used. This results in much better
|
V generates code for JSON encoding and decoding.
|
||||||
performance.
|
No runtime reflection is used. This results in much better performance.
|
||||||
|
|
||||||
## Testing
|
## Testing
|
||||||
|
|
||||||
|
@ -2153,7 +2178,8 @@ fn test() []int {
|
||||||
|
|
||||||
(This is still in an alpha state)
|
(This is still in an alpha state)
|
||||||
|
|
||||||
V has a built-in ORM (object-relational mapping) which supports SQLite, and will soon support MySQL, Postgres, MS SQL, and Oracle.
|
V has a built-in ORM (object-relational mapping) which supports SQLite,
|
||||||
|
and will soon support MySQL, Postgres, MS SQL, and Oracle.
|
||||||
|
|
||||||
V's ORM provides a number of benefits:
|
V's ORM provides a number of benefits:
|
||||||
|
|
||||||
|
@ -2161,7 +2187,8 @@ V's ORM provides a number of benefits:
|
||||||
- Queries are constructed using V's syntax. (There's no need to learn another syntax.)
|
- Queries are constructed using V's syntax. (There's no need to learn another syntax.)
|
||||||
- Safety. (All queries are automatically sanitised to prevent SQL injection.)
|
- Safety. (All queries are automatically sanitised to prevent SQL injection.)
|
||||||
- Compile time checks. (This prevents typos which can only be caught during runtime.)
|
- Compile time checks. (This prevents typos which can only be caught during runtime.)
|
||||||
- Readability and simplicity. (You don't need to manually parse the results of a query and then manually construct objects from the parsed results.)
|
- Readability and simplicity. (You don't need to manually parse the results of a query and
|
||||||
|
then manually construct objects from the parsed results.)
|
||||||
|
|
||||||
```v
|
```v
|
||||||
struct Customer { // struct name has to be the same as the table name (for now)
|
struct Customer { // struct name has to be the same as the table name (for now)
|
||||||
|
@ -2199,7 +2226,8 @@ For more examples, see <a href='https://github.com/vlang/v/blob/master/vlib/orm/
|
||||||
## Writing Documentation
|
## Writing Documentation
|
||||||
|
|
||||||
The way it works is very similar to Go. It's very simple: there's no need to
|
The way it works is very similar to Go. It's very simple: there's no need to
|
||||||
write documentation separately for your code, vdoc will generate it from docstrings in the source code.
|
write documentation separately for your code,
|
||||||
|
vdoc will generate it from docstrings in the source code.
|
||||||
|
|
||||||
Documentation for each function/type/const must be placed right before the declaration:
|
Documentation for each function/type/const must be placed right before the declaration:
|
||||||
|
|
||||||
|
@ -2335,8 +2363,10 @@ fn my_callback(arg voidptr, howmany int, cvalues &charptr, cnames &charptr) int
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
db := &C.sqlite3(0) // this means `sqlite3* db = 0`
|
db := &C.sqlite3(0) // this means `sqlite3* db = 0`
|
||||||
C.sqlite3_open('users.db', &db) // passing a string literal to a C function call results in a C string, not a V string
|
// passing a string literal to a C function call results in a C string, not a V string
|
||||||
// C.sqlite3_open(db_path.str, &db) // you can also use `.str byteptr` field to convert a V string to a C char pointer
|
C.sqlite3_open('users.db', &db)
|
||||||
|
// C.sqlite3_open(db_path.str, &db)
|
||||||
|
// you can also use `.str byteptr` field to convert a V string to a C char pointer
|
||||||
query := 'select count(*) from users'
|
query := 'select count(*) from users'
|
||||||
stmt := &C.sqlite3_stmt(0)
|
stmt := &C.sqlite3_stmt(0)
|
||||||
C.sqlite3_prepare_v2(db, query.str, - 1, &stmt, 0)
|
C.sqlite3_prepare_v2(db, query.str, - 1, &stmt, 0)
|
||||||
|
@ -2365,7 +2395,8 @@ Add `#flag` directives to the top of your V files to provide C compilation flags
|
||||||
- `-L` for adding C library files search paths
|
- `-L` for adding C library files search paths
|
||||||
- `-D` for setting compile time variables
|
- `-D` for setting compile time variables
|
||||||
|
|
||||||
You can use different flags for different targets. Currently the `linux`, `darwin` , `freebsd`, and `windows` flags are supported.
|
You can use different flags for different targets.
|
||||||
|
Currently the `linux`, `darwin` , `freebsd`, and `windows` flags are supported.
|
||||||
|
|
||||||
NB: Each flag must go on its own line (for now)
|
NB: Each flag must go on its own line (for now)
|
||||||
|
|
||||||
|
@ -2379,7 +2410,9 @@ NB: Each flag must go on its own line (for now)
|
||||||
|
|
||||||
### Including C code
|
### Including C code
|
||||||
|
|
||||||
You can also include C code directly in your V module. For example, let's say that your C code is located in a folder named 'c' inside your module folder. Then:
|
You can also include C code directly in your V module.
|
||||||
|
For example, let's say that your C code is located in a folder named 'c' inside your module folder.
|
||||||
|
Then:
|
||||||
|
|
||||||
* Put a v.mod file inside the toplevel folder of your module (if you
|
* Put a v.mod file inside the toplevel folder of your module (if you
|
||||||
created your module with `v new` you already have v.mod file). For
|
created your module with `v new` you already have v.mod file). For
|
||||||
|
@ -2401,11 +2434,13 @@ Module {
|
||||||
#include "header.h"
|
#include "header.h"
|
||||||
```
|
```
|
||||||
NB: @VROOT will be replaced by V with the *nearest parent folder, where there is a v.mod file*.
|
NB: @VROOT will be replaced by V with the *nearest parent folder, where there is a v.mod file*.
|
||||||
Any .v file beside or below the folder where the v.mod file is, can use `#flag @VROOT/abc` to refer to this folder.
|
Any .v file beside or below the folder where the v.mod file is,
|
||||||
The @VROOT folder is also *prepended* to the module lookup path, so you can *import* other
|
can use `#flag @VROOT/abc` to refer to this folder.
|
||||||
modules under your @VROOT, by just naming them.
|
The @VROOT folder is also *prepended* to the module lookup path,
|
||||||
|
so you can *import* other modules under your @VROOT, by just naming them.
|
||||||
|
|
||||||
The instructions above will make V look for an compiled .o file in your module `folder/c/implementation.o`.
|
The instructions above will make V look for an compiled .o file in
|
||||||
|
your module `folder/c/implementation.o`.
|
||||||
If V finds it, the .o file will get linked to the main executable, that used the module.
|
If V finds it, the .o file will get linked to the main executable, that used the module.
|
||||||
If it does not find it, V assumes that there is a `@VROOT/c/implementation.c` file,
|
If it does not find it, V assumes that there is a `@VROOT/c/implementation.c` file,
|
||||||
and tries to compile it to a .o file, then will use that.
|
and tries to compile it to a .o file, then will use that.
|
||||||
|
@ -2416,15 +2451,19 @@ You can see a complete minimal example for using C code in a V wrapper module he
|
||||||
Another example, demonstrating passing structs from C to V and back again:
|
Another example, demonstrating passing structs from C to V and back again:
|
||||||
[interoperate between C to V to C](https://github.com/vlang/v/tree/master/vlib/v/tests/project_with_c_code_2).
|
[interoperate between C to V to C](https://github.com/vlang/v/tree/master/vlib/v/tests/project_with_c_code_2).
|
||||||
|
|
||||||
You can use `-cflags` to pass custom flags to the backend C compiler. You can also use `-cc` to change the default C backend compiler.
|
You can use `-cflags` to pass custom flags to the backend C compiler.
|
||||||
|
You can also use `-cc` to change the default C backend compiler.
|
||||||
For example: `-cc gcc-9 -cflags -fsanitize=thread`.
|
For example: `-cc gcc-9 -cflags -fsanitize=thread`.
|
||||||
|
|
||||||
### C types
|
### C types
|
||||||
|
|
||||||
Ordinary zero terminated C strings can be converted to V strings with `string(cstring)` or `string(cstring, len)`.
|
Ordinary zero terminated C strings can be converted to V strings with `string(cstring)`
|
||||||
|
or `string(cstring, len)`.
|
||||||
|
|
||||||
NB: Each `string(...)` function does NOT create a copy of the `cstring`, so you should NOT free it after calling `string()`. If you need to make a copy of the C string (some libc APIs like `getenv` pretty much require that, since they
|
NB: Each `string(...)` function does NOT create a copy of the `cstring`,
|
||||||
return pointers to internal libc memory), you can use `cstring_to_vstring(cstring)`.
|
so you should NOT free it after calling `string()`.
|
||||||
|
If you need to make a copy of the C string (some libc APIs like `getenv` pretty much require that,
|
||||||
|
since they return pointers to internal libc memory), you can use `cstring_to_vstring(cstring)`.
|
||||||
|
|
||||||
On Windows, C APIs often return so called `wide` strings (utf16 encoding).
|
On Windows, C APIs often return so called `wide` strings (utf16 encoding).
|
||||||
These can be converted to V strings with `string_from_wide(&u16(cwidestring))` .
|
These can be converted to V strings with `string_from_wide(&u16(cwidestring))` .
|
||||||
|
@ -2449,13 +2488,19 @@ To debug issues in the generated C code, you can pass these flags:
|
||||||
- `-cg` - produces a less optimized executable with more debug information in it.
|
- `-cg` - produces a less optimized executable with more debug information in it.
|
||||||
- `-showcc` - prints the C command that is used to build the program.
|
- `-showcc` - prints the C command that is used to build the program.
|
||||||
|
|
||||||
For the best debugging experience, you can pass all of them at the same time: `v -cg -showcc yourprogram.v` , then just run your debugger (gdb/lldb) or IDE on the produced executable `yourprogram`.
|
For the best debugging experience, you can pass all of them at the same time:
|
||||||
|
`v -cg -showcc yourprogram.v`,
|
||||||
|
then just run your debugger (gdb/lldb) or IDE on the produced executable `yourprogram`.
|
||||||
|
|
||||||
If you just want to inspect the generated C code, without further compilation, you can also use the `-o` flag (e.g. `-o file.c`). This will make V produce the `file.c` then stop.
|
If you just want to inspect the generated C code,
|
||||||
|
without further compilation, you can also use the `-o` flag (e.g. `-o file.c`).
|
||||||
|
This will make V produce the `file.c` then stop.
|
||||||
|
|
||||||
If you want to see the generated C source code for *just* a single C function, for example `main`, you can use: `-printfn main -o file.c` .
|
If you want to see the generated C source code for *just* a single C function,
|
||||||
|
for example `main`, you can use: `-printfn main -o file.c`.
|
||||||
|
|
||||||
To see a detailed list of all flags that V supports, use `v help`, `v help build`, `v help build-c` .
|
To see a detailed list of all flags that V supports,
|
||||||
|
use `v help`, `v help build` and `v help build-c`.
|
||||||
|
|
||||||
## Conditional compilation
|
## Conditional compilation
|
||||||
|
|
||||||
|
@ -2513,7 +2558,8 @@ Full list of builtin options:
|
||||||
|
|
||||||
## Compile time pseudo variables
|
## Compile time pseudo variables
|
||||||
|
|
||||||
V also gives your code access to a set of pseudo string variables, that are substituted at compile time:
|
V also gives your code access to a set of pseudo string variables,
|
||||||
|
that are substituted at compile time:
|
||||||
|
|
||||||
- `@FN` => replaced with the name of the current V function
|
- `@FN` => replaced with the name of the current V function
|
||||||
- `@MOD` => replaced with the name of the current V module
|
- `@MOD` => replaced with the name of the current V module
|
||||||
|
@ -2641,9 +2687,9 @@ fn main() {
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Operator overloading goes against V's philosophy of simplicity and predictability. But since
|
Operator overloading goes against V's philosophy of simplicity and predictability.
|
||||||
scientific and graphical applications are among V's domains, operator overloading is an important feature to have
|
But since scientific and graphical applications are among V's domains,
|
||||||
in order to improve readability:
|
operator overloading is an important feature to have in order to improve readability:
|
||||||
|
|
||||||
`a.add(b).add(c.mul(d))` is a lot less readable than `a + b + c * d`.
|
`a.add(b).add(c.mul(d))` is a lot less readable than `a + b + c * d`.
|
||||||
|
|
||||||
|
@ -2705,11 +2751,13 @@ An online C/C++ to V translator is coming soon.
|
||||||
|
|
||||||
When should you translate C code and when should you simply call C code from V?
|
When should you translate C code and when should you simply call C code from V?
|
||||||
|
|
||||||
If you have well-written, well-tested C code, then of course you can always simply call this C code from V.
|
If you have well-written, well-tested C code,
|
||||||
|
then of course you can always simply call this C code from V.
|
||||||
|
|
||||||
Translating it to V gives you several advantages:
|
Translating it to V gives you several advantages:
|
||||||
|
|
||||||
- If you plan to develop that code base, you now have everything in one language, which is much safer and easier to develop in than C.
|
- If you plan to develop that code base, you now have everything in one language,
|
||||||
|
which is much safer and easier to develop in than C.
|
||||||
- Cross-compilation becomes a lot easier. You don't have to worry about it at all.
|
- Cross-compilation becomes a lot easier. You don't have to worry about it at all.
|
||||||
- No more build flags and include files either.
|
- No more build flags and include files either.
|
||||||
|
|
||||||
|
@ -2812,7 +2860,8 @@ On Unix-like platforms, the file can be run directly after making it executable
|
||||||
|
|
||||||
V has several attributes that modify the behavior of functions and structs.
|
V has several attributes that modify the behavior of functions and structs.
|
||||||
|
|
||||||
An attribute is specified inside `[]` right before a function/struct declaration and applies only to the following declaration.
|
An attribute is specified inside `[]` right before a function/struct declaration
|
||||||
|
and applies only to the following declaration.
|
||||||
|
|
||||||
```v
|
```v
|
||||||
// Calling this function will result in a deprecation warning
|
// Calling this function will result in a deprecation warning
|
||||||
|
|
Loading…
Reference in New Issue