c argument names in bindings
This commit is contained in:
@@ -12,6 +12,7 @@ package translatec
|
||||
// the output is an honest record of the whole header.
|
||||
|
||||
import "../cimport"
|
||||
import "../lexer"
|
||||
import "core:fmt"
|
||||
import "core:mem"
|
||||
import "core:strings"
|
||||
@@ -102,7 +103,8 @@ render_type :: proc(b: ^strings.Builder, result: ^cimport.Result, id: cimport.Ty
|
||||
fmt.sbprintf(b, "[%d]", item.count)
|
||||
render_type(b, result, item.child, record_names)
|
||||
case .Function:
|
||||
render_c_func(b, result, item.params, item.child, item.variadic, record_names)
|
||||
// Function-pointer types carry no parameter names, so every slot renders `_`.
|
||||
render_c_func(b, result, item.params, nil, item.child, item.variadic, record_names)
|
||||
case .Record:
|
||||
if int(item.record) >= 0 && int(item.record) < len(record_names) {
|
||||
strings.write_string(b, record_names[item.record])
|
||||
@@ -112,12 +114,14 @@ render_type :: proc(b: ^strings.Builder, result: ^cimport.Result, id: cimport.Ty
|
||||
}
|
||||
}
|
||||
|
||||
// render_c_func writes `c_func(arg0 T0, ...) R`. Params are named arg0.. because
|
||||
// the parser requires parameter names; names do not affect type identity.
|
||||
// render_c_func writes `c_func(name T0, ...) R`, using the real C parameter name
|
||||
// when `names` provides one and `_` (the sink) otherwise. Names do not affect type
|
||||
// identity; the parser requires a name slot, so unnamed params use `_`.
|
||||
render_c_func :: proc(
|
||||
b: ^strings.Builder,
|
||||
result: ^cimport.Result,
|
||||
params: []cimport.Type_Id,
|
||||
names: []string,
|
||||
ret: cimport.Type_Id,
|
||||
variadic: bool,
|
||||
record_names: []string,
|
||||
@@ -127,7 +131,8 @@ render_c_func :: proc(
|
||||
if index > 0 {
|
||||
strings.write_string(b, ", ")
|
||||
}
|
||||
fmt.sbprintf(b, "arg%d ", index)
|
||||
name := names[index] if index < len(names) else ""
|
||||
fmt.sbprintf(b, "%s ", safe_param_name(name))
|
||||
render_type(b, result, param, record_names)
|
||||
}
|
||||
if variadic {
|
||||
@@ -267,7 +272,7 @@ emit_functions :: proc(b: ^strings.Builder, result: ^cimport.Result, record_name
|
||||
continue
|
||||
}
|
||||
fmt.sbprintf(b, "%s :: ", function.name)
|
||||
render_c_func(b, result, function.params, function.result, function.variadic, record_names)
|
||||
render_c_func(b, result, function.params, function.param_names, function.result, function.variadic, record_names)
|
||||
strings.write_byte(b, '\n')
|
||||
wrote = true
|
||||
}
|
||||
@@ -311,6 +316,16 @@ render_macro_value :: proc(b: ^strings.Builder, value: cimport.Macro_Value) {
|
||||
}
|
||||
}
|
||||
|
||||
// safe_param_name returns the C parameter name when it is a usable brolang
|
||||
// identifier, else `_` (the sink): empty names (unnamed C params) and names that
|
||||
// collide with a brolang keyword (e.g. legal C `int f(int and)`) both become `_`.
|
||||
safe_param_name :: proc(name: string) -> string {
|
||||
if len(name) > 0 && lexer.keyword_kind(name) == .Identifier {
|
||||
return name
|
||||
}
|
||||
return "_"
|
||||
}
|
||||
|
||||
macro_scalar_kind :: proc(result: ^cimport.Result, id: cimport.Type_Id) -> bool {
|
||||
if int(id) < 0 || int(id) >= len(result.types) {
|
||||
return false
|
||||
|
||||
Reference in New Issue
Block a user