202 lines
3.9 KiB
V
202 lines
3.9 KiB
V
|
// Copyright (c) 2019 Alexander Medvednikov. All rights reserved.
|
||
|
// Use of this source code is governed by an MIT license
|
||
|
// that can be found in the LICENSE file.
|
||
|
|
||
|
module main
|
||
|
|
||
|
import (
|
||
|
strings
|
||
|
os
|
||
|
)
|
||
|
|
||
|
/* .vh generation logic.
|
||
|
.vh files contains only function signatures, consts, and types.
|
||
|
They are used together with pre-compiled modules.
|
||
|
*/
|
||
|
|
||
|
// "fn foo(a int) string"
|
||
|
fn (f &Fn) v_definition() string {
|
||
|
//t :=time.ticks()
|
||
|
mut sb := strings.new_builder(100)
|
||
|
if f.is_public {
|
||
|
sb.write('pub ')
|
||
|
}
|
||
|
sb.write('fn ')
|
||
|
if f.is_c {
|
||
|
sb.write('C.')
|
||
|
}
|
||
|
if f.is_method {
|
||
|
recv := f.args[0]
|
||
|
typ := v_type_str(recv.typ)
|
||
|
mut mu := if recv.is_mut { 'mut' } else { '' }
|
||
|
if recv.ref {
|
||
|
mu = '&'
|
||
|
}
|
||
|
sb.write('($recv.name $mu $typ) ')
|
||
|
}
|
||
|
if f.name.contains('__') {
|
||
|
sb.write(f.name.all_after('__') + '(')
|
||
|
} else {
|
||
|
sb.write('$f.name(')
|
||
|
}
|
||
|
for i, arg in f.args {
|
||
|
typ := v_type_str(arg.typ)
|
||
|
if arg.name == '' {
|
||
|
sb.write(typ)
|
||
|
} else {
|
||
|
sb.write('$arg.name $typ')
|
||
|
}
|
||
|
if i != f.args.len - 1 {
|
||
|
sb.write(', ')
|
||
|
}
|
||
|
}
|
||
|
sb.write(')')
|
||
|
if f.typ != 'void' {
|
||
|
typ := v_type_str(f.typ)
|
||
|
sb.write(' ')
|
||
|
sb.write(typ)
|
||
|
sb.writeln(' ')
|
||
|
}
|
||
|
//println('ms: ${time.ticks() - t}')
|
||
|
return sb.str()
|
||
|
}
|
||
|
|
||
|
fn v_type_str(typ_ string) string {
|
||
|
typ := if typ_.ends_with('*') {
|
||
|
'*' + typ_.left(typ_.len - 1)
|
||
|
} else {
|
||
|
typ_
|
||
|
}
|
||
|
//println('"$typ"')
|
||
|
if typ == '*void' {
|
||
|
return 'voidptr'
|
||
|
}
|
||
|
if typ == '*byte' {
|
||
|
return 'byteptr'
|
||
|
}
|
||
|
if typ.starts_with('array_') {
|
||
|
return '[]' + typ.right(6)
|
||
|
}
|
||
|
if typ.contains('__') {
|
||
|
return typ.all_after('__')
|
||
|
}
|
||
|
return typ.replace('Option_', '?')
|
||
|
}
|
||
|
|
||
|
fn (v &V) generate_vh() {
|
||
|
println('Generating a V header file for module `$v.mod`')
|
||
|
dir := v_modules_path + v.mod
|
||
|
path := dir + '.vh'
|
||
|
if !os.dir_exists(dir) {
|
||
|
os.mkdir(dir)
|
||
|
}
|
||
|
println(path)
|
||
|
|
||
|
file := os.create(path) or { panic(err) }
|
||
|
// Consts
|
||
|
file.writeln('// $v.mod module header \n')
|
||
|
file.writeln('// Consts')
|
||
|
if v.table.consts.len > 0 {
|
||
|
file.writeln('const (')
|
||
|
for i, c in v.table.consts {
|
||
|
if c.mod != v.mod {
|
||
|
continue
|
||
|
}
|
||
|
println('$i $c.name')
|
||
|
//if !c.name.contains('__') {
|
||
|
//continue
|
||
|
//}
|
||
|
name := c.name.all_after('__')
|
||
|
typ := v_type_str(c.typ)
|
||
|
file.writeln('\t$name $typ')
|
||
|
}
|
||
|
file.writeln(')\n')
|
||
|
// Globals
|
||
|
for var in v.table.consts {
|
||
|
if var.mod != v.mod {
|
||
|
continue
|
||
|
}
|
||
|
if !var.is_global {
|
||
|
continue
|
||
|
}
|
||
|
name := var.name.all_after('__')
|
||
|
typ := v_type_str(var.typ)
|
||
|
file.writeln('__global $name $typ')
|
||
|
}
|
||
|
file.writeln('\n')
|
||
|
}
|
||
|
// Types
|
||
|
file.writeln('// Types')
|
||
|
for _, typ in v.table.typesmap {
|
||
|
if typ.mod != v.mod {
|
||
|
continue
|
||
|
}
|
||
|
if typ.name.contains('__') {
|
||
|
continue
|
||
|
}
|
||
|
if typ.cat == .struct_ {
|
||
|
file.writeln('struct $typ.name {')
|
||
|
// Private fields
|
||
|
for field in typ.fields {
|
||
|
if field.access_mod == .public {
|
||
|
continue
|
||
|
}
|
||
|
field_type := v_type_str(field.typ)
|
||
|
file.writeln('\t$field.name $field_type')
|
||
|
}
|
||
|
file.writeln('pub:')
|
||
|
for field in typ.fields {
|
||
|
if field.access_mod == .private {
|
||
|
continue
|
||
|
}
|
||
|
field_type := v_type_str(field.typ)
|
||
|
file.writeln('\t$field.name $field_type')
|
||
|
}
|
||
|
file.writeln('}\n')
|
||
|
}
|
||
|
}
|
||
|
// Functions & methods
|
||
|
file.writeln('// Functions')
|
||
|
// Public first
|
||
|
mut fns := []Fn
|
||
|
// TODO fns := v.table.fns.filter(.mod == v.mod)
|
||
|
for _, f in v.table.fns {
|
||
|
if f.mod == v.mod {
|
||
|
fns << f
|
||
|
}
|
||
|
}
|
||
|
for _, f in fns {
|
||
|
if !f.is_public {
|
||
|
continue
|
||
|
}
|
||
|
file.writeln(f.v_definition())
|
||
|
}
|
||
|
// Private
|
||
|
for _, f in fns {
|
||
|
if f.is_public {
|
||
|
continue
|
||
|
}
|
||
|
file.writeln(f.v_definition())
|
||
|
}
|
||
|
// Methods
|
||
|
file.writeln('\n// Methods //////////////////')
|
||
|
for _, typ in v.table.typesmap {
|
||
|
if typ.mod != v.mod {
|
||
|
continue
|
||
|
}
|
||
|
for method in typ.methods {
|
||
|
file.writeln(method.v_definition())
|
||
|
}
|
||
|
}
|
||
|
file.close()
|
||
|
|
||
|
/*
|
||
|
for i, p in v.parsers {
|
||
|
if v.parsers[i].vh_lines.len > 0 {
|
||
|
os.write_file(p.file_name +'.vh', v.parsers[i].vh_lines.join('\n'))
|
||
|
}
|
||
|
}
|
||
|
*/
|
||
|
}
|
||
|
|