Initial project import
This commit is contained in:
commit
23f2d29e32
11957 files changed
+1754577
No files matched your search
@@ -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')
|
||||
}
|
||||
Reference in new issue
Block a user