v ast: use `flag`, add ability to combine -p and -w, implement --hide pos,name_pos,args,global_scope,scope

pull/10784/head
Delyan Angelov 2021-07-12 14:50:36 +03:00
parent fe65cde03b
commit b09fa69cb3
No known key found for this signature in database
GPG Key ID: 66886C0F12D595ED
1 changed files with 60 additions and 33 deletions

View File

@ -1,56 +1,80 @@
module main module main
import os
import time
import flag
import v.token import v.token
import v.parser import v.parser
import v.ast import v.ast
import v.pref import v.pref
import v.errors import v.errors
import os
import time
const usage = ' struct Context {
usage: mut:
1.v ast demo.v generate demo.json file. is_watch bool
2.v ast -w demo.v generate demo.json file, and watch for changes. is_compile bool
3.v ast -c demo.v generate demo.json and demo.c file, and watch for changes. is_print bool
4.v ast -p demo.v print the json string to stdout, instead of saving it to a file. }
'
struct HideFields {
mut:
names map[string]bool
}
const hide_fields = &HideFields{}
fn main() { fn main() {
args := os.args[1..] if os.args.len < 2 {
match args.len { eprintln('not enough parameters')
2 { exit(1)
file := get_abs_path(args[1]) }
check_file(file) mut ctx := Context{}
println('AST written to: ' + json_file(file)) mut fp := flag.new_flag_parser(os.args[2..])
} fp.application('v ast')
3 { fp.usage_example('demo.v generate demo.json file.')
file := get_abs_path(args[2]) fp.usage_example('-w demo.v generate demo.json file, and watch for changes.')
check_file(file) fp.usage_example('-c demo.v generate demo.json *and* a demo.c file, and watch for changes.')
option := args[1] fp.usage_example('-p demo.v print the json output to stdout.')
match option { fp.description('Dump a JSON representation of the V AST for a given .v or .vsh file.')
'-p' { println(json(file)) } fp.description('By default, `v ast` will save the JSON to a .json file, named after the .v file.')
'-w' { gen(file, false) } fp.description('Pass -p to see it instead.')
'-c' { gen(file, true) } ctx.is_watch = fp.bool('watch', `w`, false, 'watch a .v file for changes, rewrite the .json file, when a change is detected')
else { println(usage) } ctx.is_print = fp.bool('print', `p`, false, 'print the AST to stdout')
} ctx.is_compile = fp.bool('compile', `c`, false, 'watch the .v file for changes, rewrite the .json file, *AND* generate a .c file too on any change')
} hfields := fp.string_multi('hide', 0, 'hide the specified fields. You can give several, by separating them with `,`').join(',')
else { mut mhf := unsafe { hide_fields }
println(usage) for hf in hfields.split(',') {
mhf.names[hf] = true
}
fp.limit_free_args_to_at_least(1)
rest_of_args := fp.remaining_parameters()
for vfile in rest_of_args {
file := get_abs_path(vfile)
check_file(file)
ctx.write_file_or_print(file)
if ctx.is_watch || ctx.is_compile {
ctx.watch_for_changes(file)
} }
} }
} }
fn (ctx Context) write_file_or_print(file string) {
if ctx.is_print {
println(json(file))
} else {
println('$time.now(): AST written to: ' + json_file(file))
}
}
// generate ast json file and c source code file // generate ast json file and c source code file
fn gen(file string, is_genc bool) { fn (ctx Context) watch_for_changes(file string) {
println('start watching...') println('start watching...')
mut timestamp := 0 mut timestamp := 0
for { for {
new_timestamp := os.file_last_mod_unix(file) new_timestamp := os.file_last_mod_unix(file)
if timestamp != new_timestamp { if timestamp != new_timestamp {
res := json_file(file) ctx.write_file_or_print(file)
println('$time.now() : AST written to: ' + res) if ctx.is_compile {
if is_genc {
file_name := file[0..(file.len - os.file_ext(file).len)] file_name := file[0..(file.len - os.file_ext(file).len)]
os.system('v -o ${file_name}.c $file') os.system('v -o ${file_name}.c $file')
} }
@ -141,6 +165,9 @@ fn new_object() &Node {
// add item to object node // add item to object node
[inline] [inline]
fn (node &Node) add(key string, child &Node) { fn (node &Node) add(key string, child &Node) {
if hide_fields.names.len > 0 && key in hide_fields.names {
return
}
add_item_to_object(node, key, child) add_item_to_object(node, key, child)
} }