206 lines
4.1 KiB
V
206 lines
4.1 KiB
V
module codemodel
|
|
|
|
import freeflowuniverse.herolib.core.pathlib
|
|
// Code is a list of statements
|
|
// pub type Code = []CodeItem
|
|
|
|
pub type CodeItem = Alias | Comment | CustomCode | Function | Import | Struct | Sumtype
|
|
|
|
// item for adding custom code in
|
|
pub struct CustomCode {
|
|
pub:
|
|
text string
|
|
}
|
|
|
|
pub struct Comment {
|
|
pub:
|
|
text string
|
|
is_multi bool
|
|
}
|
|
|
|
pub struct Struct {
|
|
pub mut:
|
|
name string
|
|
description string
|
|
mod string
|
|
is_pub bool
|
|
embeds []Struct @[str: skip]
|
|
generics map[string]string @[str: skip]
|
|
attrs []Attribute
|
|
fields []StructField
|
|
}
|
|
|
|
pub struct Sumtype {
|
|
pub:
|
|
name string
|
|
description string
|
|
types []Type
|
|
}
|
|
|
|
pub struct StructField {
|
|
pub mut:
|
|
comments []Comment
|
|
attrs []Attribute
|
|
name string
|
|
description string
|
|
default string
|
|
is_pub bool
|
|
is_mut bool
|
|
is_ref bool
|
|
anon_struct Struct @[str: skip] // sometimes fields may hold anonymous structs
|
|
typ Type
|
|
structure Struct @[str: skip]
|
|
}
|
|
|
|
pub struct Attribute {
|
|
pub:
|
|
name string // [name]
|
|
has_arg bool
|
|
arg string // [name: arg]
|
|
}
|
|
|
|
pub struct Function {
|
|
pub:
|
|
name string
|
|
receiver Param
|
|
is_pub bool
|
|
mod string
|
|
pub mut:
|
|
description string
|
|
params []Param
|
|
body string
|
|
result Result
|
|
has_return bool
|
|
}
|
|
|
|
pub fn parse_function(code_ string) !Function {
|
|
mut code := code_.trim_space()
|
|
is_pub := code.starts_with('pub ')
|
|
if is_pub {
|
|
code = code.trim_string_left('pub ').trim_space()
|
|
}
|
|
|
|
is_fn := code.starts_with('fn ')
|
|
if !is_fn {
|
|
return error('invalid function format')
|
|
}
|
|
code = code.trim_string_left('fn ').trim_space()
|
|
|
|
receiver := if code.starts_with('(') {
|
|
param_str := code.all_after('(').all_before(')').trim_space()
|
|
code = code.all_after(')').trim_space()
|
|
parse_param(param_str)!
|
|
} else {
|
|
Param{}
|
|
}
|
|
|
|
name := code.all_before('(').trim_space()
|
|
code = code.trim_string_left(name).trim_space()
|
|
|
|
params_str := code.all_after('(').all_before(')')
|
|
params := if params_str.trim_space() != '' {
|
|
params_str_lst := params_str.split(',')
|
|
params_str_lst.map(parse_param(it)!)
|
|
} else {
|
|
[]Param{}
|
|
}
|
|
result := parse_result(code.all_after(')').all_before('{').replace(' ', ''))!
|
|
|
|
body := if code.contains('{') { code.all_after('{').all_before_last('}') } else { '' }
|
|
return Function{
|
|
name: name
|
|
receiver: receiver
|
|
params: params
|
|
result: result
|
|
body: body
|
|
}
|
|
}
|
|
|
|
pub fn parse_param(code_ string) !Param {
|
|
mut code := code_.trim_space()
|
|
is_mut := code.starts_with('mut ')
|
|
if is_mut {
|
|
code = code.trim_string_left('mut ').trim_space()
|
|
}
|
|
split := code.split(' ').filter(it != '')
|
|
if split.len != 2 {
|
|
return error('invalid param format: ${code_}')
|
|
}
|
|
return Param{
|
|
name: split[0]
|
|
typ: Type{
|
|
symbol: split[1]
|
|
}
|
|
mutable: is_mut
|
|
}
|
|
}
|
|
|
|
pub fn parse_result(code_ string) !Result {
|
|
code := code_.replace(' ', '').trim_space()
|
|
|
|
return Result{
|
|
result: code_.starts_with('!')
|
|
optional: code_.starts_with('?')
|
|
typ: Type{
|
|
symbol: code.trim('!?')
|
|
is_optional: code.starts_with('?')
|
|
is_result: code.starts_with('!')
|
|
}
|
|
}
|
|
}
|
|
|
|
pub struct Param {
|
|
pub:
|
|
required bool
|
|
mutable bool
|
|
is_shared bool
|
|
is_optional bool
|
|
description string
|
|
name string
|
|
typ Type
|
|
struct_ Struct
|
|
}
|
|
|
|
pub struct Result {
|
|
pub mut:
|
|
typ Type
|
|
description string
|
|
name string
|
|
result bool // whether is result type
|
|
optional bool // whether is result type
|
|
structure Struct
|
|
}
|
|
|
|
// todo: maybe make 'is_' fields methods?
|
|
pub struct Type {
|
|
pub mut:
|
|
is_reference bool @[str: skip]
|
|
is_map bool @[str: skip]
|
|
is_array bool
|
|
is_mutable bool @[str: skip]
|
|
is_shared bool @[str: skip]
|
|
is_optional bool @[str: skip]
|
|
is_result bool @[str: skip]
|
|
symbol string
|
|
mod string @[str: skip]
|
|
}
|
|
|
|
pub struct File {
|
|
pub mut:
|
|
name string
|
|
extension string
|
|
content string
|
|
}
|
|
|
|
pub fn (f File) write(path string) ! {
|
|
mut fd_file := pathlib.get_file(path: '${path}/${f.name}.${f.extension}')!
|
|
fd_file.write(f.content)!
|
|
}
|
|
|
|
pub struct Alias {
|
|
pub:
|
|
name string
|
|
description string
|
|
typ Type
|
|
}
|