v ast: use `flag`, add ability to combine -p and -w, implement --hide pos,name_pos,args,global_scope,scope
parent
fe65cde03b
commit
b09fa69cb3
|
@ -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])
|
}
|
||||||
|
mut ctx := Context{}
|
||||||
|
mut fp := flag.new_flag_parser(os.args[2..])
|
||||||
|
fp.application('v ast')
|
||||||
|
fp.usage_example('demo.v generate demo.json file.')
|
||||||
|
fp.usage_example('-w demo.v generate demo.json file, and watch for changes.')
|
||||||
|
fp.usage_example('-c demo.v generate demo.json *and* a demo.c file, and watch for changes.')
|
||||||
|
fp.usage_example('-p demo.v print the json output to stdout.')
|
||||||
|
fp.description('Dump a JSON representation of the V AST for a given .v or .vsh file.')
|
||||||
|
fp.description('By default, `v ast` will save the JSON to a .json file, named after the .v file.')
|
||||||
|
fp.description('Pass -p to see it instead.')
|
||||||
|
ctx.is_watch = fp.bool('watch', `w`, false, 'watch a .v file for changes, rewrite the .json file, when a change is detected')
|
||||||
|
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(',')
|
||||||
|
mut mhf := unsafe { hide_fields }
|
||||||
|
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)
|
check_file(file)
|
||||||
println('AST written to: ' + json_file(file))
|
ctx.write_file_or_print(file)
|
||||||
}
|
if ctx.is_watch || ctx.is_compile {
|
||||||
3 {
|
ctx.watch_for_changes(file)
|
||||||
file := get_abs_path(args[2])
|
|
||||||
check_file(file)
|
|
||||||
option := args[1]
|
|
||||||
match option {
|
|
||||||
'-p' { println(json(file)) }
|
|
||||||
'-w' { gen(file, false) }
|
|
||||||
'-c' { gen(file, true) }
|
|
||||||
else { println(usage) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
println(usage)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue