cgen: replace reserved C keywords in identifiers
parent
2efc37947d
commit
89af7e7a5b
|
@ -8,6 +8,16 @@ import (
|
|||
term
|
||||
)
|
||||
|
||||
const (
|
||||
c_reserved = ['delete', 'exit', 'unix',
|
||||
// 'print',
|
||||
// 'ok',
|
||||
'error', 'calloc', 'free', 'panic',
|
||||
// 'malloc',
|
||||
// Full list of C reserved words, from: https://en.cppreference.com/w/c/keyword
|
||||
'auto', 'char', 'default', 'do', 'double', 'extern', 'float', 'inline', 'int', 'long', 'register', 'restrict', 'short', 'signed', 'sizeof', 'static', 'switch', 'typedef', 'union', 'unsigned', 'void', 'volatile', 'while', ]
|
||||
)
|
||||
|
||||
struct Gen {
|
||||
out strings.Builder
|
||||
typedefs strings.Builder
|
||||
|
@ -152,7 +162,12 @@ pub fn (g mut Gen) write_typedef_types() {
|
|||
info := typ.info as table.FnType
|
||||
func := info.func
|
||||
if !info.has_decl && !info.is_anon {
|
||||
fn_name := func.name.replace('.', '__')
|
||||
fn_name := if func.is_c {
|
||||
func.name.replace('.', '__')
|
||||
}
|
||||
else {
|
||||
c_name(func.name)
|
||||
}
|
||||
g.definitions.write('typedef ${g.typ(func.return_type)} (*$fn_name)(')
|
||||
for i, arg in func.args {
|
||||
g.definitions.write(g.typ(arg.typ))
|
||||
|
@ -395,7 +410,12 @@ fn (g mut Gen) stmt(node ast.Stmt) {
|
|||
g.return_statement(it)
|
||||
}
|
||||
ast.StructDecl {
|
||||
name := it.name.replace('.', '__')
|
||||
name := if it.is_c {
|
||||
it.name.replace('.', '__')
|
||||
}
|
||||
else {
|
||||
c_name(it.name)
|
||||
}
|
||||
// g.writeln('typedef struct {')
|
||||
// for field in it.fields {
|
||||
// field_type_sym := g.table.get_type_symbol(field.typ)
|
||||
|
@ -560,16 +580,15 @@ fn (g mut Gen) gen_fn_decl(it ast.FnDecl) {
|
|||
if it.is_method {
|
||||
name = g.table.get_type_symbol(it.receiver.typ).name + '_' + name
|
||||
}
|
||||
if it.is_c {
|
||||
name = name.replace('.', '__')
|
||||
}
|
||||
else {
|
||||
name = c_name(name)
|
||||
}
|
||||
if name.starts_with('_op_') {
|
||||
name = op_to_fn_name(name)
|
||||
}
|
||||
if name == 'exit' {
|
||||
name = 'v_exit'
|
||||
}
|
||||
if name == 'free' {
|
||||
name = 'v_free'
|
||||
}
|
||||
// type_name := g.table.type_to_str(it.return_type)
|
||||
type_name := g.typ(it.return_type)
|
||||
g.write('$type_name ${name}(')
|
||||
|
@ -984,7 +1003,8 @@ fn (g mut Gen) expr(node ast.Expr) {
|
|||
g.writeln('($styp){')
|
||||
}
|
||||
for i, field in it.fields {
|
||||
g.write('\t.$field = ')
|
||||
field_name := c_name(field)
|
||||
g.write('\t.$field_name = ')
|
||||
g.expr_with_cast(it.exprs[i], it.expr_types[i], it.expected_types[i])
|
||||
g.writeln(', ')
|
||||
}
|
||||
|
@ -1009,7 +1029,7 @@ fn (g mut Gen) expr(node ast.Expr) {
|
|||
if it.expr_type == 0 {
|
||||
verror('cgen: SelectorExpr typ=0 field=$it.field')
|
||||
}
|
||||
g.write(it.field)
|
||||
g.write(c_name(it.field))
|
||||
}
|
||||
ast.Type {
|
||||
// match sum Type
|
||||
|
@ -1246,14 +1266,14 @@ fn (g mut Gen) match_expr(node ast.MatchExpr) {
|
|||
}
|
||||
|
||||
fn (g mut Gen) ident(node ast.Ident) {
|
||||
name := node.name.replace('.', '__')
|
||||
if name == 'lld' {
|
||||
if node.name == 'lld' {
|
||||
return
|
||||
}
|
||||
if name.starts_with('C__') {
|
||||
g.write(name[3..])
|
||||
if node.name.starts_with('C.') {
|
||||
g.write(node.name[2..].replace('.', '__'))
|
||||
}
|
||||
else {
|
||||
name := c_name(node.name)
|
||||
// TODO `is`
|
||||
match node.info {
|
||||
ast.IdentVar {
|
||||
|
@ -1524,7 +1544,7 @@ fn (g mut Gen) return_statement(it ast.Return) {
|
|||
|
||||
fn (g mut Gen) const_decl(node ast.ConstDecl) {
|
||||
for i, field in node.fields {
|
||||
name := field.name.replace('.', '__')
|
||||
name := c_name(field.name)
|
||||
expr := node.exprs[i]
|
||||
// TODO hack. Cut the generated value and paste it into definitions.
|
||||
pos := g.out.len
|
||||
|
@ -1562,7 +1582,8 @@ fn (g mut Gen) assoc(node ast.Assoc) {
|
|||
styp := g.typ(node.typ)
|
||||
g.writeln('($styp){')
|
||||
for i, field in node.fields {
|
||||
g.write('\t.$field = ')
|
||||
field_name := c_name(field)
|
||||
g.write('\t.$field_name = ')
|
||||
g.expr(node.exprs[i])
|
||||
g.writeln(', ')
|
||||
}
|
||||
|
@ -1573,7 +1594,8 @@ fn (g mut Gen) assoc(node ast.Assoc) {
|
|||
if field.name in node.fields {
|
||||
continue
|
||||
}
|
||||
g.writeln('\t.$field.name = ${node.var_name}.$field.name,')
|
||||
field_name := c_name(field.name)
|
||||
g.writeln('\t.$field_name = ${node.var_name}.$field_name,')
|
||||
}
|
||||
g.write('}')
|
||||
if g.is_amp {
|
||||
|
@ -1731,7 +1753,8 @@ fn (g mut Gen) write_types(types []table.TypeSymbol) {
|
|||
g.definitions.writeln('struct $name {')
|
||||
for field in info.fields {
|
||||
type_name := g.typ(field.typ)
|
||||
g.definitions.writeln('\t$type_name $field.name;')
|
||||
field_name := c_name(field.name)
|
||||
g.definitions.writeln('\t$type_name $field_name;')
|
||||
}
|
||||
// g.definitions.writeln('} $name;\n')
|
||||
//
|
||||
|
@ -1882,18 +1905,15 @@ fn (g mut Gen) gen_filter(node ast.MethodCallExpr) {
|
|||
}
|
||||
|
||||
fn (g mut Gen) call_expr(it ast.CallExpr) {
|
||||
mut name := it.name.replace('.', '__')
|
||||
if name == 'exit' {
|
||||
name = 'v_exit'
|
||||
}
|
||||
if name == 'free' {
|
||||
name = 'v_free'
|
||||
}
|
||||
mut name := it.name
|
||||
is_print := name == 'println'
|
||||
if it.is_c {
|
||||
// Skip "C__"
|
||||
// Skip "C."
|
||||
g.is_c_call = true
|
||||
name = name[3..]
|
||||
name = name[2..].replace('.', '__')
|
||||
}
|
||||
else {
|
||||
name = c_name(name)
|
||||
}
|
||||
// Generate tmp vars for values that have to be freed.
|
||||
/*
|
||||
|
@ -2046,3 +2066,12 @@ fn comp_if_to_ifdef(name string) string {
|
|||
// verror('bad os ifdef name "$name"')
|
||||
return ''
|
||||
}
|
||||
|
||||
[inline]
|
||||
fn c_name(name_ string) string {
|
||||
name := name_.replace('.', '__')
|
||||
if name in c_reserved {
|
||||
return 'v_$name'
|
||||
}
|
||||
return name
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue