I want to represent Ints, Floats, and Strings in an Array or a Matrix, and compile it with help of StaticCompiler.
How can I do this?
Since a MallocMatrix on Ints works (but not on an union), one could encode Floats and (Malloc)Strings as Integer. More specific, Floats could be represented as a fraction of an Integer and a power of ten, e.g. 1000. Strings could be converted to a number via the ascii-value of the string’s characters. Here is one approach.
using StaticCompiler, StaticTools
const int_type = 1
const float_type = 2
const string_type = 3
mutable struct DataFrameStc
table::MallocMatrix{Int64}
number_of_rows::Int64
number_of_columns::Int64
function DataFrameStc(number_of_rows::Int64,number_of_columns::Int64)
table = MallocMatrix{Int64}(undef,number_of_rows,number_of_columns)
new(table,number_of_rows,number_of_columns)
end
end
encode(num::Int64)::Int64 = num
encode(num::Float64)::Int64 = Int(num * 1000)
encode(str::MallocString)::Int64 = str2num(str)
function decode(num::Int64,column_type::Int64)
if column_type == int_type
return num
elseif column_type == float_type
return num * 0.001
else
return num2str(num)
end
end
function num2str(num::Int64)::MallocString
num2letter = MallocArray{MallocString}(undef,26)
num2letter[1] = m"A"
num2letter[2] = m"B"
num2letter[3] = m"C"
# and so on
str = m""
while num > 0
t = mod(num-1,26)
b = num2letter[Int(t+1)]
str = b*str
num = div((num-t),26)
end
str
end
function str2num(str::MallocString)::Int64
len = length(str)
num = 0
for i in 1:len
num += (Int(str[i])-64) * 26 ^ (len-i)
end
num
end
function f()
column_types = MallocArray{Int64}(undef,3)
column_types[1] = int_type
column_types[2] = float_type
column_types[3] = string_type
df = DataFrameStc(2,3)
df.table[1,1] = encode(1)
df.table[1,2] = encode(2.345)
df.table[1,3] = encode(m"A")
val1 = decode(df.table[1,1],column_types[1])
val2 = decode(df.table[1,2],column_types[2])
val3 = decode(df.table[1,3],column_types[3])
printf(val1)
printf(val2)
printf(val3)
0
end
@time f()
compile_executable(f, (), "C:\\jul\\staticcompiler")
The code fails with a link error.
ld.lld: error: undefined symbol: ijl_throw
>>> referenced by C:/Users/T460/AppData/Local/Temp/f-c1cca1.o:(f)
clang-17: error: linker command failed with exit code 1 (use -v to see invocation)
ERROR: LoadError: failed process: Process(`cmd /c clang -Wno-override-module 'C:\jul\staticcompiler\wrapper.c' 'C:\jul\staticcompiler\f.ll' -o 'C:\jul\staticcompiler\f'`, ProcessExited(1)) [1]
I want to mention that I run StaticCompiler on Windows, and I have adapted StaticCompiler to Windows. I don’t know, if this error is windows-specific. So if you use Linux, it would be valuable to know, whether you receive the same error.
The code works fine, when calling decode()
with a concrete column_type
, e.g. val1 = decode(df.table[1,1],int_type)
. However, I don’t know the column type in advance, but want to determine it with column_types[<column_number>]
. Furthermore the code works, when representing and decoding only two of the three types, e.g. Int and Float, or Int and MallocString.
How can I run it with all three types, Int, Float and String, and determining the column type from the column number?