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. |
||
---|---|---|
.. | ||
ast | ||
builder | ||
cflag | ||
checker | ||
depgraph | ||
doc | ||
embed_file | ||
errors | ||
eval | ||
fmt | ||
gen | ||
live | ||
parser | ||
pkgconfig | ||
pref | ||
preludes | ||
scanner | ||
table | ||
tests | ||
token | ||
util | ||
vcache | ||
vet | ||
vmod | ||
README.md | ||
compiler_errors_test.v |
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
orPreferences.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)