ci: separate workflow for docs line len check (#6653)
parent
5c93f942be
commit
d881185d79
|
@ -1,7 +1,16 @@
|
|||
name: CI
|
||||
on: [push, pull_request]
|
||||
jobs:
|
||||
|
||||
on:
|
||||
push:
|
||||
paths-ignore:
|
||||
- "doc/**"
|
||||
- "CHANGELOG.md"
|
||||
pull_request:
|
||||
paths-ignore:
|
||||
- "doc/**"
|
||||
- "CHANGELOG.md"
|
||||
|
||||
jobs:
|
||||
code-formatting:
|
||||
runs-on: ubuntu-18.04
|
||||
env:
|
||||
|
@ -461,15 +470,6 @@ jobs:
|
|||
# - name: v2 self compilation
|
||||
# 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:
|
||||
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
|
||||
*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.
|
||||
- `strconv`, `sprintf`, and `printf` in native V, without any libc calls.
|
||||
- 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 `is` keyword for checking the type of sum types and interfaces.
|
||||
- `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:
|
||||
number of calls, average time per call, total time per function.
|
||||
- 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
|
||||
- `import(xxx)` syntax has been removed in favor of `import xxx` for simplicity and greppability.
|
||||
- Lots of fixes and improvements in the type checker.
|
||||
- `time.StopWatch`
|
||||
- `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)`.
|
||||
- New operator `!in`.
|
||||
- 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
|
||||
*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
|
||||
*31 Dec 2019*
|
||||
|
||||
- A new parser/generator built on top of an AST that simplifies code greatly and allows to implement new
|
||||
backends much faster.
|
||||
- A new parser/generator built on top of an AST that simplifies code greatly
|
||||
and allows to implement new backends much faster.
|
||||
- Sum types (`type Expr = IfExpr | MatchExpr | IntegerLiteral`).
|
||||
- B-tree map (sped up the V compiler by ~10%).
|
||||
- `v fmt -w`.
|
||||
|
@ -54,7 +57,7 @@ number of calls, average time per call, total time per function.
|
|||
- os: `is_link()`, `is_dir()`, `exists()`.
|
||||
- Ranging through fixed size arrays.
|
||||
- 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.
|
||||
- freestanding: `malloc()`/`free()`.
|
||||
- `++` 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
|
||||
*30 Nov 2019*
|
||||
|
||||
- [Direct x64 machine code generation](https://github.com/vlang/v/issues/2849). Hello world being built in 3 milliseconds.
|
||||
- Bare metal support via the `-freestanding` flag, allowing to build programs without linking to libc.
|
||||
- [Direct x64 machine code generation](https://github.com/vlang/v/issues/2849).
|
||||
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.
|
||||
- `string.index()` now returns `?int` instead of `int/-1`.
|
||||
- Lots of fixes in Generics.
|
||||
- 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.
|
||||
- V now enforces short enum syntax (`.green` instead of `Color.green`) when it's enough.
|
||||
- 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.
|
||||
- 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.
|
||||
- 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).
|
||||
- `<<` and `>>` now work with all integer types.
|
||||
- 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.
|
||||
- `utf8` helper functions (`to_lower()`, `to_upper()`, etc).
|
||||
- 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()`.
|
||||
- `sqlite` module.
|
||||
- Cached modules for faster compilation.
|
||||
- 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).
|
||||
- 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)
|
||||
- V scripts (simpler and cross-platform alternative to Bash).
|
||||
- Infinite multi-dimensional arrays (`[][][]int`).
|
||||
- `unsafe`.
|
||||
|
@ -296,7 +300,7 @@ this backend.
|
|||
## V 0.1.15
|
||||
*15 Jul 2019*
|
||||
- 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.
|
||||
- `defer` statement.
|
||||
- map.v was re-written. It's now much faster.
|
||||
|
@ -310,7 +314,7 @@ this backend.
|
|||
## V 0.1.14
|
||||
*12 Jul 2019*
|
||||
- `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).
|
||||
- `type` aliases can now have methods.
|
||||
- Const overflow check during compilation (`byte(1000)` will no longer compile).
|
||||
|
@ -332,8 +336,10 @@ this backend.
|
|||
## V 0.1.12
|
||||
*4 Jul 2019*
|
||||
- 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.
|
||||
- `println` was optimized. It no longer results in allocations. Now it also works correctly with all integer types.
|
||||
- `os` module now uses optionals in all functions that return `File`.
|
||||
- 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.
|
||||
- New `strings` module.
|
||||
- Lots of other fixes and improvements, thanks to all the contributors.
|
||||
|
|
|
@ -8,23 +8,36 @@ const (
|
|||
|
||||
fn main() {
|
||||
files_paths := os.args[1..]
|
||||
mut warnings := 0
|
||||
mut errors := 0
|
||||
for file_path in files_paths {
|
||||
real_path := os.real_path(file_path)
|
||||
lines := os.read_lines(real_path) or {
|
||||
println('"$file_path" does not exist')
|
||||
warnings++
|
||||
continue
|
||||
}
|
||||
for i, line in lines {
|
||||
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++
|
||||
}
|
||||
}
|
||||
}
|
||||
// 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 {
|
||||
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
|
||||
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.
|
||||
|
||||
|
@ -281,8 +282,10 @@ fn main() {
|
|||
|
||||
### 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 production mode (enabled by passing the `-prod` flag to v – `v -prod foo.v`) it will not compile at all (like in Go).
|
||||
In development mode the compiler will warn you that you haven't used the variable
|
||||
(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
|
||||
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
|
||||
|
||||
|
@ -393,8 +397,9 @@ println('Hello, $name!') // Hello, Bob!
|
|||
It also works with fields: `'age = $user.age'`.
|
||||
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
|
||||
and specify the output format. The compiler takes care of the storage size, so there is no `hd` or `llu`.
|
||||
Format specifiers similar to those in C's `printf()` are also supported.
|
||||
`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
|
||||
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`).
|
||||
* `['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]`.
|
||||
V arrays are homogeneous (all elements must have the same type). This means that code like `[1, 'a']` will not compile.
|
||||
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]`.
|
||||
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,
|
||||
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]`
|
||||
```
|
||||
|
||||
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
|
||||
mut numbers := []int{ cap: 1000 }
|
||||
|
@ -731,7 +739,8 @@ if a < b {
|
|||
```
|
||||
|
||||
`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:
|
||||
|
||||
|
@ -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.
|
||||
```v
|
||||
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)
|
||||
}
|
||||
```
|
||||
|
@ -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
|
||||
|
||||
|
@ -819,7 +830,8 @@ for i, name in names {
|
|||
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.
|
||||
|
||||
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
|
||||
mut numbers := [0, 1, 2]
|
||||
|
@ -982,7 +994,8 @@ Note: `match` as an expression is not usable in `for` loop and `if` statements.
|
|||
|
||||
### 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
|
||||
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.
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -1190,11 +1205,11 @@ but a short, preferably one letter long, name.
|
|||
|
||||
### Pure functions by default
|
||||
|
||||
V functions are pure by default, meaning that their return values are a function of their arguments only,
|
||||
and their evaluation has no side effects (besides I/O).
|
||||
V functions are pure by default, meaning that their return values are a function of their
|
||||
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,
|
||||
even when [references](#references) are passed.
|
||||
This is achieved by a lack of global variables and all function arguments being
|
||||
immutable by default, even when [references](#references) are passed.
|
||||
|
||||
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
|
||||
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)`
|
||||
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
|
||||
|
||||
|
@ -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;
|
||||
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,
|
||||
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,
|
||||
or use a control flow statement (`return`, `break`, `continue`, etc) to break from the current block.
|
||||
Here, you can either call `panic()` or `exit()`, which will stop the execution of the
|
||||
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.
|
||||
|
||||
V does not have a way to forcibly "unwrap" an optional (as other languages do, for instance Rust's `unwrap()`
|
||||
or Swift's `!`). To do this, use `or { panic(err) }` instead.
|
||||
V does not have a way to forcibly "unwrap" an optional (as other languages do,
|
||||
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,
|
||||
that value would be assigned instead, so it must have the same type as the content of the `Option` being handled.
|
||||
The third method is to provide a default value at the end of the `or` block.
|
||||
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
|
||||
fn do_something(s string) ?string {
|
||||
|
@ -1911,8 +1931,9 @@ y := <-ch2 ?
|
|||
|
||||
#### Channel Select
|
||||
|
||||
The `select` command allows monitoring several channels at the same time without noticeable CPU load. It consists
|
||||
of a list of possible transfers and associated branches of statements - similar to the [match](#match) command:
|
||||
The `select` command allows monitoring several channels at the same time
|
||||
without noticeable CPU load. It consists of a list of possible transfers and associated branches
|
||||
of statements - similar to the [match](#match) command:
|
||||
```v
|
||||
select {
|
||||
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
|
||||
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
|
||||
if select {
|
||||
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
|
||||
c := ch.cap // maximum queue length
|
||||
```
|
||||
The `try_push/pop()` methods will return immediately with one of the results `.success`, `.not_ready`
|
||||
or `.closed` - dependent on whether the object has been transferred or the reason why not. Usage
|
||||
of these methods and properties in production is not recommended - algorithms based on them are often subject
|
||||
to race conditions. Use `select` instead.
|
||||
The `try_push/pop()` methods will return immediately with one of the results
|
||||
`.success`, `.not_ready` or `.closed` - dependent on whether the object has been transferred or
|
||||
the reason why not.
|
||||
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
|
||||
and the calling thread via a shared variable. This variable should be created as reference and passed to
|
||||
the coroutine as `mut`. The underlying `struct` should also contain a `mutex` to lock concurrent access:
|
||||
Data can be exchanged between a coroutine and the calling thread via a shared variable.
|
||||
This variable should be created as reference and passed to the coroutine as `mut`.
|
||||
The underlying `struct` should also contain a `mutex` to lock concurrent access:
|
||||
|
||||
```v
|
||||
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.
|
||||
|
||||
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
|
||||
performance.
|
||||
V generates code for JSON encoding and decoding.
|
||||
No runtime reflection is used. This results in much better performance.
|
||||
|
||||
## Testing
|
||||
|
||||
|
@ -2153,7 +2178,8 @@ fn test() []int {
|
|||
|
||||
(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:
|
||||
|
||||
|
@ -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.)
|
||||
- Safety. (All queries are automatically sanitised to prevent SQL injection.)
|
||||
- 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
|
||||
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
|
||||
|
||||
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:
|
||||
|
||||
|
@ -2335,8 +2363,10 @@ fn my_callback(arg voidptr, howmany int, cvalues &charptr, cnames &charptr) int
|
|||
|
||||
fn main() {
|
||||
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
|
||||
// C.sqlite3_open(db_path.str, &db) // you can also use `.str byteptr` field to convert a V string to a C char pointer
|
||||
// passing a string literal to a C function call results in a C string, not a V string
|
||||
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'
|
||||
stmt := &C.sqlite3_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
|
||||
- `-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)
|
||||
|
||||
|
@ -2379,7 +2410,9 @@ NB: Each flag must go on its own line (for now)
|
|||
|
||||
### 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
|
||||
created your module with `v new` you already have v.mod file). For
|
||||
|
@ -2401,11 +2434,13 @@ Module {
|
|||
#include "header.h"
|
||||
```
|
||||
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.
|
||||
The @VROOT folder is also *prepended* to the module lookup path, so you can *import* other
|
||||
modules under your @VROOT, by just naming them.
|
||||
Any .v file beside or below the folder where the v.mod file is,
|
||||
can use `#flag @VROOT/abc` to refer to this folder.
|
||||
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 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.
|
||||
|
@ -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:
|
||||
[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`.
|
||||
|
||||
### 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
|
||||
return pointers to internal libc memory), you can use `cstring_to_vstring(cstring)`.
|
||||
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 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).
|
||||
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.
|
||||
- `-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
|
||||
|
||||
|
@ -2513,7 +2558,8 @@ Full list of builtin options:
|
|||
|
||||
## 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
|
||||
- `@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
|
||||
scientific and graphical applications are among V's domains, operator overloading is an important feature to have
|
||||
in order to improve readability:
|
||||
Operator overloading goes against V's philosophy of simplicity and predictability.
|
||||
But since scientific and graphical applications are among V's domains,
|
||||
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`.
|
||||
|
||||
|
@ -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?
|
||||
|
||||
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:
|
||||
|
||||
- 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.
|
||||
- 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.
|
||||
|
||||
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
|
||||
// Calling this function will result in a deprecation warning
|
||||
|
|
Loading…
Reference in New Issue