1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

parser: cached tokens (second step)

This commit is contained in:
Alexander Medvednikov
2019-09-26 05:28:43 +03:00
parent a45255337d
commit da43267e09
8 changed files with 149 additions and 104 deletions

View File

@ -74,6 +74,7 @@ mut:
vroot string
mod string // module being built with -lib
parsers []Parser
vgen_file os.File
}
struct Preferences {
@ -153,6 +154,8 @@ fn main() {
vfmt(args)
return
}
// Construct the V object from command line arguments
mut v := new_v(args)
if args.join(' ').contains(' test v') {
@ -223,13 +226,9 @@ fn (v mut V) compile() {
if os.user_os() != 'windows' && v.os == .msvc {
verror('Cannot build with msvc on ${os.user_os()}')
}
mut cgen := v.cgen
cgen.genln('// Generated by V')
// Add builtin parsers
for i, file in v.files {
// v.parsers << v.new_parser(file)
}
if v.pref.is_verbose {
println('all .v files before:')
println(v.files)
@ -239,11 +238,24 @@ fn (v mut V) compile() {
println('all .v files:')
println(v.files)
}
if v.pref.is_debug {
println('\nparsers:')
for q in v.parsers {
println(q.file_name)
}
println('\nfiles:')
for q in v.files {
println(q)
}
}
// First pass (declarations)
for file in v.files {
mut p := v.new_parser(file)
p.parse(.decl)
//if p.pref.autofree { p.scanner.text.free() free(p.scanner) }
for i, p in v.parsers {
if p.file_path == file {
v.parsers[i].parse(.decl)
break
}
}
}
// Main pass
cgen.pass = Pass.main
@ -279,13 +291,15 @@ fn (v mut V) compile() {
v.dir.contains('/ui'))) {
cgen.genln('id defaultFont = 0; // main.v')
}
// We need the cjson header for all the json decoding user will do in default mode
// We need the cjson header for all the json decoding that will be done in
// default mode
if v.pref.build_mode == .default_mode {
if imports_json {
cgen.genln('#include "cJSON.h"')
}
}
if v.pref.build_mode == .embed_vlib || v.pref.build_mode == .default_mode {
//if v.pref.build_mode in [.embed_vlib, .default_mode] {
// If we declare these for all modes, then when running `v a.v` we'll get
// `/usr/bin/ld: multiple definition of 'total_m'`
// TODO
@ -294,7 +308,7 @@ fn (v mut V) compile() {
$if !js {
cgen.genln('int g_test_ok = 1; ')
}
if 'json' in v.table.imports {
if imports_json {
cgen.genln('
#define js_get(object, key) cJSON_GetObjectItemCaseSensitive((object), (key))
')
@ -307,8 +321,12 @@ fn (v mut V) compile() {
cgen.genln('this line will be replaced with definitions')
defs_pos := cgen.lines.len - 1
for file in v.files {
mut p := v.new_parser(file)
p.parse(.main)
for i, p in v.parsers {
if p.file_path == file {
v.parsers[i].parse(.main)
break
}
}
//if p.pref.autofree { p.scanner.text.free() free(p.scanner) }
// p.g.gen_x64()
// Format all files (don't format automatically generated vlib headers)
@ -316,6 +334,10 @@ fn (v mut V) compile() {
// new vfmt is not ready yet
}
}
// Close the file with generated V code (str() methods etc) and parse it
v.vgen_file.close()
mut vgen_parser := v.new_parser(vgen_file_name)
vgen_parser.parse(.main)
v.log('Done parsing.')
// Write everything
mut d := strings.new_builder(10000)// Avoid unnecessary allocations
@ -335,8 +357,7 @@ fn (v mut V) compile() {
d.writeln('; // Prof counters:')
d.writeln(v.prof_counters())
}
dd := d.str()
cgen.lines[defs_pos] = dd// TODO `def.str()` doesn't compile
cgen.lines[defs_pos] = d.str()
v.generate_main()
v.generate_hot_reload_code()
if v.pref.is_verbose {
@ -716,6 +737,10 @@ fn (v &V) log(s string) {
}
fn new_v(args[]string) &V {
os.rm(vgen_file_name)
vgen_file := os.open_append(vgen_file_name) or { panic(err) }
vgen_file.writeln('module main\nimport strings')
joined_args := args.join(' ')
target_os := get_arg(joined_args, 'os', '')
mut out_name := get_arg(joined_args, 'o', 'a.out')
@ -907,6 +932,7 @@ fn new_v(args[]string) &V {
vroot: vroot
pref: pref
mod: mod
vgen_file: vgen_file
}
}