v/vlib/v
spaceface 4152c704f3
sokol: remove `.lib` extensions in `#pragma` directives (#8639)
fixes tcc on windows - this kind of fix has been done several times in the past, and should probably be upstreamed to sokol soon to prevent things from breaking every time we update the headers.
2021-02-09 11:36:01 +02:00
..
ast fmt: keep comments between and after imports (#8637) 2021-02-08 19:48:48 +02:00
builder compiler: move timing_start/timing_measure to util.timing_start/util.timing_measure 2021-02-05 16:34:56 +02:00
cflag builder: implement `-dump-c-flags flags.txt` 2021-01-29 18:05:14 +02:00
checker cgen: cast default struct field value to correct SumType/interface (#8619) 2021-02-08 17:33:05 +02:00
depgraph all: update copyright to 2019-2021 (#8029) 2021-01-18 13:20:06 +01:00
doc doc, fmt: use `map{key: value}` syntax for map literals (#8623) 2021-02-08 16:57:42 +02:00
embed_file checker: allow ptr++/ptr-- in unsafe{}, for any kind of pointer, except voidptr 2021-01-17 18:09:25 +02:00
errors fmt: fix multiple things and format most of the compiler (#6631) 2020-10-15 22:12:59 +02:00
eval all: update copyright to 2019-2021 (#8029) 2021-01-18 13:20:06 +01:00
fmt fmt: keep comments between and after imports (#8637) 2021-02-08 19:48:48 +02:00
gen sokol: remove `.lib` extensions in `#pragma` directives (#8639) 2021-02-09 11:36:01 +02:00
live all: require calling `optfn() ?` / `optfn() or {...}` for `fn optfn() ? {}` 2021-01-26 16:43:17 +02:00
parser all: allow using aliases as keys in map (#8589) 2021-02-08 18:51:05 +01:00
pkgconfig all: require calling `optfn() ?` / `optfn() or {...}` for `fn optfn() ? {}` 2021-01-26 16:43:17 +02:00
pref v.pref: support `v -skip-unused run examples/hello_world.v` 2021-02-05 11:12:28 +02:00
preludes live: move to vlib/v/live 2021-01-16 15:05:01 +02:00
scanner fmt: single line ternary return (#8605) 2021-02-08 00:28:46 +01:00
table all: allow using aliases as keys in map (#8589) 2021-02-08 18:51:05 +01:00
tests all: allow using aliases as keys in map (#8589) 2021-02-08 18:51:05 +01:00
token token: fix Token.str() for punctuation and operators (#8610) 2021-02-07 03:40:00 +01:00
util doc, fmt: use `map{key: value}` syntax for map literals (#8623) 2021-02-08 16:57:42 +02:00
vcache v.vcache: improve tracing of vcache usage 2021-01-29 18:05:13 +02:00
vet all: update copyright to 2019-2021 (#8029) 2021-01-18 13:20:06 +01:00
vmod ci: fix `v test-cleancode` 2021-01-25 12:55:01 +02:00
README.md cgen: move cgen from v.gen to v.gen.c (#8515) 2021-02-02 15:41:51 +01:00
compiler_errors_test.v ci: fix the using_comptime_env.vv test (execute only on ubuntu-tcc again) 2021-02-06 13:07:21 +02:00

README.md

Compiler pipeline

A simple high level explanation how the compiler pipeline (parser -> checker -> generator) works.

Reading files

Getting builtin files

To load all builtin files, a preference Preferences.lookup_path for the path where to look for exists. See Builder.get_builtin_files as example. If the file is a .vsh file and the backend is C, vlib/os will also be loaded as builtin.

Getting project files

Either there is a specific file: my_file.v or a directory containing V files. In the last case it scans that directory for all files. See Builder.v_files_from_dir as the helper method. This list of files needs to be filtered so that only *.v files exist.

Skips the following file types:

  • *_test.v
  • either *.c.v or *.c.js depending on the backend
  • all files that doesn't end with .v
  • Files that are not defined in Preferences.compile_defines or Preferences.compile_defines_all if any file is defined.

Parsing files

To parse something a new template is created as the first step:

import v.table

table := table.new_table()

a new preference is created:

import v.pref

pref := pref.Preferences{}

and a new scope is created:

import v.ast

scope := ast.Scope{
	parent: 0
}

after that, you can parse your files.

Parse text

If you want to parse only text which isn't saved on the disk you can use this function.

import v.parser

code := ''
// table, pref and scope needs to be passed as reference
parsed_file := parser.parse_text(code, table, .parse_comments, &pref, &scope)

Parse a single file

For parsing files on disk, a path needs to be provided. The paths are collected one step earlier.

import v.parser

path := ''
// table, pref and scope needs to be passed as reference
parsed_file := parser.parse_file(path, table, .parse_comments, &pref, &scope)

Parse a set of files

If you have a batch of paths available which should be parsed, there is also a function which does all the work.

import v.parser

paths := ['']
// table, pref and scope needs to be passed as reference
parsed_files := parser.parse_files(paths, table, &pref, &scope)

Parse imports

A file often contains imports. These imports might need to be parsed as well. The builder contains a method which does this: Builder.parse_imports.

If the module which is imported isn't parsed already, you have to collect it relatively from the main file. For this the ast.File contains a list of imports. Those imports needs to be found on disk. . is just replaced with seperators in the relative location of the main file. Then all files from that directory are collected and parsed again like the previous steps explained.

Checking AST

A new checker is created:

import v.checker

mut checker := checker.new_checker(table, &pref)

After checking your files in checker.errors and checker.warnings you can see the results.

Check ast.File

checker.check(parsed_file)

Check a list of ast.File

checker.check_files(parsed_files)

Generate target from AST

Generating C code works just as this:

import v.gen.c

res := c.gen(parsed_files, table, &pref)