more ui vh fixes

pull/2619/head
Alexander Medvednikov 2019-11-01 16:10:28 +03:00
parent 59efd42483
commit 80ba8f07b8
3 changed files with 83 additions and 64 deletions

View File

@ -236,7 +236,6 @@ fn (a mut array) set(i int, val voidptr) {
C.memcpy(a.data + a.element_size * i, val, a.element_size) C.memcpy(a.data + a.element_size * i, val, a.element_size)
} }
// TODO push(val) is the same as push_many(val, 1), can be eliminated
fn (a mut array) push(val voidptr) { fn (a mut array) push(val voidptr) {
a.ensure_cap(a.len + 1) a.ensure_cap(a.len + 1)
C.memcpy(a.data + a.element_size * a.len, val, a.element_size) C.memcpy(a.data + a.element_size * a.len, val, a.element_size)

View File

@ -274,7 +274,7 @@ fn (p mut Parser) fn_decl() {
} }
f.fn_name_token_idx = p.cur_tok_index() f.fn_name_token_idx = p.cur_tok_index()
// init fn // init fn
if f.name == 'init' && !f.is_method && f.is_public { if f.name == 'init' && !f.is_method && f.is_public && !p.is_vh {
p.error('init function cannot be public') p.error('init function cannot be public')
} }
// C function header def? (fn C.NSMakeRect(int,int,int,int)) // C function header def? (fn C.NSMakeRect(int,int,int,int))

View File

@ -15,9 +15,19 @@ import (
They are used together with pre-compiled modules. They are used together with pre-compiled modules.
*/ */
struct VhGen {
mut:
i int // token index
consts strings.Builder
fns strings.Builder
types strings.Builder
tokens []Token
}
// `mod` == "vlib/os" // `mod` == "vlib/os"
fn generate_vh(mod string) { fn generate_vh(mod string) {
println('\n\n\n\nGenerating a V header file for module `$mod`') println('\n\n\n\n1Generating a V header file for module `$mod`')
vexe := os.executable() vexe := os.executable()
full_mod_path := os.dir(vexe) + '/' + mod full_mod_path := os.dir(vexe) + '/' + mod
mod_path := mod.replace('.', os.path_separator) mod_path := mod.replace('.', os.path_separator)
@ -46,110 +56,120 @@ fn generate_vh(mod string) {
!it.ends_with('_windows.v') && !it.ends_with('_win.v') && !it.ends_with('_windows.v') && !it.ends_with('_win.v') &&
!it.ends_with('_lin.v') && !it.ends_with('_lin.v') &&
!it.contains('/examples') && !it.contains('/examples') &&
!it.contains('_js.v') &&
!it.contains('/js')) // TODO merge once filter allows it !it.contains('/js')) // TODO merge once filter allows it
println('f:')
println(filtered) println(filtered)
mut v := new_v(['foo.v']) mut v := new_v(['foo.v'])
//v.pref.generating_vh = true //v.pref.generating_vh = true
mut consts := strings.new_builder(100) mut g := VhGen{
mut fns := strings.new_builder(100) consts : strings.new_builder(1000)
mut types := strings.new_builder(100) fns : strings.new_builder(1000)
types : strings.new_builder(1000)
}
for file in filtered { for file in filtered {
mut p := v.new_parser_from_file(file) mut p := v.new_parser_from_file(file)
p.scanner.is_vh = true p.scanner.is_vh = true
p.parse(.decl) p.parse(.decl)
for i, tok in p.tokens { g.tokens = p.tokens
if !p.tok.is_decl() { g.i = 0
for ; g.i < p.tokens.len; g.i++ {
if !p.tokens[g.i].tok.is_decl() {
continue continue
} }
match tok.tok { match g.tokens[g.i].tok {
.key_fn { fns.writeln(generate_fn(p.tokens, i)) } .key_fn { g.generate_fn() }
.key_const { consts.writeln(generate_const(p.tokens, i)) } .key_const { g.generate_const() }
.key_struct { types.writeln(generate_type(p.tokens, i)) } .key_struct { g.generate_type() }
.key_type { types.writeln(generate_alias(p.tokens, i)) } .key_type { g.generate_alias() }
} }
} }
} }
result := consts.str() + types.str() + result :=
fns.str().replace('\n\n\n', '\n').replace('\n\n', '\n') g.types.str() +
g.consts.str() +
g.fns.str().replace('\n\n\n', '\n').replace('\n\n', '\n')
out.writeln(result.replace('[ ] ', '[]').replace('? ', '?')) out.writeln(result.replace('[ ] ', '[]').replace('? ', '?'))
out.close() out.close()
} }
fn generate_fn(tokens []Token, i int) string { fn (g mut VhGen) generate_fn() {
mut out := strings.new_builder(100) if g.i >= g.tokens.len - 2 {
mut next := tokens[i+1] return
if tokens[i-1].tok != .key_pub { }
mut next := g.tokens[g.i+1]
if g.i > 0 && g.tokens[g.i-1].tok != .key_pub {
// Skip private fns // Skip private fns
return '' //return ''
} }
if next.tok == .name && next.lit == 'C' { if next.tok == .name && next.lit == 'C' {
println('skipping C') println('skipping C')
return '' return
} }
//out.write('pub ') //out.write('pub ')
mut tok := tokens[i] mut tok := g.tokens[g.i]
for i < tokens.len && tok.tok != .lcbr { for g.i < g.tokens.len - 1 && tok.tok != .lcbr {
next = tokens[i+1] next = g.tokens[g.i+1]
out.write(tok.str()) g.fns.write(tok.str())
if tok.tok != .lpar && !(next.tok in [.comma, .rpar]) { if tok.tok != .lpar && !(next.tok in [.comma, .rpar]) {
// No space after (), [], etc // No space after (), [], etc
out.write(' ') g.fns.write(' ')
} }
i++ g.i++
tok = tokens[i] tok = g.tokens[g.i]
} }
return out.str() g.fns.writeln('')
//g.i--
} }
fn generate_alias(tokens []Token, i int) string { fn (g mut VhGen) generate_alias() {
mut out := strings.new_builder(100) mut tok := g.tokens[g.i]
mut tok := tokens[i] for g.i < g.tokens.len-1 {
for i < tokens.len-1 { g.types.write(tok.str())
out.write(tok.str()) g.types.write(' ')
out.write(' ') if tok.line_nr != g.tokens[g.i+1].line_nr {
if tok.line_nr != tokens[i+1].line_nr {
break break
} }
i++ g.i++
tok = tokens[i] tok = g.tokens[g.i]
} }
out.writeln('\n') g.types.writeln('\n')
return out.str() //g.i--
} }
fn generate_const(tokens []Token, i int) string { fn (g mut VhGen) generate_const() {
mut out := strings.new_builder(100) mut tok := g.tokens[g.i]
mut tok := tokens[i] for g.i < g.tokens.len && tok.tok != .rpar {
for i < tokens.len && tok.tok != .rpar { g.consts.write(tok.str())
out.write(tok.str()) g.consts.write(' ')
out.write(' ') if g.tokens[g.i+2].tok == .assign {
if tokens[i+2].tok == .assign { g.consts.write('\n\t')
out.write('\n\t')
} }
i++ g.i++
tok = tokens[i] tok = g.tokens[g.i]
} }
out.writeln('\n)') g.consts.writeln('\n)')
return out.str() //g.i--
} }
fn generate_type(tokens []Token, i int) string { fn (g mut VhGen) generate_type() {
mut out := strings.new_builder(100) //old := g.i
mut tok := tokens[i] mut tok := g.tokens[g.i]
for i < tokens.len && tok.tok != .rcbr { for g.i < g.tokens.len && tok.tok != .rcbr {
out.write(tok.str()) g.types.write(tok.str())
out.write(' ') g.types.write(' ')
if tokens[i+1].line_nr != tokens[i].line_nr { if g.tokens[g.i+1].line_nr != g.tokens[g.i].line_nr {
out.write('\n\t') g.types.write('\n\t')
} }
i++ g.i++
tok = tokens[i] tok = g.tokens[g.i]
} }
out.writeln('\n}') g.types.writeln('\n}')
return out.str() //g.i = old
//g.i--
} }