This commit is contained in:
2025-03-24 06:44:39 +01:00
parent 0df10f5cb3
commit 598b312140
371 changed files with 8238 additions and 9082 deletions

View File

@@ -1,4 +1,3 @@
module code
pub type Value = string

View File

@@ -3,23 +3,23 @@ module code
import freeflowuniverse.herolib.core.pathlib
pub interface IFolder {
name string
files []IFile
name string
files []IFile
modules []Module
write(string, WriteOptions) !
}
pub struct Folder {
pub:
name string
files []IFile
name string
files []IFile
folders []IFolder
modules []Module
}
pub fn (f Folder) write(path string, options WriteOptions) ! {
mut dir := pathlib.get_dir(
path: '${path}/${f.name}'
path: '${path}/${f.name}'
empty: options.overwrite
)!
@@ -36,4 +36,4 @@ pub fn (f Folder) write(path string, options WriteOptions) ! {
for mod in f.modules {
mod.write(dir.path, options)!
}
}
}

View File

@@ -3,7 +3,14 @@ module code
// Code is a list of statements
// pub type Code = []CodeItem
pub type CodeItem = Alias | Comment | CustomCode | Function | Import | Struct | Sumtype | Interface
pub type CodeItem = Alias
| Comment
| CustomCode
| Function
| Import
| Struct
| Sumtype
| Interface
// item for adding custom code in
pub struct CustomCode {

View File

@@ -11,7 +11,7 @@ pub fn parse_const(code_ string) !Const {
return error('code <${code_}> is not of const')
}
return Const{
name: code.split('=')[0].trim_space()
name: code.split('=')[0].trim_space()
value: code.split('=')[1].trim_space()
}
}

View File

@@ -5,8 +5,8 @@ import freeflowuniverse.herolib.core.pathlib
import os
pub interface IFile {
write(string, WriteOptions) !
name string
write(string, WriteOptions) !
}
pub struct File {
@@ -30,7 +30,6 @@ pub fn (f File) typescript(path string, params WriteOptions) ! {
}
}
pub struct VFile {
pub mut:
name string
@@ -44,7 +43,7 @@ pub mut:
pub fn new_file(config VFile) VFile {
return VFile{
...config
mod: texttools.name_fix(config.mod)
mod: texttools.name_fix(config.mod)
items: config.items
}
}
@@ -85,11 +84,13 @@ pub fn (code VFile) write(path string, options WriteOptions) ! {
}
mut file := pathlib.get_file(
path: filepath.path
path: filepath.path
create: true
)!
mod_stmt := if code.mod == '' {''} else {
mod_stmt := if code.mod == '' {
''
} else {
'module ${code.mod}'
}
@@ -128,4 +129,4 @@ pub fn (file VFile) functions() []Function {
pub fn (file VFile) structs() []Struct {
return file.items.filter(it is Struct).map(it as Struct)
}
}

View File

@@ -3,23 +3,23 @@ module code
import freeflowuniverse.herolib.core.pathlib
pub interface IBasicFolder {
name string
files []IFile
name string
files []IFile
modules []Module
write(string, WriteOptions) !
}
pub struct BasicFolder {
pub:
name string
files []IFile
name string
files []IFile
folders []IBasicFolder
modules []Module
}
pub fn (f BasicFolder) write(path string, options WriteOptions) ! {
mut dir := pathlib.get_dir(
path: '${path}/${f.name}'
path: '${path}/${f.name}'
empty: options.overwrite
)!
@@ -36,4 +36,4 @@ pub fn (f BasicFolder) write(path string, options WriteOptions) ! {
for mod in f.modules {
mod.write(dir.path, options)!
}
}
}

View File

@@ -4,60 +4,62 @@ import freeflowuniverse.herolib.core.texttools
pub struct Function {
pub:
name string @[omitempty]
receiver Param @[omitempty]
is_pub bool @[omitempty]
mod string @[omitempty]
name string @[omitempty]
receiver Param @[omitempty]
is_pub bool @[omitempty]
mod string @[omitempty]
pub mut:
summary string @[omitempty]
description string @[omitempty]
params []Param @[omitempty]
body string @[omitempty]
summary string @[omitempty]
description string @[omitempty]
params []Param @[omitempty]
body string @[omitempty]
result Param @[omitempty]
has_return bool @[omitempty]
has_return bool @[omitempty]
}
// vgen_function generates a function statement for a function
pub fn (function Function) vgen(options WriteOptions) string {
mut params_ := function.params.clone()
optionals := function.params.filter(it.is_optional)
options_struct := Struct{
name: '${texttools.pascal_case(function.name)}Options'
attrs: [Attribute{
name: '${texttools.pascal_case(function.name)}Options'
attrs: [Attribute{
name: 'params'
}]
fields: optionals.map(StructField{
name: it.name
name: it.name
description: it.description
typ: it.typ
typ: it.typ
})
}
if optionals.len > 0 {
params_ << Param{
name: 'options'
typ: type_from_symbol(options_struct.name)
typ: type_from_symbol(options_struct.name)
}
}
params := params_.filter(!it.is_optional).map(it.vgen()).join(', ')
receiver_ := Param{
...function.receiver,
...function.receiver
typ: if function.receiver.typ is Result {
function.receiver.typ.typ
} else {function.receiver.typ}
} else {
function.receiver.typ
}
}
receiver := if receiver_.vgen().trim_space() != '' {
'(${receiver_.vgen()})'
} else {''}
} else {
''
}
name := texttools.name_fix(function.name)
result := function.result.typ.vgen()
mut function_str := $tmpl('templates/function/function.v.template')
// if options.format {
// result := os.execute_opt('echo "${function_str.replace('$', '\\$')}" | v fmt') or {
// panic('${function_str}\n${err}')
@@ -115,10 +117,10 @@ pub fn parse_function(code_ string) !Function {
body := if code.contains('{') { code.all_after('{').all_before_last('}') } else { '' }
return Function{
name: name
name: name
receiver: receiver
params: params
result: result
body: body
params: params
result: result
body: body
}
}
}

View File

@@ -14,7 +14,7 @@ pub fn parse_import(code_ string) Import {
code := code_.trim_space().trim_string_left('import').trim_space()
types_str := if code.contains(' ') { code.all_after(' ').trim('{}') } else { '' }
return Import{
mod: code.all_before(' ')
mod: code.all_before(' ')
types: if types_str != '' {
types_str.split(',').map(it.trim_space())
} else {

View File

@@ -1,4 +1,5 @@
module code
import freeflowuniverse.herolib.ui.console
import freeflowuniverse.herolib.core.pathlib
import os
@@ -6,75 +7,71 @@ import log
pub struct Module {
pub mut:
name string
name string
description string
version string = '0.0.1'
license string = 'apache2'
vcs string = 'git'
files []IFile
folders []IFolder
modules []Module
in_src bool // whether mod will be generated in src folder
version string = '0.0.1'
license string = 'apache2'
vcs string = 'git'
files []IFile
folders []IFolder
modules []Module
in_src bool // whether mod will be generated in src folder
}
pub fn new_module(mod Module) Module {
return Module {
return Module{
...mod
files: mod.files.map(
if it is VFile {
IFile(VFile{...it, mod: mod.name})
} else {it}
)
files: mod.files.map(if it is VFile {
IFile(VFile{ ...it, mod: mod.name })
} else {
it
})
}
}
pub fn (mod Module) write(path string, options WriteOptions) ! {
mut module_dir := pathlib.get_dir(
path: if mod.in_src { '${path}/src' } else { '${path}/${mod.name}' }
path: if mod.in_src { '${path}/src' } else { '${path}/${mod.name}' }
empty: options.overwrite
)!
console.print_debug("write ${module_dir.path}")
console.print_debug('write ${module_dir.path}')
// pre:="v -n -w -enable-globals"
pre:="v -n -w -gc none -cc tcc -d use_openssl -enable-globals run"
pre := 'v -n -w -gc none -cc tcc -d use_openssl -enable-globals run'
if !options.overwrite && module_dir.exists() {
return
}
for file in mod.files {
console.print_debug("mod file write ${file.name}")
console.print_debug('mod file write ${file.name}')
file.write(module_dir.path, options)!
}
for folder in mod.folders {
console.print_debug("mod folder write ${folder.name}")
console.print_debug('mod folder write ${folder.name}')
folder.write('${path}/${mod.name}', options)!
}
for mod_ in mod.modules {
console.print_debug("mod write ${mod_.name}")
console.print_debug('mod write ${mod_.name}')
mod_.write('${path}/${mod.name}', options)!
}
if options.format {
console.print_debug("format ${module_dir.path}")
console.print_debug('format ${module_dir.path}')
os.execute('v fmt -w ${module_dir.path}')
}
if options.compile {
console.print_debug("compile shared ${module_dir.path}")
os.execute_opt('${pre} -shared ${module_dir.path}') or {
log.fatal(err.msg())
}
console.print_debug('compile shared ${module_dir.path}')
os.execute_opt('${pre} -shared ${module_dir.path}') or { log.fatal(err.msg()) }
}
if options.test {
console.print_debug("test ${module_dir.path}")
os.execute_opt('${pre} test ${module_dir.path}') or {
log.fatal(err.msg())
}
console.print_debug('test ${module_dir.path}')
os.execute_opt('${pre} test ${module_dir.path}') or { log.fatal(err.msg()) }
}
if options.document {
docs_path := '${path}/${mod.name}/docs'
console.print_debug("document ${module_dir.path}")
console.print_debug('document ${module_dir.path}')
os.execute('v doc -f html -o ${docs_path} ${module_dir.path}')
}

View File

@@ -4,18 +4,18 @@ import freeflowuniverse.herolib.core.texttools
pub struct Param {
pub mut:
required bool @[omitempty]
mutable bool @[omitempty]
is_shared bool @[omitempty]
is_optional bool @[omitempty]
is_result bool @[omitempty]
description string @[omitempty]
name string @[omitempty]
typ Type @[omitempty]
required bool @[omitempty]
mutable bool @[omitempty]
is_shared bool @[omitempty]
is_optional bool @[omitempty]
is_result bool @[omitempty]
description string @[omitempty]
name string @[omitempty]
typ Type @[omitempty]
}
@[params]
pub struct Params{
pub struct Params {
pub:
v string
}
@@ -37,7 +37,7 @@ pub fn (param Param) vgen() string {
pub fn (p Param) typescript() string {
name := texttools.camel_case(p.name)
suffix := if p.is_optional {'?'} else {''}
suffix := if p.is_optional { '?' } else { '' }
return '${name}${suffix}: ${p.typ.typescript()}'
}
@@ -45,9 +45,13 @@ pub fn parse_param(code_ string) !Param {
mut code := code_.trim_space()
if code == '!' {
return Param{is_result: true}
return Param{
is_result: true
}
} else if code == '?' {
return Param{is_optional: true}
return Param{
is_optional: true
}
}
is_mut := code.starts_with('mut ')
@@ -59,7 +63,7 @@ pub fn parse_param(code_ string) !Param {
if split.len == 1 {
// means anonymous param
return Param{
typ: type_from_symbol(split[0])
typ: type_from_symbol(split[0])
mutable: is_mut
}
}
@@ -67,8 +71,8 @@ pub fn parse_param(code_ string) !Param {
return error('invalid param format: ${code_}')
}
return Param{
name: split[0]
typ: type_from_symbol(split[1])
name: split[0]
typ: type_from_symbol(split[1])
mutable: is_mut
}
}

View File

@@ -33,7 +33,9 @@ pub fn (struct_ Struct) vgen() string {
comments := if struct_.description.trim_space() != '' {
'// ${struct_.description.trim_space()}'
} else {''}
} else {
''
}
priv_fields := struct_.fields.filter(!it.is_mut && !it.is_pub).map(it.vgen())
pub_fields := struct_.fields.filter(!it.is_mut && it.is_pub).map(it.vgen())
@@ -51,16 +53,15 @@ pub fn (struct_ Struct) vgen() string {
return struct_str
}
pub struct Interface {
pub mut:
name string
description string
is_pub bool
embeds []Interface @[str: skip]
embeds []Interface @[str: skip]
attrs []Attribute
fields []StructField
methods []Function
methods []Function
}
pub fn (iface Interface) vgen() string {
@@ -104,8 +105,8 @@ pub mut:
is_pub bool
is_mut bool
is_ref bool
anon_struct Struct @[str: skip] // sometimes fields may hold anonymous structs
structure Struct @[str: skip]
anon_struct Struct @[str: skip] // sometimes fields may hold anonymous structs
structure Struct @[str: skip]
}
pub fn (field StructField) vgen() string {
@@ -133,4 +134,4 @@ pub fn (s Struct) typescript() string {
name := texttools.pascal_case(s.name)
fields := s.fields.map(it.typescript()).join_lines()
return 'export interface ${name} {\n${fields}\n}'
}
}

View File

@@ -1,56 +1,65 @@
module code
struct Float {
bytes int
bytes int
}
// Integer types
pub const type_i8 = Integer{
bytes: 8
bytes: 8
}
pub const type_u8 = Integer{
bytes: 8
signed: false
bytes: 8
signed: false
}
pub const type_i16 = Integer{
bytes: 16
bytes: 16
}
pub const type_u16 = Integer{
bytes: 16
signed: false
bytes: 16
signed: false
}
pub const type_i32 = Integer{
bytes: 32
bytes: 32
}
pub const type_u32 = Integer{
bytes: 32
signed: false
bytes: 32
signed: false
}
pub const type_i64 = Integer{
bytes: 64
bytes: 64
}
pub const type_u64 = Integer{
bytes: 64
signed: false
bytes: 64
signed: false
}
// Floating-point types
pub const type_f32 = Float{
bytes: 32
bytes: 32
}
pub const type_f64 = Float{
bytes: 64
bytes: 64
}
pub type Type = Void | Map | Array | Object | Result | Integer | Alias | String | Boolean | Function
pub type Type = Void
| Map
| Array
| Object
| Result
| Integer
| Alias
| String
| Boolean
| Function
pub struct Alias {
pub:
@@ -59,12 +68,12 @@ pub:
typ Type
}
pub struct Boolean{}
pub struct Boolean {}
pub struct Void{}
pub struct Void {}
pub struct Integer {
bytes u8
bytes u8
signed bool = true
}
@@ -84,26 +93,44 @@ pub fn type_from_symbol(symbol_ string) Type {
pub fn (t Type) symbol() string {
return match t {
Array { '[]${t.typ.symbol()}' }
Object { t.name }
Result { '!${t.typ.symbol()}'}
Array {
'[]${t.typ.symbol()}'
}
Object {
t.name
}
Result {
'!${t.typ.symbol()}'
}
Integer {
mut str := ''
if !t.signed {
str += 'u'
}
if t.bytes != 0 {
'${str}${t.bytes}'
} else {
'${str}int'
}
}
Alias {t.name}
String {'string'}
Boolean {'bool'}
Map{'map[string]${t.typ.symbol()}'}
Function{'fn ()'}
Void {''}
mut str := ''
if !t.signed {
str += 'u'
}
if t.bytes != 0 {
'${str}${t.bytes}'
} else {
'${str}int'
}
}
Alias {
t.name
}
String {
'string'
}
Boolean {
'bool'
}
Map {
'map[string]${t.typ.symbol()}'
}
Function {
'fn ()'
}
Void {
''
}
}
}
@@ -131,16 +158,16 @@ pub:
pub fn (t Type) typescript() string {
return match t {
Map {'Record<string, ${t.typ.typescript()}>'}
Map { 'Record<string, ${t.typ.typescript()}>' }
Array { '${t.typ.typescript()}[]' }
Object { t.name }
Result { '${t.typ.typescript()}'}
Boolean { 'boolean'}
Result { '${t.typ.typescript()}' }
Boolean { 'boolean' }
Integer { 'number' }
Alias {t.name}
String {'string'}
Function {'func'}
Void {''}
Alias { t.name }
String { 'string' }
Function { 'func' }
Void { '' }
}
}
@@ -151,15 +178,39 @@ pub fn (t Type) vgen() string {
pub fn (t Type) empty_value() string {
return match t {
Map {'{}'}
Array { '[]${t.typ.symbol()}{}' }
Object { if t.name != '' {'${t.name}{}'} else {''} }
Result { t.typ.empty_value() }
Boolean { 'false' }
Integer { '0' }
Alias {''}
String {"''"}
Function {''}
Void {''}
Map {
'{}'
}
Array {
'[]${t.typ.symbol()}{}'
}
Object {
if t.name != '' {
'${t.name}{}'
} else {
''
}
}
Result {
t.typ.empty_value()
}
Boolean {
'false'
}
Integer {
'0'
}
Alias {
''
}
String {
"''"
}
Function {
''
}
Void {
''
}
}
}
}

View File

@@ -11,11 +11,10 @@ pub:
overwrite bool
document bool
prefix string
compile bool // whether to compile the written code
test bool // whether to test the written code
compile bool // whether to compile the written code
test bool // whether to test the written code
}
interface ICodeItem {
vgen() string
}
@@ -53,7 +52,6 @@ pub fn (import_ Import) vgen() string {
return 'import ${import_.mod} ${types_str}'
}
pub fn vgen_generics(generics map[string]string) string {
if generics.keys().len == 0 {
return ''
@@ -67,4 +65,4 @@ pub fn vgen_generics(generics map[string]string) string {
pub fn (custom CustomCode) vgen() string {
return custom.text
}
}