package main import ( "flag" "strings" _ "embed" logger "git.site.quack-lab.dev/dave/cylogger" utils "git.site.quack-lab.dev/dave/cyutils" ) func main() { outdir := flag.String("o", ".", "Output directory") flag.Parse() logger.InitFlag() logger.Info("Starting...") files := flag.Args() if len(files) == 0 { logger.Error("No files specified") flag.Usage() return } // TODO: Implement parsing enums somehow // TODO: Implement some sort of switching (between a class and an enum) utils.WithWorkers(10, files, func(worker int, file string) { class, err := ParseClass(file) if err != nil { logger.Error("Error parsing file: %v", err) return } class.Write(*outdir, classTemplate) }) } func MapType(t string) string { // Handle complex types like table if strings.Contains(t, "<") && strings.Contains(t, ">") { // Extract the base type and inner types openBracket := strings.Index(t, "<") closeBracket := strings.LastIndex(t, ">") if openBracket != -1 && closeBracket != -1 { baseType := t[:openBracket] innerTypes := t[openBracket+1 : closeBracket] // Split inner types by comma, but be careful about nested brackets var mappedInnerTypes []string var current strings.Builder bracketDepth := 0 for i := 0; i < len(innerTypes); i++ { char := innerTypes[i] if char == '<' { bracketDepth++ current.WriteByte(char) } else if char == '>' { bracketDepth-- current.WriteByte(char) } else if char == ',' && bracketDepth == 0 { // Only split on commas that are not inside nested brackets mappedInnerTypes = append(mappedInnerTypes, MapType(strings.TrimSpace(current.String()))) current.Reset() } else { current.WriteByte(char) } } // Add the last inner type if current.Len() > 0 { mappedInnerTypes = append(mappedInnerTypes, MapType(strings.TrimSpace(current.String()))) } // Reconstruct the complex type return baseType + "<" + strings.Join(mappedInnerTypes, ", ") + ">" } } // Handle simple types switch t { case "var": return "any" case "var...": return "..." case "int": return "number" case "int...": return "number..." case "unsigned int": return "number" case "float": return "number" case "double": return "number" case "bool": return "boolean" case "char": return "string" case "table_t": return "table" default: return t } } func IsReservedKeyword(t string) bool { switch t { case "and", "break", "do", "else", "elseif", "end", "false", "for", "function", "if", "in", "local", "nil", "not", "or", "repeat", "return", "then", "true", "until", "while", "any", "boolean", "number", "string", "table", "thread", "userdata", "var": return true } return false }