cgen: replace reserved C keywords in identifiers
parent
2efc37947d
commit
89af7e7a5b
|
@ -8,6 +8,16 @@ import (
|
||||||
term
|
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 {
|
struct Gen {
|
||||||
out strings.Builder
|
out strings.Builder
|
||||||
typedefs strings.Builder
|
typedefs strings.Builder
|
||||||
|
@ -152,7 +162,12 @@ pub fn (g mut Gen) write_typedef_types() {
|
||||||
info := typ.info as table.FnType
|
info := typ.info as table.FnType
|
||||||
func := info.func
|
func := info.func
|
||||||
if !info.has_decl && !info.is_anon {
|
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)(')
|
g.definitions.write('typedef ${g.typ(func.return_type)} (*$fn_name)(')
|
||||||
for i, arg in func.args {
|
for i, arg in func.args {
|
||||||
g.definitions.write(g.typ(arg.typ))
|
g.definitions.write(g.typ(arg.typ))
|
||||||
|
@ -395,7 +410,12 @@ fn (g mut Gen) stmt(node ast.Stmt) {
|
||||||
g.return_statement(it)
|
g.return_statement(it)
|
||||||
}
|
}
|
||||||
ast.StructDecl {
|
ast.StructDecl {
|
||||||
name := it.name.replace('.', '__')
|
name := if it.is_c {
|
||||||
|
it.name.replace('.', '__')
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
c_name(it.name)
|
||||||
|
}
|
||||||
// g.writeln('typedef struct {')
|
// g.writeln('typedef struct {')
|
||||||
// for field in it.fields {
|
// for field in it.fields {
|
||||||
// field_type_sym := g.table.get_type_symbol(field.typ)
|
// 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 {
|
if it.is_method {
|
||||||
name = g.table.get_type_symbol(it.receiver.typ).name + '_' + name
|
name = g.table.get_type_symbol(it.receiver.typ).name + '_' + name
|
||||||
}
|
}
|
||||||
|
if it.is_c {
|
||||||
name = name.replace('.', '__')
|
name = name.replace('.', '__')
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
name = c_name(name)
|
||||||
|
}
|
||||||
if name.starts_with('_op_') {
|
if name.starts_with('_op_') {
|
||||||
name = op_to_fn_name(name)
|
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.table.type_to_str(it.return_type)
|
||||||
type_name := g.typ(it.return_type)
|
type_name := g.typ(it.return_type)
|
||||||
g.write('$type_name ${name}(')
|
g.write('$type_name ${name}(')
|
||||||
|
@ -984,7 +1003,8 @@ fn (g mut Gen) expr(node ast.Expr) {
|
||||||
g.writeln('($styp){')
|
g.writeln('($styp){')
|
||||||
}
|
}
|
||||||
for i, field in it.fields {
|
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.expr_with_cast(it.exprs[i], it.expr_types[i], it.expected_types[i])
|
||||||
g.writeln(', ')
|
g.writeln(', ')
|
||||||
}
|
}
|
||||||
|
@ -1009,7 +1029,7 @@ fn (g mut Gen) expr(node ast.Expr) {
|
||||||
if it.expr_type == 0 {
|
if it.expr_type == 0 {
|
||||||
verror('cgen: SelectorExpr typ=0 field=$it.field')
|
verror('cgen: SelectorExpr typ=0 field=$it.field')
|
||||||
}
|
}
|
||||||
g.write(it.field)
|
g.write(c_name(it.field))
|
||||||
}
|
}
|
||||||
ast.Type {
|
ast.Type {
|
||||||
// match sum 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) {
|
fn (g mut Gen) ident(node ast.Ident) {
|
||||||
name := node.name.replace('.', '__')
|
if node.name == 'lld' {
|
||||||
if name == 'lld' {
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if name.starts_with('C__') {
|
if node.name.starts_with('C.') {
|
||||||
g.write(name[3..])
|
g.write(node.name[2..].replace('.', '__'))
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
name := c_name(node.name)
|
||||||
// TODO `is`
|
// TODO `is`
|
||||||
match node.info {
|
match node.info {
|
||||||
ast.IdentVar {
|
ast.IdentVar {
|
||||||
|
@ -1524,7 +1544,7 @@ fn (g mut Gen) return_statement(it ast.Return) {
|
||||||
|
|
||||||
fn (g mut Gen) const_decl(node ast.ConstDecl) {
|
fn (g mut Gen) const_decl(node ast.ConstDecl) {
|
||||||
for i, field in node.fields {
|
for i, field in node.fields {
|
||||||
name := field.name.replace('.', '__')
|
name := c_name(field.name)
|
||||||
expr := node.exprs[i]
|
expr := node.exprs[i]
|
||||||
// TODO hack. Cut the generated value and paste it into definitions.
|
// TODO hack. Cut the generated value and paste it into definitions.
|
||||||
pos := g.out.len
|
pos := g.out.len
|
||||||
|
@ -1562,7 +1582,8 @@ fn (g mut Gen) assoc(node ast.Assoc) {
|
||||||
styp := g.typ(node.typ)
|
styp := g.typ(node.typ)
|
||||||
g.writeln('($styp){')
|
g.writeln('($styp){')
|
||||||
for i, field in node.fields {
|
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.expr(node.exprs[i])
|
||||||
g.writeln(', ')
|
g.writeln(', ')
|
||||||
}
|
}
|
||||||
|
@ -1573,7 +1594,8 @@ fn (g mut Gen) assoc(node ast.Assoc) {
|
||||||
if field.name in node.fields {
|
if field.name in node.fields {
|
||||||
continue
|
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('}')
|
g.write('}')
|
||||||
if g.is_amp {
|
if g.is_amp {
|
||||||
|
@ -1731,7 +1753,8 @@ fn (g mut Gen) write_types(types []table.TypeSymbol) {
|
||||||
g.definitions.writeln('struct $name {')
|
g.definitions.writeln('struct $name {')
|
||||||
for field in info.fields {
|
for field in info.fields {
|
||||||
type_name := g.typ(field.typ)
|
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')
|
// 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) {
|
fn (g mut Gen) call_expr(it ast.CallExpr) {
|
||||||
mut name := it.name.replace('.', '__')
|
mut name := it.name
|
||||||
if name == 'exit' {
|
|
||||||
name = 'v_exit'
|
|
||||||
}
|
|
||||||
if name == 'free' {
|
|
||||||
name = 'v_free'
|
|
||||||
}
|
|
||||||
is_print := name == 'println'
|
is_print := name == 'println'
|
||||||
if it.is_c {
|
if it.is_c {
|
||||||
// Skip "C__"
|
// Skip "C."
|
||||||
g.is_c_call = true
|
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.
|
// 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"')
|
// verror('bad os ifdef name "$name"')
|
||||||
return ''
|
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