mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
docs: unify format of notes (#17294)
This commit is contained in:
parent
e7fcf66095
commit
c8c70de87d
@ -24,55 +24,55 @@ The architecture of the compiler is very simple and has three distinct steps:
|
||||
Parse/generate AST (`v.parser`) => Check types (`v.checker`)
|
||||
=> Generate C/JavaScript/machine code (`v.gen`)
|
||||
|
||||
|
||||
The main files are:
|
||||
|
||||
1. `cmd/v/v.v` The entry point.
|
||||
|
||||
- V figures out the build mode.
|
||||
- Constructs the compiler object (`struct V`).
|
||||
- Creates a list of .v files that need to be parsed.
|
||||
- Creates a parser object for each file and runs `parse()` on them.
|
||||
- The correct backend is called (C, JS, native), and a binary is compiled.
|
||||
- V figures out the build mode.
|
||||
- Constructs the compiler object (`struct V`).
|
||||
- Creates a list of .v files that need to be parsed.
|
||||
- Creates a parser object for each file and runs `parse()` on them.
|
||||
- The correct backend is called (C, JS, native), and a binary is compiled.
|
||||
|
||||
2. `vlib/v/scanner` The scanner's job is to parse a list of characters and convert
|
||||
them to tokens.
|
||||
them to tokens.
|
||||
|
||||
3. `vlib/v/token` This is simply a list of all tokens, their string values, and a
|
||||
couple of helper functions.
|
||||
couple of helper functions.
|
||||
|
||||
4. `vlib/v/parser` The parser. It converts a list of tokens into an AST.
|
||||
In V, objects can be used before declaration, so unknown types are marked as
|
||||
unresolved. They are resolved later in the type checker.
|
||||
In V, objects can be used before declaration, so unknown types are marked as
|
||||
unresolved. They are resolved later in the type checker.
|
||||
|
||||
5. `vlib/v/table` V creates one table object that is shared by all parsers. It
|
||||
contains all types, consts, and functions, as well as several helpers to search
|
||||
for objects by name, register new objects, modify types' fields, etc.
|
||||
contains all types, consts, and functions, as well as several helpers to search
|
||||
for objects by name, register new objects, modify types' fields, etc.
|
||||
|
||||
6. `vlib/v/checker` Type checker and resolver. It processes the AST and makes sure
|
||||
the types are correct. Unresolved types are resolved, type information is added
|
||||
to the AST.
|
||||
the types are correct. Unresolved types are resolved, type information is added
|
||||
to the AST.
|
||||
|
||||
7. `vlib/v/gen/c` C backend. It simply walks the AST and generates C code that can be
|
||||
compiled with Clang, GCC, Visual Studio, and TCC.
|
||||
compiled with Clang, GCC, Visual Studio, and TCC.
|
||||
|
||||
8. `vlib/v/gen/js` JavaScript backend. It simply walks the AST and generates JS code that can be
|
||||
executed on the browser or in NodeJS/Deno.
|
||||
executed on the browser or in NodeJS/Deno.
|
||||
|
||||
9. `vlib/v/gen/c/json.v` defines the json code generation. This file will be removed once V
|
||||
supports comptime code generation, and it will be possible to do this using the
|
||||
language's tools.
|
||||
supports comptime code generation, and it will be possible to do this using the
|
||||
language's tools.
|
||||
|
||||
10. `vlib/v/gen/native` is the directory with all the machine code generation logic. It
|
||||
defines a set of functions that translate assembly instructions to machine code
|
||||
and build the binary from scratch byte by byte. It manually builds all headers,
|
||||
segments, sections, symtable, relocations, etc. Right now it only has basic
|
||||
support of the native platform (ELF, MACHO format).
|
||||
defines a set of functions that translate assembly instructions to machine code
|
||||
and build the binary from scratch byte by byte. It manually builds all headers,
|
||||
segments, sections, symtable, relocations, etc. Right now it only has basic
|
||||
support of the native platform (ELF, MACHO format).
|
||||
|
||||
The rest of the directories are vlib modules: `builtin/` (strings, arrays,
|
||||
maps), `time/`, `os/`, etc. Their documentation is pretty clear.
|
||||
|
||||
## Example Workflow for Contributing
|
||||
|
||||
(provided by [@spytheman](https://github.com/spytheman))
|
||||
|
||||
(If you don't already have a GitHub account, please create one. Your GitHub
|
||||
@ -80,13 +80,14 @@ username will be referred to later as 'YOUR_GITHUB_USERNAME'. Change it
|
||||
accordingly in the steps below.)
|
||||
|
||||
1. Fork https://github.com/vlang/v using GitHub's interface to your own account.
|
||||
Let's say that the forked repository is at
|
||||
`https://github.com/YOUR_GITHUB_USERNAME/v` .
|
||||
Let's say that the forked repository is at
|
||||
`https://github.com/YOUR_GITHUB_USERNAME/v` .
|
||||
2. Clone the main v repository https://github.com/vlang/v to a local folder on
|
||||
your computer, say named nv/ (`git clone https://github.com/vlang/v nv`)
|
||||
your computer, say named nv/ (`git clone https://github.com/vlang/v nv`)
|
||||
3. `cd nv`
|
||||
4. `git remote add pullrequest https://github.com/YOUR_GITHUB_USERNAME/v`
|
||||
NB: the remote named `pullrequest` should point to YOUR own forked repo, not the
|
||||
|
||||
Note: The remote named `pullrequest` should point to YOUR own forked repo, not the
|
||||
main v repository! After this, your local cloned repository is prepared for
|
||||
making pullrequests, and you can just do normal git operations such as:
|
||||
`git pull` `git status` and so on.
|
||||
@ -94,7 +95,7 @@ making pullrequests, and you can just do normal git operations such as:
|
||||
5. When finished with a feature/bugfix/change, you can:
|
||||
`git checkout -b fix_alabala`
|
||||
- Don't forget to keep formatting standards, run `v fmt -w YOUR_MODIFIED_FILES` before committing
|
||||
6. `git push pullrequest` # (NOTE: the `pullrequest` remote was setup on step 4)
|
||||
6. `git push pullrequest` Note: The `pullrequest` remote was setup on step 4
|
||||
7. On GitHub's web interface, go to: https://github.com/vlang/v/pulls
|
||||
|
||||
Here the UI shows a dialog with a button to make a new pull request based on
|
||||
@ -102,11 +103,11 @@ making pullrequests, and you can just do normal git operations such as:
|
||||
(Example dialog: https://url4e.com/gyazo/images/364edc04.png)
|
||||
|
||||
8. After making your pullrequest (aka, PR), you can continue to work on the
|
||||
branch `fix_alabala` ... just do again `git push pullrequest` when you have more
|
||||
commits.
|
||||
branch `fix_alabala` ... just do again `git push pullrequest` when you have more
|
||||
commits.
|
||||
|
||||
9. If there are merge conflicts, or a branch lags too much behind V's master,
|
||||
you can do the following:
|
||||
you can do the following:
|
||||
|
||||
1. `git pull --rebase origin master` # solve conflicts and do
|
||||
`git rebase --continue`
|
||||
@ -120,7 +121,8 @@ main V repository's master, then `git checkout master`, as well as
|
||||
(these are actually used by `v up`) and git can always do it cleanly.
|
||||
|
||||
Git is very flexible, so there are other ways to accomplish the same thing.
|
||||
See the [GitHub flow](https://guides.github.com/introduction/git-handbook/#github), for more information.
|
||||
See the [GitHub flow](https://guides.github.com/introduction/git-handbook/#github), for more
|
||||
information.
|
||||
|
||||
## Using Github's hub CLI tool
|
||||
|
||||
@ -129,9 +131,11 @@ You can download the `hub` tool from https://hub.github.com/ . Using
|
||||
to make PRs. Most remote operations can be done through the `hub` CLI
|
||||
command.
|
||||
|
||||
NB: You still need to have a GitHub account.
|
||||
> **Note**
|
||||
> You still need to have a GitHub account.
|
||||
|
||||
### Preparation:
|
||||
|
||||
(steps 1..3 need to be done just *once*):
|
||||
|
||||
1. `hub clone vlang/v my_v`
|
||||
@ -139,13 +143,14 @@ NB: You still need to have a GitHub account.
|
||||
3. `hub fork --remote-name pullrequest`
|
||||
|
||||
4. `git checkout -b my_cool_feature` # Step 4 is better done *once per each new
|
||||
feature/bugfix* that you make.
|
||||
feature/bugfix* that you make.
|
||||
|
||||
### Improve V by making commits:
|
||||
|
||||
5. `git commit -am "math: add a new function copysign"`
|
||||
|
||||
### Testing your commits locally:
|
||||
|
||||
You can test locally whether your changes have not broken something by
|
||||
running: `v test-all`. See `TESTS.md` for more details.
|
||||
|
||||
@ -154,6 +159,7 @@ running: `v test-all`. See `TESTS.md` for more details.
|
||||
6. `git push pullrequest`
|
||||
|
||||
### Making a PR with `hub`:
|
||||
|
||||
(so that your changes can be merged to the main V repository)
|
||||
|
||||
7. `hub pull-request`
|
||||
@ -163,6 +169,7 @@ Optionally, you can track the status of your PR CI tests with:
|
||||
8. `hub ci-status --verbose`
|
||||
|
||||
### Fixing failing tests:
|
||||
|
||||
If everything is OK, after 5-10 minutes, the CI tests should pass for
|
||||
all platforms. If not, visit the URLs for the failing CI jobs, see
|
||||
which tests have failed and then fix them by making more changes. Just use
|
||||
@ -186,7 +193,7 @@ Some flags can make the compiler very verbose, so it is recommended
|
||||
to create a copy of the compiler rather than replacing it with `v self`.
|
||||
|
||||
| Flag | Usage |
|
||||
|------|-------|
|
||||
|-----------------------------------|---------------------------------------------------------------------------------------------------------------------|
|
||||
| `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 |
|
||||
|
83
README.md
83
README.md
@ -19,9 +19,11 @@
|
||||
</div>
|
||||
|
||||
## Key Features of V
|
||||
|
||||
- Simplicity: the language can be learned in a weekend
|
||||
- Fast compilation: ≈110k loc/s with a Clang backend,
|
||||
≈500k loc/s with native and tcc backends *(Intel i5-7500, SSD, no optimization)* ([demo video](https://www.youtube.com/watch?v=pvP6wmcl_Sc))
|
||||
≈500k 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)
|
||||
- Safety: no null, no globals, no undefined behavior, immutability by default
|
||||
@ -38,6 +40,7 @@
|
||||
- Great for writing low-level software ([Vinix OS](https://github.com/vlang/vinix))
|
||||
|
||||
## Stability guarantee and future changes
|
||||
|
||||
Despite being at an early development stage, the V language is relatively stable and has
|
||||
backwards compatibility guarantee, meaning that the code you write today is guaranteed
|
||||
to work a month, a year, or five years from now.
|
||||
@ -58,10 +61,12 @@ language, very similar to the way it is right now.
|
||||
--> **_(this is the preferred method)_**
|
||||
|
||||
### Linux, macOS, Windows, *BSD, Solaris, WSL, etc.
|
||||
|
||||
Usually installing V is quite simple if you have an environment that already has a
|
||||
functional `git` installation.
|
||||
|
||||
To get started, simply try to execute the following in your terminal/shell:
|
||||
|
||||
```bash
|
||||
git clone https://github.com/vlang/v
|
||||
cd v
|
||||
@ -77,7 +82,8 @@ That should be it and you should find your V executable at `[path to V repo]/v`.
|
||||
Now you can try `./v run examples/hello_world.v` (or `v run examples/hello_world.v` in cmd shell).
|
||||
|
||||
* *Trouble? Please see the note above and link to
|
||||
[Installation Issues](https://github.com/vlang/v/discussions/categories/installation-issues) for help.*
|
||||
[Installation Issues](https://github.com/vlang/v/discussions/categories/installation-issues)
|
||||
for help.*
|
||||
|
||||
V is constantly being updated. To update V, simply run:
|
||||
|
||||
@ -85,14 +91,17 @@ V is constantly being updated. To update V, simply run:
|
||||
v up
|
||||
```
|
||||
|
||||
* *(* ***NOTE:*** *If you run into any trouble, or you have a different operating
|
||||
system or Linux distribution that doesn't install or work immediately, please see
|
||||
[Installation Issues](https://github.com/vlang/v/discussions/categories/installation-issues)
|
||||
and search for your OS and problem. If you can't find your problem, please add it to an
|
||||
existing discussion if one exists for your OS, or create a new one if a main discussion
|
||||
doesn't yet exist for your OS.)*
|
||||
> **Note**
|
||||
> If you run into any trouble, or you have a different operating
|
||||
> system or Linux distribution that doesn't install or work immediately, please see
|
||||
> [Installation Issues](https://github.com/vlang/v/discussions/categories/installation-issues)
|
||||
> and search for your OS and problem.
|
||||
>
|
||||
> If you can't find your problem, please add it to an existing discussion if one exists for
|
||||
> your OS, or create a new one if a main discussion doesn't yet exist for your OS.
|
||||
|
||||
### C compiler
|
||||
|
||||
The [Tiny C Compiler (tcc)](https://repo.or.cz/w/tinycc.git) is downloaded for you by `make` if
|
||||
there is a compatible version for your system, and installed under the V `thirdparty` directory.
|
||||
|
||||
@ -109,9 +118,11 @@ Otherwise, follow these instructions:
|
||||
- [Installing a C compiler on Windows](https://github.com/vlang/v/wiki/Installing-a-C-compiler-on-Windows)
|
||||
|
||||
### Symlinking
|
||||
NB: it is *highly recommended*, that you put V on your PATH. That saves
|
||||
you the effort to type in the full path to your v executable every time.
|
||||
V provides a convenience `v symlink` command to do that more easily.
|
||||
|
||||
> **Note**
|
||||
> It is *highly recommended*, that you put V on your PATH. That saves
|
||||
> you the effort to type in the full path to your v executable every time.
|
||||
> V provides a convenience `v symlink` command to do that more easily.
|
||||
|
||||
On Unix systems, it creates a `/usr/local/bin/v` symlink to your
|
||||
executable. To do that, run:
|
||||
@ -128,17 +139,19 @@ type:
|
||||
```bat
|
||||
v symlink
|
||||
```
|
||||
|
||||
(or `./v symlink` in PowerShell)
|
||||
|
||||
That will make V available everywhere, by adding it to your PATH. Please restart your
|
||||
shell/editor after that, so that it can pick up the new PATH variable.
|
||||
|
||||
NB: there is no need to run `v symlink` more than once - v will still 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.
|
||||
|
||||
> **Note**
|
||||
> There is no need to run `v symlink` more than once - v will still 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.
|
||||
|
||||
### Void Linux
|
||||
|
||||
<details><summary>Expand Void Linux instructions</summary>
|
||||
|
||||
```bash
|
||||
@ -148,10 +161,11 @@ $ git clone https://github.com/vlang/v
|
||||
$ cd v
|
||||
$ make
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
|
||||
### Docker
|
||||
|
||||
<details><summary>Expand Docker instructions</summary>
|
||||
|
||||
```bash
|
||||
@ -160,19 +174,24 @@ cd v
|
||||
docker build -t vlang .
|
||||
docker run --rm -it vlang:latest
|
||||
```
|
||||
|
||||
### Docker with Alpine/musl
|
||||
|
||||
```bash
|
||||
git clone https://github.com/vlang/v
|
||||
cd v
|
||||
docker build -t vlang --file=Dockerfile.alpine .
|
||||
docker run --rm -it vlang:latest
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
### Termux/Android
|
||||
|
||||
On Termux, V needs some packages preinstalled - a working C compiler, also `libexecinfo`,
|
||||
`libgc` and `libgc-static`. After installing them, you can use the same script, like on
|
||||
Linux/macos:
|
||||
|
||||
```bash
|
||||
pkg install clang libexecinfo libgc libgc-static make git
|
||||
git clone https://github.com/vlang/v
|
||||
@ -181,7 +200,9 @@ make
|
||||
```
|
||||
|
||||
## Testing and running the examples
|
||||
|
||||
Make sure V can compile itself:
|
||||
|
||||
```bash
|
||||
$ v self
|
||||
$ v
|
||||
@ -192,6 +213,7 @@ Use Ctrl-C or `exit` to exit
|
||||
hello world
|
||||
>>>
|
||||
```
|
||||
|
||||
```bash
|
||||
cd examples
|
||||
v hello_world.v && ./hello_world # or simply
|
||||
@ -201,9 +223,10 @@ v run word_counter/word_counter.v word_counter/cinderella.txt
|
||||
v run news_fetcher.v
|
||||
v run tetris/tetris.v
|
||||
```
|
||||
|
||||
<img src='https://raw.githubusercontent.com/vlang/v/master/examples/tetris/screenshot.png' width=300 alt='tetris screenshot'>
|
||||
|
||||
NB: In order to build Tetris or 2048 (or anything else using `sokol` or `gg` graphics modules),
|
||||
In order to build Tetris or 2048 (or anything else using `sokol` or `gg` graphics modules),
|
||||
you will need additional development libraries for your system.
|
||||
For some Linux distros (Debian/Ubuntu based), you need to run this:
|
||||
`sudo apt install libxi-dev libxcursor-dev`.
|
||||
@ -213,6 +236,7 @@ For NixOS, add these packages to your `environment.systemPackages`:
|
||||
`xorg.libX11.dev xorg.libXcursor.dev xorg.libXi.dev libGL.dev`
|
||||
|
||||
## V net.http, net.websocket, `v install`
|
||||
|
||||
The net.http module, the net.websocket module, and the `v install` command may all use SSL.
|
||||
V comes with a version of mbedtls, which should work on all systems. If you find a need to
|
||||
use OpenSSL instead, you will need to make sure that it is installed on your system, then
|
||||
@ -238,9 +262,11 @@ On Windows, OpenSSL is simply hard to get working correctly. The instructions
|
||||
[here](https://tecadmin.net/install-openssl-on-windows/) may (or may not) help.
|
||||
|
||||
## V sync
|
||||
|
||||
V's `sync` module and channel implementation uses libatomic.
|
||||
It is most likely already installed on your system, but if not,
|
||||
you can install it, by doing the following:
|
||||
|
||||
```bash
|
||||
MacOS: already installed
|
||||
|
||||
@ -252,6 +278,7 @@ sudo dnf install libatomic-static
|
||||
```
|
||||
|
||||
## V UI
|
||||
|
||||
<a href="https://github.com/vlang/ui">
|
||||
<img src='https://raw.githubusercontent.com/vlang/ui/master/examples/screenshot.png' width=712 alt='V UI example screenshot'>
|
||||
</a>
|
||||
@ -280,15 +307,20 @@ Hello from V.js
|
||||
-->
|
||||
|
||||
## Android graphical apps
|
||||
|
||||
With V's `vab` tool, building V UI and graphical apps for Android can become as easy as:
|
||||
|
||||
```
|
||||
./vab /path/to/v/examples/2048
|
||||
```
|
||||
|
||||
[https://github.com/vlang/vab](https://github.com/vlang/vab).
|
||||
<img src="https://user-images.githubusercontent.com/768942/107622846-c13f3900-6c58-11eb-8a66-55db12979b73.png" alt="vab examples screenshot">
|
||||
|
||||
## Developing web applications
|
||||
Check out the [Building a simple web blog](https://github.com/vlang/v/blob/master/tutorials/building_a_simple_web_blog_with_vweb/README.md)
|
||||
|
||||
Check out the
|
||||
[Building a simple web blog](https://github.com/vlang/v/blob/master/tutorials/building_a_simple_web_blog_with_vweb/README.md)
|
||||
tutorial and Gitly, a light and fast alternative to GitHub/GitLab:
|
||||
|
||||
https://github.com/vlang/gitly
|
||||
@ -296,6 +328,7 @@ https://github.com/vlang/gitly
|
||||
<img src="https://user-images.githubusercontent.com/687996/85933714-b195fe80-b8da-11ea-9ddd-09cadc2103e4.png" alt="gitly screenshot">
|
||||
|
||||
## Vinix, an OS/kernel written in V
|
||||
|
||||
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.
|
||||
|
||||
@ -305,10 +338,20 @@ https://github.com/vlang/vinix
|
||||
<img src="https://github.com/vlang/vinix/blob/main/screenshot1.png?raw=true" alt="vinix screenshot 2">
|
||||
|
||||
## Acknowledgement
|
||||
V thanks Fabrice Bellard for his original work on the [TCC - Tiny C Compiler](https://bellard.org/tcc/). Note the TCC website is old; the current TCC repository can be found [here](https://repo.or.cz/w/tinycc.git). V utilizes pre-built TCC binaries located at [https://github.com/vlang/tccbin/](https://github.com/vlang/tccbin/).
|
||||
|
||||
V thanks Fabrice Bellard for his original work on the
|
||||
[TCC - Tiny C Compiler](https://bellard.org/tcc/).
|
||||
Note the TCC website is old; the current TCC repository can be found
|
||||
[here](https://repo.or.cz/w/tinycc.git).
|
||||
V utilizes pre-built TCC binaries located at
|
||||
[https://github.com/vlang/tccbin/](https://github.com/vlang/tccbin/).
|
||||
|
||||
## Troubleshooting
|
||||
Please see the [Troubleshooting](https://github.com/vlang/v/wiki/Troubleshooting) section on our [wiki page](https://github.com/vlang/v/wiki)
|
||||
|
||||
Please see the
|
||||
[Troubleshooting](https://github.com/vlang/v/wiki/Troubleshooting)
|
||||
section on our
|
||||
[wiki page](https://github.com/vlang/v/wiki)
|
||||
|
||||
[WorkflowBadge]: https://github.com/vlang/v/workflows/CI/badge.svg
|
||||
[DiscordBadge]: https://img.shields.io/discord/592103645835821068?label=Discord&logo=discord&logoColor=white
|
||||
|
@ -1,4 +1,5 @@
|
||||
## [Version 0.4]
|
||||
|
||||
- [ ] [Coroutines](https://github.com/vlang/v/discussions/11582)
|
||||
- [ ] [Thread safe maps](https://github.com/vlang/v/discussions/11729)
|
||||
- [ ] Parallel parser
|
||||
|
23
TESTS.md
23
TESTS.md
@ -14,6 +14,7 @@ Test and build *everything*. Usefull to verify *locally*, that the CI will
|
||||
most likely pass. Slowest, but most comprehensive.
|
||||
|
||||
It works, by running these in succession:
|
||||
|
||||
* `v test-cleancode`
|
||||
* `v test-self`
|
||||
* `v test-fmt`
|
||||
@ -23,9 +24,11 @@ It works, by running these in succession:
|
||||
* `v install nedpals.args`
|
||||
|
||||
# Details:
|
||||
|
||||
In the `v` repo there are many tests. The main types are:
|
||||
|
||||
## `_test.v` tests - these are the normal V test files.
|
||||
|
||||
All `test_` functions in these files, will be ran automatically by
|
||||
V's test framework.
|
||||
|
||||
@ -44,7 +47,6 @@ recursively.
|
||||
`v -stats test folder` - same, but will also produce timing reports
|
||||
about how fast each test_ function in each _test.v file ran.
|
||||
|
||||
|
||||
## `v test vlib/v/tests`:
|
||||
|
||||
This folder contains _test.v files, testing the different features of the V
|
||||
@ -58,8 +60,9 @@ matches an expected .out file. You can also check for code that does panic
|
||||
using this test runner - just paste the start of the `panic()` output in the
|
||||
corresponding .out file.
|
||||
|
||||
NB: these tests, expect to find a pair of `.vv` and `.out` files, in the folder:
|
||||
vlib/v/slow_tests/inout
|
||||
> **Note**
|
||||
> These tests, expect to find a pair of `.vv` and `.out` files, in the folder:
|
||||
> vlib/v/slow_tests/inout
|
||||
|
||||
The test runner will run each `.vv` file, and will check that its output, matches
|
||||
the contents of the `.out` file with the same base name. This is particularly useful
|
||||
@ -78,12 +81,15 @@ lines, *should* be present *at least once* in the output, when the .vv
|
||||
file is compiled with `-o -` .
|
||||
|
||||
## `v vlib/v/slow_tests/run_project_folders_test.v`
|
||||
|
||||
This *test runner*, checks whether whole project folders, can be compiled, and run.
|
||||
|
||||
NB: Each project in these folders, should finish with an exit code of 0,
|
||||
and it should output `OK` as its last stdout line.
|
||||
> **Note**
|
||||
> Each project in these folders, should finish with an exit code of 0,
|
||||
> and it should output `OK` as its last stdout line.
|
||||
|
||||
## `v vlib/v/tests/known_errors/known_errors_test.v`
|
||||
|
||||
This *test runner*, checks whether a known program, that was expected to compile,
|
||||
but did NOT, due to a buggy checker, parser or cgen, continues to fail.
|
||||
The negative programs are collected in the `vlib/v/tests/known_errors/testdata/` folder.
|
||||
@ -96,7 +102,6 @@ change/improvement. For example, code that triggers generating invalid C code ca
|
||||
and later when a bug is fixed, can be moved to a proper _test.v or .vv/.out pair, outside of
|
||||
the `vlib/v/tests/known_errors/testdata/` folder.
|
||||
|
||||
|
||||
## Test building of actual V programs (examples, tools, V itself)
|
||||
|
||||
* `v build-tools`
|
||||
@ -147,12 +152,14 @@ Run `vlib` module tests, *including* the compiler tests.
|
||||
## `v vlib/v/compiler_errors_test.v`
|
||||
|
||||
This runs tests for:
|
||||
|
||||
* `vlib/v/scanner/tests/*.vv`
|
||||
* `vlib/v/checker/tests/*.vv`
|
||||
* `vlib/v/parser/tests/*.vv`
|
||||
|
||||
NB: there are special folders, that compiler_errors_test.v will try to
|
||||
run/compile with specific options:
|
||||
> **Note**
|
||||
> There are special folders, that compiler_errors_test.v will try to
|
||||
> run/compile with specific options:
|
||||
|
||||
vlib/v/checker/tests/globals_run/ - `-enable-globals run`;
|
||||
results stored in `.run.out` files, matching the .vv ones.
|
||||
|
186
doc/docs.md
186
doc/docs.md
@ -209,7 +209,7 @@ by using any of the following commands in a terminal:
|
||||
</table>
|
||||
|
||||
<!--
|
||||
NB: there are several special keywords, which you can put after the code fences for v:
|
||||
Note: There are several special keywords, which you can put after the code fences for v:
|
||||
compile, cgen, live, ignore, failcompile, okfmt, oksyntax, badsyntax, wip, nofmt
|
||||
For more details, do: `v check-md`
|
||||
-->
|
||||
@ -252,10 +252,11 @@ This means that a "hello world" program in V is as simple as
|
||||
println('hello world')
|
||||
```
|
||||
|
||||
Note: if you do not use explicitly `fn main() {}`, you need to make sure, that all your
|
||||
declarations, come before any variable assignment statements, or top level function calls,
|
||||
since V will consider everything after the first assignment/function call as part of your
|
||||
implicit main function.
|
||||
> **Note**
|
||||
> If you do not use explicitly `fn main() {}`, you need to make sure, that all your
|
||||
> declarations, come before any variable assignment statements, or top level function calls,
|
||||
> since V will consider everything after the first assignment/function call as part of your
|
||||
> implicit main function.
|
||||
|
||||
## Running a project folder with several files
|
||||
|
||||
@ -285,13 +286,15 @@ import os
|
||||
println(os.args)
|
||||
```
|
||||
|
||||
NB: after a successful run, V will delete the generated executable.
|
||||
If you want to keep it, use `v -keepc run .` instead, or just compile
|
||||
manually with `v .` .
|
||||
> **Note**
|
||||
> After a successful run, V will delete the generated executable.
|
||||
> If you want to keep it, use `v -keepc run .` instead, or just compile
|
||||
> manually with `v .` .
|
||||
|
||||
NB: any V compiler flags should be passed *before* the `run` command.
|
||||
Everything after the source file/folder, will be passed to the program
|
||||
as is - it will not be processed by V.
|
||||
> **Note**
|
||||
> Any V compiler flags should be passed *before* the `run` command.
|
||||
> Everything after the source file/folder, will be passed to the program
|
||||
> as is - it will not be processed by V.
|
||||
|
||||
## Comments
|
||||
|
||||
@ -359,8 +362,9 @@ Functions are private (not exported) by default.
|
||||
To allow other [modules](#module-imports) to use them, prepend `pub`. The same applies
|
||||
to [structs](#structs), [constants](#constants) and [types](#type-declarations).
|
||||
|
||||
Note: `pub` can only be used from a named module.
|
||||
For information about creating a module, see [Modules](#modules).
|
||||
> **Note**
|
||||
> `pub` can only be used from a named module.
|
||||
> For information about creating a module, see [Modules](#modules).
|
||||
|
||||
## Variables
|
||||
|
||||
@ -477,7 +481,8 @@ voidptr // this one is mostly used for [C interoperability](#v-and-c)
|
||||
any // similar to C's void* and Go's interface{}
|
||||
```
|
||||
|
||||
Please note that unlike C and Go, `int` is always a 32 bit integer.
|
||||
> **Note**
|
||||
> Unlike C and Go, `int` is always a 32 bit integer.
|
||||
|
||||
There is an exception to the rule that all operators
|
||||
in V must have values of the same type on both sides. A small primitive type
|
||||
@ -623,9 +628,10 @@ To use a format specifier, follow this pattern:
|
||||
`${varname:[flags][width][.precision][type]}`
|
||||
|
||||
- flags: may be zero or more of the following: `-` to left-align output within the field, `0` to use
|
||||
`0` as the padding character instead of the default `space` character. (Note: V does not currently
|
||||
support the use of `'` or `#` as format flags, and V supports but doesn't need `+` to right-align
|
||||
since that's the default.)
|
||||
`0` as the padding character instead of the default `space` character.
|
||||
> **Note**
|
||||
> V does not currently support the use of `'` or `#` as format flags, and V supports but
|
||||
> doesn't need `+` to right-align since that's the default.
|
||||
- width: may be an integer value describing the minimum width of total field to output.
|
||||
- precision: an integer value preceded by a `.` will guarantee that many digits after the decimal
|
||||
point, if the input variable is a float. Ignored if variable is an integer.
|
||||
@ -637,13 +643,15 @@ To use a format specifier, follow this pattern:
|
||||
integer and will render it as octal digits, `b` requires an integer and will render it as binary
|
||||
digits, `s` requires a string (almost never used).
|
||||
|
||||
Note: when a numeric type can render alphabetic characters, such as hex strings or special values
|
||||
like `infinity`, the lowercase version of the type forces lowercase alphabetics and the uppercase
|
||||
version forces uppercase alphabetics.
|
||||
> **Note**
|
||||
> When a numeric type can render alphabetic characters, such as hex strings or special values
|
||||
> like `infinity`, the lowercase version of the type forces lowercase alphabetics and the
|
||||
> uppercase version forces uppercase alphabetics.
|
||||
|
||||
Also note: in most cases, it's best to leave the format type empty. Floats will be rendered by
|
||||
default as `g`, integers will be rendered by default as `d`, and `s` is almost always redundant.
|
||||
There are only three cases where specifying a type is recommended:
|
||||
> **Note**
|
||||
> In most cases, it's best to leave the format type empty. Floats will be rendered by
|
||||
> default as `g`, integers will be rendered by default as `d`, and `s` is almost always redundant.
|
||||
> There are only three cases where specifying a type is recommended:
|
||||
|
||||
- format strings are parsed at compile time, so specifying a type can help detect errors then
|
||||
- format strings default to using lowercase letters for hex digits and the `e` in exponents. Use a
|
||||
@ -887,7 +895,8 @@ println(nums.len) // "0"
|
||||
`data` is a field (of type `voidptr`) with the address of the first
|
||||
element. This is for low-level [`unsafe`](#memory-unsafe-code) code.
|
||||
|
||||
Note that the fields are read-only and can't be modified by the user.
|
||||
> **Note**
|
||||
> Fields are read-only and can't be modified by the user.
|
||||
|
||||
#### Array Initialization
|
||||
|
||||
@ -933,7 +942,8 @@ for i in 0 .. 1000 {
|
||||
}
|
||||
```
|
||||
|
||||
Note: The above code uses a [range `for`](#range-for) statement.
|
||||
> **Note**
|
||||
> The above code uses a [range `for`](#range-for) statement.
|
||||
|
||||
You can initialize the array by accessing the `it` variable which gives
|
||||
the index as shown here:
|
||||
@ -1231,7 +1241,7 @@ You can call .clone() on the slice, if you do want to have an independent copy r
|
||||
```v
|
||||
mut a := [0, 1, 2, 3, 4, 5]
|
||||
mut b := a[2..4].clone()
|
||||
b[0] = 7 // NB: `b[0]` is NOT referring to `a[2]`, as it would have been, without the .clone()
|
||||
b[0] = 7 // Note: `b[0]` is NOT referring to `a[2]`, as it would have been, without the .clone()
|
||||
println(a) // [0, 1, 2, 3, 4, 5]
|
||||
println(b) // [7, 3]
|
||||
```
|
||||
@ -1441,8 +1451,9 @@ fn main() {
|
||||
}
|
||||
```
|
||||
|
||||
Note: This will import the module as well. Also, this is not allowed for
|
||||
constants - they must always be prefixed.
|
||||
> **Note**
|
||||
> This will import the module as well. Also, this is not allowed for
|
||||
> constants - they must always be prefixed.
|
||||
|
||||
You can import several specific symbols at once:
|
||||
|
||||
@ -1459,7 +1470,8 @@ println('Your OS is ${current_os}.')
|
||||
|
||||
Any imported module name can be aliased using the `as` keyword:
|
||||
|
||||
NOTE: this example will not compile unless you have created `mymod/sha256.v`
|
||||
> **Note**
|
||||
> This example will not compile unless you have created `mymod/sha256.v`
|
||||
|
||||
```v failcompile
|
||||
import crypto.sha256
|
||||
@ -1737,7 +1749,8 @@ println(num)
|
||||
|
||||
Constants can also be used in the range branch expressions.
|
||||
|
||||
Note: `match` as an expression is not usable in `for` loop and `if` statements.
|
||||
> **Note**
|
||||
> `match` as an expression is not usable in `for` loop and `if` statements.
|
||||
|
||||
### In operator
|
||||
|
||||
@ -2273,12 +2286,12 @@ 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`.
|
||||
> Note 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
|
||||
|
||||
@ -2526,7 +2539,8 @@ Output: `Size: 4B, clr1.b: 136, clr2.b: 0`
|
||||
|
||||
Union member access must be performed in an `unsafe` block.
|
||||
|
||||
Note that the embedded struct arguments are not necessarily stored in the order listed.
|
||||
> **Note**
|
||||
> Embedded struct arguments are not necessarily stored in the order listed.
|
||||
|
||||
## Functions 2
|
||||
|
||||
@ -2541,7 +2555,8 @@ are a function of their arguments only, and their evaluation has no side effects
|
||||
|
||||
Function arguments are immutable by default, even when [references](#references) are passed.
|
||||
|
||||
Note that V is not a purely functional language however.
|
||||
> **Note**
|
||||
> V is not a purely functional language however.
|
||||
|
||||
There is a compiler flag to enable global variables (`-enable-globals`), but this is
|
||||
intended for low-level applications like kernels and drivers.
|
||||
@ -2901,8 +2916,9 @@ fn panic(s string) // prints a message and backtraces on stderr, and terminates
|
||||
fn print_backtrace() // prints backtraces on stderr
|
||||
```
|
||||
|
||||
Note: Although the `print` functions take a string, V accepts other printable types too.
|
||||
See below for details.
|
||||
> **Note**
|
||||
> Although the `print` functions take a string, V accepts other printable types too.
|
||||
> See below for details.
|
||||
|
||||
There is also a special built-in function called [`dump`](#dumping-expressions-at-runtime).
|
||||
|
||||
@ -3398,7 +3414,8 @@ They are just a convenient way to write `i.some_function()` instead of
|
||||
`some_function(i)`, similar to how struct methods can be looked at, as
|
||||
a convenience for writing `s.xyz()` instead of `xyz(s)`.
|
||||
|
||||
N.B. This feature is NOT a "default implementation" like in C#.
|
||||
> **Note**
|
||||
> This feature is NOT a "default implementation" like in C#.
|
||||
|
||||
For example, if a struct `cat` is wrapped in an interface `a`, that has
|
||||
implemented a method with the same name `speak`, as a method implemented by
|
||||
@ -3744,7 +3761,9 @@ user := repo.find_user_by_id(7) or { return }
|
||||
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.
|
||||
|
||||
> **Note**
|
||||
> `break` and `continue` can only be used inside a `for` loop.
|
||||
|
||||
V does not have a way to forcibly "unwrap" an option (as other languages do,
|
||||
for instance Rust's `unwrap()` or Swift's `!`). To do this, use `or { panic(err) }` instead.
|
||||
@ -4303,7 +4322,8 @@ assert fails it is reported to *stderr*, and the values on each side of a compar
|
||||
unexpected value. Assert statements can be used in any function, not just test ones,
|
||||
which is handy when developing new functionality, to keep your invariants in check.
|
||||
|
||||
Note: all `assert` statements are *removed*, when you compile your program with the `-prod` flag.
|
||||
> **Note**
|
||||
> All `assert` statements are *removed*, when you compile your program with the `-prod` flag.
|
||||
|
||||
### Asserts with an extra message
|
||||
|
||||
@ -4351,8 +4371,9 @@ assert_continues_example.v:3: FAIL: fn main.abc: assert ii == 2
|
||||
right value: 2
|
||||
```
|
||||
|
||||
Note: V also supports a command line flag `-assert continues`, which will change the
|
||||
behaviour of all asserts globally, as if you had tagged every function with `[assert_continues]`.
|
||||
> **Note**
|
||||
> V also supports a command line flag `-assert continues`, which will change the
|
||||
> behaviour of all asserts globally, as if you had tagged every function with `[assert_continues]`.
|
||||
|
||||
### Test files
|
||||
|
||||
@ -4381,10 +4402,11 @@ fn test_hello() {
|
||||
To run the test file above, use `v hello_test.v`. This will check that the function `hello` is
|
||||
producing the correct output. V executes all test functions in the file.
|
||||
|
||||
Note: all `_test.v` files (both external and internal ones), are compiled as *separate programs*.
|
||||
In other words, you may have as many `_test.v` files, and tests in them as you like, they will
|
||||
not affect the compilation of your other code in `.v` files normally at all, but only when you
|
||||
do explicitly `v file_test.v` or `v test .`.
|
||||
> **Note**
|
||||
> All `_test.v` files (both external and internal ones), are compiled as *separate programs*.
|
||||
> In other words, you may have as many `_test.v` files, and tests in them as you like, they will
|
||||
> not affect the compilation of your other code in `.v` files normally at all, but only when you
|
||||
> do explicitly `v file_test.v` or `v test .`.
|
||||
|
||||
* All test functions have to be inside a test file whose name ends in `_test.v`.
|
||||
* Test function names must begin with `test_` to mark them for execution.
|
||||
@ -4435,8 +4457,9 @@ 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.
|
||||
|
||||
NB: the path to the V compiler, is available through @VEXE, so a _test.v
|
||||
file, can easily run *other* test files like this:
|
||||
> **Note**
|
||||
> The path to the V compiler, is available through @VEXE, so a _test.v
|
||||
> file, can easily run *other* test files like this:
|
||||
|
||||
```v oksyntax
|
||||
import os
|
||||
@ -4484,9 +4507,10 @@ For developers willing to have more low level control, autofree can be disabled
|
||||
`-manualfree`, or by adding a `[manualfree]` on each function that wants manage its
|
||||
memory manually. (See [attributes](#attributes)).
|
||||
|
||||
Note 2: Autofree is still WIP. Until it stabilises and becomes the default, please
|
||||
avoid using it. Right now allocations are handled by a minimal and well performing GC
|
||||
until V's autofree engine is production ready.
|
||||
> **Note**
|
||||
> Autofree is still WIP. Until it stabilises and becomes the default, please
|
||||
> avoid using it. Right now allocations are handled by a minimal and well performing GC
|
||||
> until V's autofree engine is production ready.
|
||||
|
||||
**Examples**
|
||||
|
||||
@ -5616,10 +5640,11 @@ With the example above:
|
||||
That corresponds to `$if customflag ? {}`, but for a whole file, not just a
|
||||
single block. `customflag` should be a snake_case identifier, it can not
|
||||
contain arbitrary characters (only lower case latin letters + numbers + `_`).
|
||||
NB: a combinatorial `_d_customflag_linux.c.v` postfix will not work.
|
||||
If you do need a custom flag file, that has platform dependent code, use the
|
||||
postfix `_d_customflag.v`, and then use plaftorm dependent compile time
|
||||
conditional blocks inside it, i.e. `$if linux {}` etc.
|
||||
> **Note**
|
||||
> A combinatorial `_d_customflag_linux.c.v` postfix will not work.
|
||||
> If you do need a custom flag file, that has platform dependent code, use the
|
||||
> postfix `_d_customflag.v`, and then use plaftorm dependent compile time
|
||||
> conditional blocks inside it, i.e. `$if linux {}` etc.
|
||||
|
||||
- `_notd_customflag.v` => similar to _d_customflag.v, but will be used
|
||||
*only* if you do NOT pass `-d customflag` to V.
|
||||
@ -5669,7 +5694,8 @@ If you suspect your program does violate memory-safety, you have a head start on
|
||||
finding the cause: look at the `unsafe` blocks (and how they interact with
|
||||
surrounding code).
|
||||
|
||||
* Note: This is work in progress.
|
||||
> **Note**
|
||||
> This is work in progress.
|
||||
|
||||
## Structs with reference fields
|
||||
|
||||
@ -5797,10 +5823,11 @@ with `-prod`. There are some situations though, where you may want to give
|
||||
additional hints to the compiler, so that it can further optimize some
|
||||
blocks of code.
|
||||
|
||||
NB: These are *rarely* needed, and should not be used, unless you
|
||||
*profile your code*, and then see that there are significant benefits for them.
|
||||
To cite gcc's documentation: "programmers are notoriously bad at predicting
|
||||
how their programs actually perform".
|
||||
> **Note**
|
||||
> These are *rarely* needed, and should not be used, unless you
|
||||
> *profile your code*, and then see that there are significant benefits for them.
|
||||
> To cite gcc's documentation: "programmers are notoriously bad at predicting
|
||||
> how their programs actually perform".
|
||||
|
||||
`[inline]` - you can tag functions with `[inline]`, so the C compiler will
|
||||
try to inline them, which in some cases, may be beneficial for performance,
|
||||
@ -5970,8 +5997,9 @@ or
|
||||
v -os linux .
|
||||
```
|
||||
|
||||
NB: Cross-compiling a windows binary on a linux machine requires the GNU C compiler for
|
||||
MinGW-w64 (targeting Win64) to first be installed.
|
||||
> **Note**
|
||||
> Cross-compiling a windows binary on a linux machine requires the GNU C compiler for
|
||||
> MinGW-w64 (targeting Win64) to first be installed.
|
||||
|
||||
For Ubuntu/Debian based distributions:
|
||||
|
||||
@ -6113,7 +6141,7 @@ fn main() {
|
||||
// C.sqlite3_open(db_path.str, &db)
|
||||
query := 'select count(*) from users'
|
||||
stmt := &C.sqlite3_stmt(0)
|
||||
// NB: you can also use the `.str` field of a V string,
|
||||
// Note: You can also use the `.str` field of a V string,
|
||||
// to get its C style zero terminated representation
|
||||
C.sqlite3_prepare_v2(db, &char(query.str), -1, &stmt, 0)
|
||||
C.sqlite3_step(stmt)
|
||||
@ -6152,7 +6180,8 @@ Add `#flag` directives to the top of your V files to provide C compilation flags
|
||||
You can (optionally) 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)
|
||||
> **Note**
|
||||
> Each flag must go on its own line (for now)
|
||||
|
||||
```v oksyntax
|
||||
#flag linux -lsdl2
|
||||
@ -6228,11 +6257,13 @@ Module {
|
||||
#include "header.h"
|
||||
```
|
||||
|
||||
NB: @VMODROOT 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 @VMODROOT/abc` to refer to this folder.
|
||||
The @VMODROOT folder is also *prepended* to the module lookup path,
|
||||
so you can *import* other modules under your @VMODROOT, by just naming them.
|
||||
> **Note**
|
||||
> @VMODROOT 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 @VMODROOT/abc` to refer to this folder.
|
||||
> The @VMODROOT folder is also *prepended* to the module lookup path,
|
||||
> so you can *import* other modules under your @VMODROOT, by just naming them.
|
||||
|
||||
The instructions above will make V look for an compiled .o file in
|
||||
your module `folder/c/implementation.o`.
|
||||
@ -6252,10 +6283,11 @@ Ordinary zero terminated C strings can be converted to V strings with
|
||||
`unsafe { &char(cstring).vstring() }` or if you know their length already with
|
||||
`unsafe { &char(cstring).vstring_with_len(len) }`.
|
||||
|
||||
NB: The .vstring() and .vstring_with_len() methods do NOT create a copy of the `cstring`,
|
||||
so you should NOT free it after calling the method `.vstring()`.
|
||||
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)`.
|
||||
> **Note**
|
||||
> The `.vstring()` and `.vstring_with_len()` methods do NOT create a copy of the `cstring`,
|
||||
> so you should NOT free it after calling the method `.vstring()`.
|
||||
> 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))` .
|
||||
@ -6475,7 +6507,7 @@ An example `deploy.vsh`:
|
||||
```v oksyntax
|
||||
#!/usr/bin/env -S v
|
||||
|
||||
// Note: the shebang line above, associates the .vsh file to V on Unix-like systems,
|
||||
// Note: The shebang line above, associates the .vsh file to V on Unix-like systems,
|
||||
// so it can be run just by specifying the path to the .vsh file, once it's made
|
||||
// executable, using `chmod +x deploy.vsh`, i.e. after that chmod command, you can
|
||||
// run the .vsh script, by just typing its name/path like this: `./deploy.vsh`
|
||||
|
@ -66,7 +66,7 @@ To help making the correct decision the following table summarizes the
|
||||
different capabilities:
|
||||
|
||||
| | *default* | `mut` | `shared` | `atomic` |
|
||||
| :--- | :---: | :---: | :---: | :---: |
|
||||
|:-------------------------|:---------:|:-----:|:--------:|:--------:|
|
||||
| write access | | + | + | + |
|
||||
| concurrent access | + | | + | + |
|
||||
| performance | ++ | ++ | | + |
|
||||
@ -74,37 +74,47 @@ different capabilities:
|
||||
| structured data types | + | + | + | |
|
||||
|
||||
### Strengths
|
||||
|
||||
**default**
|
||||
|
||||
- very fast
|
||||
- unlimited access from different coroutines
|
||||
- easy to handle
|
||||
|
||||
**`mut`**
|
||||
|
||||
- very fast
|
||||
- easy to handle
|
||||
|
||||
**`shared`**
|
||||
|
||||
- concurrent access from different coroutines
|
||||
- data type may be complex structure
|
||||
- sophisticated access possible (several statements within one `lock`
|
||||
block)
|
||||
|
||||
**`atomic`**
|
||||
|
||||
- concurrent access from different coroutines
|
||||
- reasonably fast
|
||||
|
||||
### Weaknesses
|
||||
|
||||
**default**
|
||||
|
||||
- read only
|
||||
|
||||
**`mut`**
|
||||
|
||||
- access only from one coroutine at a time
|
||||
|
||||
**`shared`**
|
||||
|
||||
- lock/unlock are slow
|
||||
- moderately difficult to handle (needs `lock` block)
|
||||
|
||||
**`atomic`**
|
||||
|
||||
- limited to single (max. 64 bit) integers (and pointers)
|
||||
- only a small set of predefined operations possible
|
||||
- very difficult to handle correctly
|
||||
@ -118,6 +128,7 @@ allocation would be an unnecessary overhead. Instead the compiler
|
||||
creates a global.
|
||||
|
||||
### Compatibility
|
||||
|
||||
Outside of `lock`/`rlock` blocks function arguments must in general
|
||||
match - with the familiar exception that objects declared `mut` can be
|
||||
used to call functions expecting immutable arguments:
|
||||
@ -145,6 +156,7 @@ i(atomic d)
|
||||
|
||||
Inside a `lock c {...}` block `c` behaves like a `mut`,
|
||||
inside an `rlock c {...}` block like an immutable:
|
||||
|
||||
```v ignore
|
||||
shared c := St{...}
|
||||
lock c {
|
||||
@ -160,6 +172,7 @@ rlock c {
|
||||
```
|
||||
|
||||
### Automatic Lock
|
||||
|
||||
In general the compiler will generate an error message when a `shared`
|
||||
object is accessed outside of any corresponding `lock`/`rlock`
|
||||
block. However in simple and obvious cases the necessary lock/unlock
|
||||
|
@ -13,11 +13,12 @@ provides V language support for Visual Studio Code.
|
||||
![Screenshot Code with activated extension](https://github.com/vlang/vscode-vlang/raw/HEAD/images/demo.png)
|
||||
|
||||
**Features:**
|
||||
|
||||
* Syntax Highlighting.
|
||||
* Code Snippets for quick coding.
|
||||
* Format code on file save as well as format manually (using v fmt).
|
||||
* Linter (Workspace files only).
|
||||
[more](https://marketplace.visualstudio.com/items?itemName=vlanguage.vscode-vlang)
|
||||
[more](https://marketplace.visualstudio.com/items?itemName=vlanguage.vscode-vlang)
|
||||
|
||||
**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)
|
||||
@ -35,11 +36,12 @@ The [C/C++ Extension](https://marketplace.visualstudio.com/items?itemName=ms-vsc
|
||||
for Visual Studio Code provides visual conditional debugging.
|
||||
|
||||
**Features:**
|
||||
|
||||
* Conditional breakpoints
|
||||
* Function breakpoints
|
||||
* Expression evaluation
|
||||
* Change Values
|
||||
[more Features & Documentation](https://code.visualstudio.com/docs/cpp/cpp-debug)
|
||||
[more Features & Documentation](https://code.visualstudio.com/docs/cpp/cpp-debug)
|
||||
|
||||
**Hint:** Not all types (e.g. Array) in V currently create the required
|
||||
[DWARF](https://en.wikipedia.org/wiki/DWARF) information to show and
|
||||
@ -48,18 +50,21 @@ edit the variable.
|
||||
### Setup Debugging
|
||||
|
||||
#### Step1: Configure the launch.json file
|
||||
1. Install the [C/C++ Extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools)
|
||||
|
||||
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",`
|
||||
or a more flexible one `"program": "${fileDirname}/${fileBasenameNoExtension}",`
|
||||
when you want to debug the current opened file.
|
||||
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`:
|
||||
|
||||
```json
|
||||
{
|
||||
// Use IntelliSense to learn about possible attributes.
|
||||
@ -89,6 +94,7 @@ or create the file `.vscode/launch.json`:
|
||||
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.
|
||||
|
||||
@ -104,6 +110,7 @@ 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
|
||||
@ -136,7 +143,7 @@ The application needs to include additional debugging information
|
||||
|
||||
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.
|
||||
`> (lldb) Start`, or use `F5` to launch your application in debug mode.
|
||||
|
||||
For all options look at the official
|
||||
[C/C++ Extension documentation](https://code.visualstudio.com/docs/cpp/cpp-debug).
|
||||
|
@ -3,6 +3,8 @@
|
||||
There are 2 ways to do regex:
|
||||
a) using the native module called `regex`
|
||||
b) using an exteranl module called `pcre`, which wraps the C library pcre.
|
||||
NB: you need to first do: `v install pcre`, for the `pcre` module to work.
|
||||
|
||||
> **Note**
|
||||
> You need to first do: `v install pcre`, for the `pcre` module to work.
|
||||
|
||||
You can find examples of both in this directory.
|
||||
|
@ -16,7 +16,8 @@ The benefits of using V for web:
|
||||
is enough.
|
||||
- Fast development without any boilerplate.
|
||||
|
||||
_Please note that V and Vweb are at a very early stage and are changing rapidly._
|
||||
> **Note**
|
||||
> V and Vweb are at a very early stage and are changing rapidly.
|
||||
|
||||
The code is available [here](./code/blog).
|
||||
|
||||
|
@ -3,11 +3,14 @@ For Linux, you need to install `MySQL development` package and `pkg-config`.
|
||||
For Windows, install [the installer](https://dev.mysql.com/downloads/installer/) ,
|
||||
then copy the `include` and `lib` folders to `<V install directory>\thirdparty\mysql`.
|
||||
|
||||
Note: if you encounter weird errors (your program just exits right away, without
|
||||
### Troubleshooting
|
||||
|
||||
If you encounter weird errors (your program just exits right away, without
|
||||
printing any messages, even though you have `println('hi')` statements in your
|
||||
`fn main()`), when trying to run a program that does `import db.mysql` on windows, you
|
||||
may need to copy the .dll file: `thirdparty/mysql/lib/libmysql.dll` , into the folder
|
||||
may need to copy the .dll file: `thirdparty/mysql/lib/libmysql.dll`, into the folder
|
||||
of the executable too (it should be right next to the .exe file).
|
||||
|
||||
This is a temporary workaround, until we have a more permanent solution, or at least
|
||||
more user friendly errors for that situation.
|
||||
|
||||
|
@ -6,8 +6,9 @@ database server.
|
||||
Before you can use this module, you must first have PostgreSQL installed on your system.
|
||||
To do this, find your OS and perform the actions listed.
|
||||
|
||||
**NOTE**: These instructions are meant only as a convenience. If your OS is not listed
|
||||
or you need extra help, [go here](https://www.postgresql.org/download/).
|
||||
> **Note**
|
||||
> These instructions are meant only as a convenience. If your OS is not listed
|
||||
> or you need extra help, [go here](https://www.postgresql.org/download/).
|
||||
|
||||
### Fedora 31
|
||||
```
|
||||
|
@ -5,5 +5,6 @@ It is a thin wrapper over `LoadLibrary` on Windows, and `dlopen` on Unix.
|
||||
|
||||
Using it, you can implement a plugin system for your application.
|
||||
|
||||
> NOTE: We highly recommend using `dl.loader` instead of `dl` directly.
|
||||
> **Note**
|
||||
> We highly recommend using `dl.loader` instead of `dl` directly.
|
||||
> It provides a more user-friendly API in the V way.
|
||||
|
@ -19,5 +19,6 @@ sequence of bytes in the previous example: `0x12`, `0x34`, `0x56`, and `0x78`. I
|
||||
this sequence in little endian format, we get the integer `0x78563412`. If we encode this
|
||||
sequence in big endian, we get `0x12345678`.
|
||||
|
||||
**NOTE:** The functions in this module assume appropriately sized u8 arrays. If the sizes
|
||||
are not valid, the functions will panic.
|
||||
> **Note**
|
||||
> The functions in this module assume appropriately sized u8 arrays. If the sizes
|
||||
> are not valid, the functions will panic.
|
||||
|
@ -51,7 +51,8 @@ fn on_press(receiver voidptr, e &ClickEvent, sender voidptr) {
|
||||
For **usage across modules**
|
||||
[check the example](https://github.com/vlang/v/tree/master/examples/eventbus).
|
||||
|
||||
_Note: As a general rule, you will need to **subscribe before publishing**._
|
||||
> **Note**
|
||||
> As a general rule, you will need to **subscribe before publishing**.
|
||||
|
||||
**main.v**
|
||||
|
||||
|
@ -3,4 +3,5 @@
|
||||
`gx` is a complementary module to `gg`, that just provides
|
||||
some predefined graphical color names/operations.
|
||||
|
||||
NB: `gx` is going to be merged with `gg` soon.
|
||||
> **Note**
|
||||
> `gx` is going to be merged with `gg` soon.
|
||||
|
@ -1,4 +1,6 @@
|
||||
## Description:
|
||||
|
||||
`js` is frontend/browser specific module, that provides access to global JS functions.
|
||||
NB: it *only* works with the JS backend.
|
||||
|
||||
> **Note**
|
||||
> It *only* works with the JS backend.
|
||||
|
@ -50,8 +50,9 @@ rng.int() // among others ...
|
||||
You can change the default generator to a different one. The only requirement is that
|
||||
the generator must implement the `PRNG` interface. See `get_current_rng()` and `set_rng()`.
|
||||
|
||||
**Note:** The global PRNG is not thread safe. It is recommended to use separate generators for
|
||||
separate threads in multi-threaded applications.
|
||||
> **Note**
|
||||
> The global PRNG is not thread safe. It is recommended to use separate generators for
|
||||
> separate threads in multi-threaded applications.
|
||||
|
||||
There are only a few extra functions that are defined only in this top-level `rand` module.
|
||||
Otherwise, there is feature parity between the generator functions and the top-level functions.
|
||||
@ -110,7 +111,8 @@ A workaround (if you _must_ use the libc RNG) is to:
|
||||
|
||||
# Notes
|
||||
|
||||
Please note that [math interval](<https://en.wikipedia.org/wiki/Interval_(mathematics)#Including_or_excluding_endpoints>) notation is used throughout
|
||||
the function documentation to denote what numbers ranges include.
|
||||
[Math interval](<https://en.wikipedia.org/wiki/Interval_(mathematics)#Including_or_excluding_endpoints>)
|
||||
notation is used throughout the function documentation to denote what numbers ranges include.
|
||||
|
||||
An example of `[0, max)` thus denotes a range with all posible values
|
||||
between `0` and `max` **including** 0 but **excluding** `max`.
|
||||
|
@ -2,7 +2,8 @@
|
||||
`regex` is a small but powerful regular expression library,
|
||||
written in pure V.
|
||||
|
||||
NB: `regex` is *not* PCRE compatible.
|
||||
> **Note**
|
||||
> `regex` is *not* PCRE compatible.
|
||||
|
||||
[TOC]
|
||||
|
||||
@ -19,9 +20,10 @@ In a query string a simple character is a token.
|
||||
|
||||
## Differences with PCRE:
|
||||
|
||||
NB: We must point out that the **V-Regex module is not PCRE compliant** and thus
|
||||
some behaviour will be different. This difference is due to the V philosophy,
|
||||
to have one way and keep it simple.
|
||||
> **Note**
|
||||
> We must point out that the **V-Regex module is not PCRE compliant** and thus
|
||||
> some behaviour will be different. This difference is due to the V philosophy,
|
||||
> to have one way and keep it simple.
|
||||
|
||||
The main differences can be summarized in the following points:
|
||||
|
||||
@ -81,12 +83,13 @@ latin chars `a-z` and all the digits `\d`.
|
||||
|
||||
It is possible to mix all the properties of the char class together.
|
||||
|
||||
NB: In order to match the `-` (minus) char, it must be preceded by
|
||||
a backslash in the cc, for example `[\-_\d\a]` will match:
|
||||
`-` minus,
|
||||
`_` underscore,
|
||||
`\d` numeric chars,
|
||||
`\a` lower case chars.
|
||||
> **Note**
|
||||
> In order to match the `-` (minus) char, it must be preceded by
|
||||
> a backslash in the cc, for example `[\-_\d\a]` will match:
|
||||
> - `-` minus,
|
||||
> - `_` underscore,
|
||||
> - `\d` numeric chars,
|
||||
> - `\a` lower case chars.
|
||||
|
||||
### Meta-chars
|
||||
|
||||
@ -146,8 +149,8 @@ parsing source string.
|
||||
| `ab.{3} .*e` | `abccc dde` |
|
||||
The dot matches any character, until the next token match is satisfied.
|
||||
|
||||
**Important Note:** *Consecutive dots, for example `...`, are not allowed.*
|
||||
*This will cause a syntax error. Use a quantifier instead.*
|
||||
> Important Note: Consecutive dots, for example `...`, are not allowed.
|
||||
> This will cause a syntax error. Use a quantifier instead.
|
||||
|
||||
### OR token
|
||||
|
||||
@ -158,9 +161,12 @@ The OR token can work in a "chained way": `a|(b)|cd ` means test first `a`,
|
||||
if the char is not `a`, then test the group `(b)`, and if the group doesn't
|
||||
match too, finally test the token `c`.
|
||||
|
||||
NB: ** unlike in PCRE, the OR operation works at token level!**
|
||||
It doesn't work at concatenation level!
|
||||
NB2: **Two char classes with an `OR` in the middle is a syntax error.**
|
||||
> **Note**
|
||||
> Unlike in PCRE, the OR operation works at token level!
|
||||
> It doesn't work at concatenation level!
|
||||
|
||||
> **Note**
|
||||
> Two char classes with an `OR` in the middle is a syntax error.
|
||||
|
||||
That also means, that a query string like `abc|bde` is not equal to
|
||||
`(abc)|(bde)`, but instead to `ab(c|b)de.
|
||||
@ -220,8 +226,9 @@ for gi < re.groups.len {
|
||||
// 1 :[pa]
|
||||
```
|
||||
|
||||
**note:** *to show the `group id number` in the result of the `get_query()`*
|
||||
*the flag `debug` of the RE object must be `1` or `2`*
|
||||
> **Note**
|
||||
> To show the `group id number` in the result of the `get_query()`
|
||||
> the flag `debug` of the RE object must be `1` or `2`
|
||||
|
||||
In order to simplify the use of the captured groups, it possible to use the
|
||||
utility function: `get_group_list`.
|
||||
@ -248,7 +255,7 @@ fn convert_html_rgb(in_col string) u32 {
|
||||
mut n_digit := if in_col.len == 4 { 1 } else { 2 }
|
||||
mut col_mul := if in_col.len == 4 { 4 } else { 0 }
|
||||
// this is the regex query, it use the V string interpolation to customize the regex query
|
||||
// NOTE: if you want use escaped code you must use the r"" (raw) strings,
|
||||
// Note: If you want use escaped code you must use the r"" (raw) strings,
|
||||
// *** please remember that the V interpoaltion doesn't work on raw strings. ***
|
||||
query := '#([a-fA-F0-9]{${n_digit}})([a-fA-F0-9]{${n_digit}})([a-fA-F0-9]{${n_digit}})'
|
||||
mut re := regex.regex_opt(query) or { panic(err) }
|
||||
@ -598,7 +605,8 @@ in this example we used the group `0` in the replace string: `\0`, the result wi
|
||||
Today it is a good day. => Tod__[ay]__it is a good d__[ay]__
|
||||
```
|
||||
|
||||
**Note:** in the replace strings can be used only groups from `0` to `9`.
|
||||
> **Note**
|
||||
> In the replace strings can be used only groups from `0` to `9`.
|
||||
|
||||
If the usage of `groups` in the replace process, is not needed, it is possible
|
||||
to use a quick function:
|
||||
|
@ -2,7 +2,8 @@
|
||||
|
||||
These are v implementations of the C language `printf` and `sprintf` functions.
|
||||
|
||||
***Note: These functions are platform dependent in C, but in V they are platform independent.***
|
||||
> **Note**
|
||||
> These functions are platform dependent in C, but in V they are platform independent.
|
||||
|
||||
### v_sprintf
|
||||
|
||||
|
@ -4,78 +4,99 @@ usefull for templated HTML views, but the mechanism is general enough
|
||||
to be used for other kinds of text output also.
|
||||
|
||||
# Template directives
|
||||
|
||||
Each template directive begins with an `@` sign.
|
||||
Some directives contain a `{}` block, others only have `''` (string) parameters.
|
||||
|
||||
Newlines on the beginning and end are ignored in `{}` blocks,
|
||||
otherwise this (see [if](#if) for this syntax):
|
||||
|
||||
```html
|
||||
@if bool_val {
|
||||
<span>This is shown if bool_val is true</span>
|
||||
}
|
||||
```
|
||||
|
||||
... would output:
|
||||
|
||||
```html
|
||||
|
||||
<span>This is shown if bool_val is true</span>
|
||||
|
||||
```
|
||||
|
||||
... which is less readable.
|
||||
|
||||
## if
|
||||
|
||||
The if directive, consists of three parts, the `@if` tag, the condition (same syntax like in V)
|
||||
and the `{}` block, where you can write html, which will be rendered if the condition is true:
|
||||
|
||||
```
|
||||
@if <condition> {}
|
||||
```
|
||||
|
||||
### Example
|
||||
|
||||
```html
|
||||
@if bool_val {
|
||||
<span>This is shown if bool_val is true</span>
|
||||
}
|
||||
```
|
||||
|
||||
One-liner:
|
||||
|
||||
```html
|
||||
@if bool_val { <span>This is shown if bool_val is true</span> }
|
||||
```
|
||||
|
||||
The first example would result in:
|
||||
|
||||
```html
|
||||
<span>This is shown if bool_val is true</span>
|
||||
```
|
||||
|
||||
... while the one-liner results in:
|
||||
|
||||
```html
|
||||
<span>This is shown if bool_val is true</span>
|
||||
```
|
||||
|
||||
## for
|
||||
|
||||
The for directive consists of three parts, the `@for` tag,
|
||||
the condition (same syntax like in V) and the `{}` block,
|
||||
where you can write text, rendered for each iteration of the loop:
|
||||
|
||||
```
|
||||
@for <condition> {}
|
||||
```
|
||||
|
||||
### Example for @for
|
||||
|
||||
```html
|
||||
@for i, val in my_vals {
|
||||
<span>$i - $val</span>
|
||||
}
|
||||
```
|
||||
|
||||
One-liner:
|
||||
|
||||
```html
|
||||
@for i, val in my_vals { <span>$i - $val</span> }
|
||||
```
|
||||
|
||||
The first example would result in:
|
||||
|
||||
```html
|
||||
<span>0 - "First"</span>
|
||||
<span>1 - "Second"</span>
|
||||
<span>2 - "Third"</span>
|
||||
...
|
||||
```
|
||||
|
||||
... while the one-liner results in:
|
||||
|
||||
```html
|
||||
<span>0 - "First"</span>
|
||||
<span>1 - "Second"</span>
|
||||
@ -84,6 +105,7 @@ The first example would result in:
|
||||
```
|
||||
|
||||
You can also write (and all other for condition syntaxes that are allowed in V):
|
||||
|
||||
```html
|
||||
@for i = 0; i < 5; i++ {
|
||||
<span>$i</span>
|
||||
@ -91,11 +113,13 @@ You can also write (and all other for condition syntaxes that are allowed in V):
|
||||
```
|
||||
|
||||
## include
|
||||
|
||||
The include directive is for including other html files (which will be processed as well)
|
||||
and consists of two parts, the `@include` tag and a following `'<path>'` string.
|
||||
The path parameter is relative to the `/templates` directory in the corresponding project.
|
||||
|
||||
### Example for the folder structure of a project using templates:
|
||||
|
||||
```
|
||||
Project root
|
||||
/templates
|
||||
@ -105,25 +129,31 @@ Project root
|
||||
```
|
||||
|
||||
`index.html`
|
||||
|
||||
```html
|
||||
|
||||
<div>@include 'header/base'</div>
|
||||
```
|
||||
> Note that there shouldn't be a file suffix,
|
||||
it is automatically appended and only allows `html` files.
|
||||
|
||||
> Note that there shouldn't be a file suffix,
|
||||
> it is automatically appended and only allows `html` files.
|
||||
|
||||
## js
|
||||
|
||||
The js directive consists of two parts, the `@js` tag and `'<path>'` string,
|
||||
where you can insert your src
|
||||
|
||||
```
|
||||
@js '<url>'
|
||||
```
|
||||
|
||||
### Example for the @js directive:
|
||||
|
||||
```html
|
||||
@js 'myscripts.js'
|
||||
```
|
||||
|
||||
# Variables
|
||||
|
||||
All variables, which are declared before the $tmpl can be used through the `@{my_var}` syntax.
|
||||
It's also possible to use properties of structs here like `@{my_struct.prop}`.
|
||||
|
@ -5,10 +5,9 @@
|
||||
- 2 space initial indentation (titles exempt)
|
||||
- Description indentation of two spaces from the longest word
|
||||
- All descriptions should be indented to the same column within a block, with a
|
||||
hard limit at column 80.
|
||||
hard limit at column 80.
|
||||
- Multi-line descriptions should indent to match the description part of the previous line
|
||||
|
||||
|
||||
## Example
|
||||
|
||||
Adding a help file was made to be easy. All you have to do is create the text file in the
|
||||
|
@ -4,8 +4,9 @@ The vlib/v/preludes/ contains small v code snippets, that V uses when
|
||||
compiling certain v programs. V adds the files below automatically itself.
|
||||
Each file is used in different situations (see below).
|
||||
|
||||
NB: preludes are *NOT* intended to be used by user programs/modules.
|
||||
The folder vlib/v/preludes/ is *NOT* a v module.
|
||||
> **Note**
|
||||
> Preludes are *NOT* intended to be used by user programs/modules.
|
||||
> The folder vlib/v/preludes/ is *NOT* a v module.
|
||||
|
||||
## Details:
|
||||
|
||||
|
@ -20,6 +20,7 @@ Instead, your test_ functions will get called inside the generated
|
||||
`int main(){...}` test runner, just like it is the case with all _test.v
|
||||
files (internal or external ones).
|
||||
|
||||
NB: each _test.v file is compiled separately from all other _test.v
|
||||
files, so you can have conflicting test_ functions in them without a
|
||||
problem too.
|
||||
> **Note**
|
||||
> Each _test.v file is compiled separately from all other _test.v
|
||||
> files, so you can have conflicting test_ functions in them without a
|
||||
> problem too.
|
||||
|
@ -17,7 +17,10 @@ mut ttf_font := ttf.TTF_File{}
|
||||
ttf_font.buf = os.read_bytes("arial.ttf") or { panic(err) }
|
||||
ttf_font.init()
|
||||
```
|
||||
*Note: the font must be passed to the `TTF_file` as RAM buffer.*
|
||||
|
||||
> **Note**
|
||||
> The font must be passed to the `TTF_file` as RAM buffer.
|
||||
|
||||
At this point the font "arial" is loaded and parsed and if it is a valid TTF font it is
|
||||
ready for the rendering.
|
||||
We can get some quick info on the font as string using the `get_info_string` function:
|
||||
@ -115,7 +118,9 @@ fn main() {
|
||||
```
|
||||
This is the low level render that draw ther text on a bitmap and save the bitmap on a disk as
|
||||
`.ppm` file.
|
||||
*Note: The render in this case is a raw rendering without any postfiltering or other processing.*
|
||||
|
||||
> **Note**
|
||||
> The render in this case is a raw rendering without any postfiltering or other processing.
|
||||
|
||||
Using the low level rendering you need to manage all the amenities like allocate and release
|
||||
memory and other tasks like calc the character dimensions.
|
||||
|
Loading…
Reference in New Issue
Block a user