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

@@ -1,29 +1,8 @@
#!/usr/bin/env -S v -n -w -gc none -cc tcc -d use_openssl -enable-globals run
import incubaid.herolib.ai.client
import incubaid.herolib.ai.flow_calendar
mut cl := client.new()!
prompt = 'Explain quantum computing in simple terms'
// response := cl.llms.llm_local.chat_completion(
// message: 'Explain quantum computing in simple terms'
// temperature: 0.5
// max_completion_tokens: 1024
// )!
response := cl.llms.llm_maverick.chat_completion(
message: 'Explain quantum computing in simple terms'
temperature: 0.5
max_completion_tokens: 1024
)!
println(response)
// response := cl.llms.llm_embed_local.embed(input: [
// 'The food was delicious and the waiter..',
// ])!
// response2 := cl.llms.llm_embed.embed(input: [
// 'The food was delicious and the waiter..',
// ])!
println(response2)
flow_calendar.start(mut coordinator, prompt)!

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 {

View File

@@ -0,0 +1,27 @@
module codegenerator
@[params]
pub struct GeneratorOptions {
pub:
parser_path string @[required]
output_dir string @[required]
recursive bool = true
format bool = true
}
pub fn new(args GeneratorOptions) !CodeGenerator {
import incubaid.herolib.core.codeparser
mut parser := codeparser.new(
path: args.parser_path
recursive: args.recursive
)!
parser.parse()!
return CodeGenerator{
parser: parser
output_dir: args.output_dir
format: args.format
}
}

View File

@@ -77,7 +77,7 @@ fn copy_directory(src string, dst string) ! {
fn test_module_parsing() {
console.print_header('Test 1: Module and File Parsing')
mut myparser := new('/tmp/codeparsertest', recursive: true)!
mut myparser := new(path: '/tmp/codeparsertest', recursive: true)!
myparser.parse()!
v_files := myparser.list_files()
@@ -148,7 +148,7 @@ fn test_struct_parsing() {
fn test_function_parsing() {
console.print_header('Test 3: Function Parsing')
mut myparser := new('/tmp/codeparsertest', recursive: true)!
mut myparser := new(path: '/tmp/codeparsertest', recursive: true)!
myparser.parse()!
mut functions := []code.Function{}
@@ -296,7 +296,7 @@ fn test_visibility_modifiers() {
fn test_method_parsing() {
console.print_header('Test 7: Method Parsing')
mut myparser := new('/tmp/codeparsertest', recursive: true)!
mut myparser := new(path: '/tmp/codeparsertest', recursive: true)!
myparser.parse()!
mut methods := []code.Function{}

View File

@@ -1,7 +1,7 @@
module codeparser
import incubaid.herolib.core.pathlib
import incubaid.herolib.core.code
// import incubaid.herolib.core.pathlib
// import incubaid.herolib.core.code
@[params]
pub struct ParserOptions {

View File

@@ -27,6 +27,7 @@ pub:
structs []StructJSON
functions []FunctionJSON
interfaces []InterfaceJSON
enums []EnumJSON
constants []ConstJSON
}
@@ -54,6 +55,14 @@ pub:
description string
}
pub struct EnumJSON {
pub:
name string
is_pub bool
value_count int
description string
}
pub struct ConstJSON {
pub:
name string
@@ -67,6 +76,7 @@ pub mut:
total_structs int
total_functions int
total_interfaces int
total_enums int
}
// to_json exports the complete code structure to JSON
@@ -140,6 +150,17 @@ pub fn (parser CodeParser) to_json(module_name string) !string {
}
}
// Build enums JSON
mut enums_json := []EnumJSON{}
for enum_ in vfile.enums() {
enums_json << EnumJSON{
name: enum_.name
is_pub: enum_.is_pub
value_count: enum_.values.len
description: enum_.description
}
}
// Build constants JSON
mut consts_json := []ConstJSON{}
for const_ in vfile.consts {
@@ -156,6 +177,7 @@ pub fn (parser CodeParser) to_json(module_name string) !string {
structs: structs_json
functions: functions_json
interfaces: interfaces_json
enums: enums_json
constants: consts_json
}
@@ -172,6 +194,7 @@ pub fn (parser CodeParser) to_json(module_name string) !string {
result.summary.total_structs += structs_json.len
result.summary.total_functions += functions_json.len
result.summary.total_interfaces += interfaces_json.len
result.summary.total_enums += enums_json.len
}
}
@@ -180,11 +203,5 @@ pub fn (parser CodeParser) to_json(module_name string) !string {
result.summary.total_modules++
}
// mut total_files := 0
// for module in result.modules.values() {
// total_files += module.stats.file_count
// }
// result.summary.total_files = total_files
return json.encode_pretty(result)
}