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

202 lines
3.9 KiB
V
Raw Normal View History

2019-10-04 15:48:09 +03:00
// 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'))
}
}
*/
}