-
Notifications
You must be signed in to change notification settings - Fork 68
/
translate.jl
152 lines (140 loc) · 6.51 KB
/
translate.jl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
"""
Reserved Julia identifiers will be prepended with "_"
"""
const RESERVED_WORDS = ["begin", "while", "if", "for", "try", "return", "break", "continue",
"function", "macro", "quote", "let", "local", "global", "const", "do",
"struct", "module", "baremodule", "using", "import", "export", "end",
"else", "elseif", "catch", "finally", "true", "false"]
"""
make_name_safe(name::Symbol) -> String
make_name_safe(name::AbstractString) -> String
Return a valid Julia variable name, prefixed with "_" if the `name` is conflict with Julia's
reserved words.
"""
make_name_safe(name::AbstractString) = (name in RESERVED_WORDS) ? "_" * name : name
make_name_safe(name::Symbol) = make_name_safe(string(name))
"""
make_symbol_safe(name) -> Symbol
Same as [`make_name_safe`](@ref), but return a Symbol.
"""
make_symbol_safe(x) = Symbol(make_name_safe(x))
"""
translate(jlty::AbstractJuliaType, options=Dict())
Translate [`AbstractJuliaType`](@ref)s to Julia expressions.
"""
translate(jlty::AbstractJuliaType, options=Dict()) = jlty
function translate(jlty::JuliaUnknown, options=Dict())
return error("hit a JuliaUnknown($(dumpobj(jlty.x))) in codegen pass...")
end
translate(jlty::JuliaCvoid, options=Dict()) = :Cvoid
function translate(jlty::JuliaCbool, options=Dict())
return get(options, "use_julia_bool", true) ? :Bool : :UInt8
end
translate(jlty::JuliaCuchar, options=Dict()) = :Cuchar
translate(jlty::JuliaCshort, options=Dict()) = :Cshort
translate(jlty::JuliaCushort, options=Dict()) = :Cushort
translate(jlty::JuliaCint, options=Dict()) = :Cint
translate(jlty::JuliaCuint, options=Dict()) = :Cuint
translate(jlty::JuliaClonglong, options=Dict()) = :Clonglong
translate(jlty::JuliaCulonglong, options=Dict()) = :Culonglong
translate(jlty::JuliaCintmax_t, options=Dict()) = :Cintmax_t
translate(jlty::JuliaCuintmax_t, options=Dict()) = :Cuintmax_t
translate(jlty::JuliaCfloat, options=Dict()) = :Cfloat
translate(jlty::JuliaCdouble, options=Dict()) = :Cdouble
translate(jlty::JuliaComplexF32, options=Dict()) = :ComplexF32
translate(jlty::JuliaComplexF64, options=Dict()) = :ComplexF64
translate(jlty::JuliaCptrdiff_t, options=Dict()) = :Cptrdiff_t
translate(jlty::JuliaCssize_t, options=Dict()) = :Cssize_t
translate(jlty::JuliaCsize_t, options=Dict()) = :Csize_t
translate(jlty::JuliaNoReturn, options=Dict()) = :(Union{})
translate(jlty::JuliaPtrCvoid, options=Dict()) = :(Ptr{Cvoid})
translate(jlty::JuliaCstring, options=Dict()) = :Cstring
translate(jlty::JuliaPtrUInt8, options=Dict()) = :(Ptr{UInt8})
translate(jlty::JuliaPtrPtrUInt8, options=Dict()) = :(Ptr{Ptr{UInt8}})
translate(jlty::JuliaAny, options=Dict()) = :Any
translate(jlty::JuliaRefAny, options=Dict()) = :(Ref{Any})
translate(jlty::JuliaCuint128, options=Dict()) = :UInt128
translate(jlty::JuliaCint128, options=Dict()) = :Int128
translate(jlty::JuliaCschar, options=Dict()) = :Int8
translate(jlty::JuliaClongdouble, options=Dict()) = :Float64
translate(jlty::JuliaComplex, options=Dict()) = :ComplexF32 # FIXME
translate(jlty::JuliaChalf, options=Dict()) = :Float16
translate(jlty::JuliaCfloat16, options=Dict()) = :Float16
translate(jlty::JuliaCuint64_t, options=Dict()) = :UInt64
translate(jlty::JuliaCuint32_t, options=Dict()) = :UInt32
translate(jlty::JuliaCuint16_t, options=Dict()) = :UInt16
translate(jlty::JuliaCuint8_t, options=Dict()) = :UInt8
translate(jlty::JuliaCint64_t, options=Dict()) = :Int64
translate(jlty::JuliaCint32_t, options=Dict()) = :Int32
translate(jlty::JuliaCint16_t, options=Dict()) = :Int16
translate(jlty::JuliaCint8_t, options=Dict()) = :Int8
translate(jlty::JuliaCuintptr_t, options=Dict()) = :Csize_t
translate(jlty::JuliaCtm, options=Dict()) = :(Libc.TmStruct)
translate(jlty::JuliaCchar, options=Dict()) = :Cchar
translate(jlty::JuliaClong, options=Dict()) = :Clong
translate(jlty::JuliaCulong, options=Dict()) = :Culong
translate(jlty::JuliaCwchar_t, options=Dict()) = :Cwchar_t
translate(jlty::JuliaCFILE, options=Dict()) = :(Libc.FILE)
function translate(jlty::JuliaCpointer, options=Dict())
is_jl_funcptr(jlty) && return translate(JuliaPtrCvoid(), options)
jlptree = tojulia(getPointeeType(jlty.ref))
if get(options, "always_NUL_terminated_string", false)
is_jl_char(jlptree) && return :Cstring
is_jl_wchar(jlptree) && return :Cwstring
end
return Expr(:curly, :Ptr, translate(jlptree, options))
end
function translate(jlty::JuliaCconstarray, options=Dict())
n = getNumElements(jlty.ref)
elty = translate(tojulia(getElementType(jlty.ref)), options)
return :(NTuple{$n,$elty})
end
function translate(jlty::JuliaCincompletearray, options=Dict())
elty = translate(tojulia(getElementType(jlty.ref)), options)
return Expr(:curly, :Ptr, elty)
end
function translate(jlty::JuliaCtypedef, options=Dict())
ids = get(options, "DAG_ids", Dict())
ids_extra = get(options, "DAG_ids_extra", Dict())
if haskey(ids, jlty.sym)
return make_symbol_safe(jlty.sym)
elseif haskey(ids_extra, jlty.sym)
return translate(ids_extra[jlty.sym], options)
elseif get(options, "opaque_func_arg_as_PtrCvoid", false)
return translate(JuliaCvoid(), options)
else
return make_symbol_safe(jlty.sym)
end
end
function translate(jlty::JuliaCenum, options=Dict())
tags = get(options, "DAG_tags", Dict())
# for now, we don't distinguish extra tags and ids, this may be improved in the future.
# tags_extra = get(options, "DAG_tags_extra", Dict())
ids_extra = get(options, "DAG_tags_extra", Dict())
if haskey(tags, jlty.sym) || haskey(ids_extra, jlty.sym)
return make_symbol_safe(jlty.sym)
else
# it could a local opaque tag-type
return translate(JuliaCvoid(), options)
end
end
function translate(jlty::JuliaCrecord, options=Dict())
tags = get(options, "DAG_tags", Dict())
# for now, we don't distinguish extra tags and ids, this may be improved in the future.
# tags_extra = get(options, "DAG_tags_extra", Dict())
ids_extra = get(options, "DAG_ids_extra", Dict())
nested_tags = get(options, "nested_tags", Dict())
if haskey(tags, jlty.sym) || haskey(ids_extra, jlty.sym)
return make_symbol_safe(jlty.sym)
else
for (id, cursor) in nested_tags
if is_same(jlty.cursor, cursor)
@assert isempty(string(jlty.sym))
return id
end
end
# then it could be a local opaque tag-type
return translate(JuliaCvoid(), options)
end
end
translate(jlty::JuliaCfunction, options=Dict()) = translate(JuliaCvoid(), options)