This commit is contained in:
2025-11-23 08:29:37 +01:00
parent 01639853ce
commit 4402cba8ac
8 changed files with 198 additions and 42 deletions

View File

@@ -11,6 +11,7 @@ pub type CodeItem = Alias
| Struct
| Sumtype
| Interface
| Enum
// item for adding custom code in
pub struct CustomCode {
@@ -31,6 +32,21 @@ pub:
types []Type
}
pub struct Enum {
pub mut:
name string
description string
is_pub bool
values []EnumValue
}
pub struct EnumValue {
pub:
name string
value string
description string
}
pub struct Attribute {
pub:
name string // [name]

View File

@@ -0,0 +1,96 @@
module code
pub fn parse_enum(code_ string) !Enum {
mut lines := code_.split_into_lines()
mut comment_lines := []string{}
mut enum_lines := []string{}
mut in_enum := false
mut enum_name := ''
mut is_pub := false
for line in lines {
trimmed := line.trim_space()
if !in_enum && trimmed.starts_with('//') {
comment_lines << trimmed.trim_string_left('//').trim_space()
} else if !in_enum && (trimmed.starts_with('enum ') || trimmed.starts_with('pub enum ')) {
in_enum = true
enum_lines << line
// Extract enum name
is_pub = trimmed.starts_with('pub ')
mut name_part := if is_pub {
trimmed.trim_string_left('pub enum ').trim_space()
} else {
trimmed.trim_string_left('enum ').trim_space()
}
if name_part.contains('{') {
enum_name = name_part.all_before('{').trim_space()
} else {
enum_name = name_part
}
} else if in_enum {
enum_lines << line
if trimmed.starts_with('}') {
break
}
}
}
if enum_name == '' {
return error('Invalid enum format: could not extract enum name')
}
// Process enum values
mut values := []EnumValue{}
for i := 1; i < enum_lines.len - 1; i++ {
line := enum_lines[i].trim_space()
// Skip empty lines and comments
if line == '' || line.starts_with('//') {
continue
}
// Parse enum value
parts := line.split('=').map(it.trim_space())
value_name := parts[0]
value_content := if parts.len > 1 { parts[1] } else { '' }
values << EnumValue{
name: value_name
value: value_content
}
}
// Process comments into description
description := comment_lines.join('\n')
return Enum{
name: enum_name
description: description
is_pub: is_pub
values: values
}
}
pub fn (e Enum) vgen() string {
prefix := if e.is_pub { 'pub ' } else { '' }
comments := if e.description.trim_space() != '' {
'// ${e.description.trim_space()}\n'
} else {
''
}
mut values_str := ''
for value in e.values {
if value.value != '' {
values_str += '\n\t${value.name} = ${value.value}'
} else {
values_str += '\n\t${value.name}'
}
}
return '${comments}${prefix}enum ${e.name} {${values_str}\n}'
}

View File

@@ -165,8 +165,16 @@ pub fn (file VFile) structs() []Struct {
return file.items.filter(it is Struct).map(it as Struct)
}
pub fn (file VFile) enums() []Enum {
return file.items.filter(it is Enum).map(it as Enum)
}
pub fn (file VFile) interfaces() []Interface {
return file.items.filter(it is Interface).map(it as Interface)
}
// parse_vfile parses V code into a VFile struct
// It extracts the module name, imports, constants, structs, and functions
// It extracts the module name, imports, constants, structs, functions, enums and interfaces
pub fn parse_vfile(code string) !VFile {
mut vfile := VFile{
content: code
@@ -195,7 +203,7 @@ pub fn parse_vfile(code string) !VFile {
// Extract constants
vfile.consts = parse_consts(code) or { []Const{} }
// Split code into chunks for parsing structs and functions
// Split code into chunks for parsing structs, functions, enums, and interfaces
mut chunks := []string{}
mut current_chunk := ''
mut brace_count := 0
@@ -211,9 +219,12 @@ pub fn parse_vfile(code string) !VFile {
continue
}
// Check for struct or function start
// Check for struct, enum, interface or function start
if (trimmed.starts_with('struct ') || trimmed.starts_with('pub struct ')
|| trimmed.starts_with('fn ') || trimmed.starts_with('pub fn ')) && !in_struct_or_fn {
|| trimmed.starts_with('enum ') || trimmed.starts_with('pub enum ')
|| trimmed.starts_with('interface ')
|| trimmed.starts_with('pub interface ') || trimmed.starts_with('fn ')
|| trimmed.starts_with('pub fn ')) && !in_struct_or_fn {
in_struct_or_fn = true
current_chunk = comment_block.join('\n')
if current_chunk != '' {
@@ -238,7 +249,7 @@ pub fn parse_vfile(code string) !VFile {
continue
}
// Add line to current chunk if we're inside a struct or function
// Add line to current chunk if we're inside a struct, enum, interface or function
if in_struct_or_fn {
current_chunk += '\n' + line
@@ -249,7 +260,7 @@ pub fn parse_vfile(code string) !VFile {
brace_count -= line.count('}')
}
// Check if we've reached the end of the struct or function
// Check if we've reached the end
if brace_count == 0 {
chunks << current_chunk
current_chunk = ''
@@ -269,6 +280,16 @@ pub fn parse_vfile(code string) !VFile {
continue
}
vfile.items << struct_obj
} else if trimmed.contains('enum ') || trimmed.contains('pub enum ') {
// Parse enum
enum_obj := parse_enum(chunk) or {
// Skip invalid enums
continue
}
vfile.items << enum_obj
} else if trimmed.contains('interface ') || trimmed.contains('pub interface ') {
// Parse interface - TODO: implement when needed
continue
} else if trimmed.contains('fn ') || trimmed.contains('pub fn ') {
// Parse function
fn_obj := parse_function(chunk) or {