Initial project import

This commit is contained in:
Agila Forge Importer committed 2026-07-13 15:20:32 +00:00
commit 23f2d29e32
11957 files changed
+1754577

No files matched your search

+126
View File
@@ -0,0 +1,126 @@
module c
import strings
const c_reserved_words = ['auto', 'break', 'case', 'char', 'const', 'continue', 'copy', 'default',
'do', 'double', 'else', 'enum', 'extern', 'float', 'for', 'goto', 'if', 'inline', 'int', 'long',
'register', 'restrict', 'return', 'short', 'signed', 'sizeof', 'static', 'struct', 'switch',
'typedef', 'union', 'unsigned', 'void', 'volatile', 'while']
fn c_name(name string) string {
if name.starts_with('C.') {
return name[2..]
}
if name == 'malloc' {
return 'v_malloc'
}
// The V builtin `exit` wraps `C.exit`; both lower to the C symbol `exit`.
// Rename the V function (and its call sites) to `v_exit` so its body's
// `C.exit(code)` call resolves to libc `exit` instead of recursing forever.
// `C.exit` itself is handled by the `C.` strip above, so it stays `exit`.
if name == 'exit' {
return 'v_exit'
}
if c_name_is_plain(name) {
if name in c_reserved_words {
return 'v_${name}'
}
return name
}
n := c_name_sanitize(name)
if n in c_reserved_words {
return 'v_${n}'
}
return n
}
fn c_name_sanitize(name string) string {
mut b := strings.new_builder(name.len + 8)
mut i := 0
for i < name.len {
c := name[i]
if c == `[` {
if i + 1 < name.len && name[i + 1] == `]` {
b.write_string('Array_')
i += 2
continue
}
b.write_u8(`_`)
} else if c == `]` {
i++
continue
} else if c == `.` {
if i + 1 < name.len {
next := name[i + 1]
if next == `-` {
b.write_string('__minus')
i += 2
continue
}
if next == `+` {
b.write_string('__plus')
i += 2
continue
}
if i + 2 < name.len {
op := name[i + 2]
if next == `=` && op == `=` {
b.write_string('__eq')
i += 3
continue
}
if next == `!` && op == `=` {
b.write_string('__ne')
i += 3
continue
}
if next == `<` && op == `=` {
b.write_string('__le')
i += 3
continue
}
if next == `>` && op == `=` {
b.write_string('__ge')
i += 3
continue
}
}
if next == `<` {
b.write_string('__lt')
i += 2
continue
}
if next == `>` {
b.write_string('__gt')
i += 2
continue
}
}
b.write_string('__')
} else if c == `&` {
b.write_string('ptr')
} else if c == `,` || c == ` ` {
b.write_u8(`_`)
} else {
b.write_u8(c)
}
i++
}
return b.str()
}
fn c_name_is_plain(name string) bool {
for i in 0 .. name.len {
c := name[i]
if (c >= `a` && c <= `z`) || (c >= `A` && c <= `Z`) || (c >= `0` && c <= `9`) || c == `_` {
continue
}
return false
}
return true
}
fn c_escape(s string) string {
return s.replace('\\', '\\\\').replace('"', '\\"').replace('\n', '\\n').replace('\t', '\\t').replace('\r',
'\\r')
}