llvm: create struct type array (pointer) - pointers

I'm working with llvm (frontend: C++) and trying to implement the struct type array (struct type pointer) in my language. My struct looks like this:
struct myStruct {
double const *myArray; //double type array
char const *myString; //string
};
And my code for struct type array implementation:
...
auto myString = Type::getInt8PtrTy(TheContext);
auto myArray = Type::getDoublePtrTy(TheContext);
auto myStruct = StructType::create(TheContext, "Struct");
myStruct->setBody({myString, myArray});
return PointerType::get(myStruct, 0);
I think that this way isn't correct because when I'm assigning data to the pointer and trying to print the array elements I got only first struct array element and only "myString" ("myArray" is always empty). I want to know what I'm doing wrong.
Additional code:
struct myStruct* getData(){
double const arr1[3] = { 10, 7, 9 }; double const* arraypnt1 = arr1; char const *str1 = "string1";
double const arr2[3] = { 1, 2, 4}; double const* arraypnt2 = arr2; char const *str2 = "string2";
struct myStruct p[2] = {{ arraypnt1, str1 }, { arraypnt2, str2 }};
struct myStruct* pairarr = p; // array of pairs
return pairarr;
}
//code generator
Value *ASTVarExpression::generateCode() {
Function *function = Builder.GetInsertBlock()->getParent();
Value *initValue = VariableValue->generateCode(); //this line creates call to function 'getData()'
if (!initValue) { return nullptr; }
AllocaInst *alloca = CreateFunctionEntryAlloca(function, VariableName, GetType(DeclaredType));
Builder.CreateStore(initValue, alloca); //store 'getData()' result in variable which type is 'myStructure* '
NamedValues[VariableName] = alloca;
return initValue;
}
static AllocaInst *CreateFunctionEntryAlloca(Function *function, StringRef variableName, Type* variableType) {
IRBuilder<> tempBlock(&function->getEntryBlock(), function->getEntryBlock().begin());
return tempBlock.CreateAlloca(variableType, 0, variableName);
}
Type *GetType(int expressionType){ //returns struct array type
auto myString = Type::getInt8PtrTy(TheContext);
auto myArray = Type::getDoublePtrTy(TheContext);
auto myStruct = StructType::create(TheContext, "Struct");
myStruct->setBody({myString, myArray});
return PointerType::get(myStruct, 0);
}
llvm IR code:
%varName = alloca %Struct.0*, align 8
%gencall = call %Struct* #getData()
store %Struct* %gencall, %Struct.0** %varName, align 8
ret %Struct* %gencall

Related

vector<vector<vector>> v , v2.assign(v.begin(),v.end()) Does this operation work normally?

struct C
{
int c;
};
struct B
{
int b;
std::vector<c> v1;
};
struct A
{
int a;
std::vector<b> v;
};
int main()
{
std::vector<A> vecA;
//vecA.push_back(...) insert value
std::vector<A> vecB;
vecB.assign(vecA.begin(), vecA.end()); //<---
}
/*If I use assign, do vecA and vecB values ​​have the same value?
The result of my test has the same value, but I wonder if there is an exception case.
*/

C Program to Search a Node in Binary Tree

this code is from binary search tree I don't know this code showing same output
I don't know where the problem is occurring I already tried to change the variables but it didn't work
What seems to be the problem? i already tried so many things but still not able to fix the errors.
#include <stdio.h>
#include <stdlib.h>
****// Basic struct of Tree****
struct node
{
int data;
struct node *left;
struct node *right;
};
****// Function to create a new Node****
struct node *createNode(int item)
{
struct node *newNode = malloc(sizeof(struct node));
newNode->left = NULL;
newNode->right = NULL;
newNode->data = item;
return newNode;
}
int search(struct node *root, int value)
{
if (root == NULL)
return 0;
if (root->data == value)
return 1;
if (root->data < value)
return search(root->right, value);
else
return search(root->left, value);
}
int main()
{
**// struct node *root = NULL;**
struct node *root = createNode(1);
root->left = createNode(2);
root->right = createNode(3);
root->left->left = createNode(4);
root->left->right = createNode(5);
root->right->right = createNode(6);
root->left->right->left = createNode(7);
root->left->right->right = createNode(8);
root->right->right->left = createNode(9);
int item = 34;
// Function to find item in the tree
int found = search(root, item);
if (found)
printf("%d value is found in the tree", item);
else
printf("%d value not found", item);
return 0;
}
The problem is that your search function expects to get a binary search tree, but your main program created a binary tree that is not a binary search tree, but this:
1
/ \
2 3
/ \ \
4 5 6
/ \ /
7 8 9
And of course, a search for 34 will anyway return 0, as it does not occur anywhere in this tree. But even if you would search for let's say 8, it would return 0.
Your search code will not work with such a tree. If you would have made a binary search tree, like for instance this one:
6
/ \
2 7
/ \ \
1 4 9
/ \ /
3 5 8
...then it would work when calling search for any value in or not in the tree. For instance, this will print "5 value is found in the tree":
int main()
{
struct node *root = createNode(6);
root->left = createNode(2);
root->right = createNode(7);
root->left->left = createNode(1);
root->left->right = createNode(4);
root->right->right = createNode(9);
root->left->right->left = createNode(3);
root->left->right->right = createNode(5);
root->right->right->left = createNode(8);
int item = 5;
// Function to find item in the tree
int found = search(root, item);
if (found)
printf("%d value is found in the tree", item);
else
printf("%d value not found", item);
return 0;
}
This function is for binary search tree (BST).
int search(struct node *root, int value)
{
if (root == NULL)
return 0;
if (root->data == value)
return 1;
if (root->data < value)
return search(root->right, value);
else
return search(root->left, value);
}
As you need to a program to work on any binary tree.
You can change it to work on an any binary tree.
int search(struct node *root, int value)
{
if (root == NULL)
return 0;
if (root->data == value)
return 1;
return search(root->right, value) || search(root->left, value);
}

how to return a pointer in a function returning char *?

I'm implementing my own strrchr - it searches for the last occurrence of the character c (an unsigned char) in the string pointed to by the argument str.
example:
Input: f("abcabc" , "b")
Output: "bc"
the function should return char *. How can i return a pointer to the char array in the function?
#include <stdio.h>
#include <string.h>
char* my_strrchr(char* param_1, char param_2)
{
int len = strlen(param_1);
char res ;
for(int i = len; i >= 0 ;i-- ){
if (param_1[i] == param_2){
res = param_1[i];
return *(res);
//here i tried return (char) res, (char*) res; nothing works
}
}
return NULL;
}
int main(){
char *d = "abcabc";
char r = 'b';
my_strrchr(d, r);
return 0 ;
}
You're trying to return value, not a pointer. Operator * means to get value by a pointer, when res isn't a pointer. You should make it a pointer an then return:
char* my_strrchr(char* param_1, char param_2)
{
int len = strlen(param_1);
char *res ; //make it a pointer
for(int i = len; i >= 0 ;i-- ){
if (param_1[i] == param_2){
res = &param_1[i]; //store address of an element to a pointer
return res; //return a pointer
}
}
return NULL;
}
Your variable res is of type char. To get the reference use the reference operator & (See Meaning of "referencing" and "dereferencing" in C):
return &res
However this will result in the address of your variable res and not in the address within your param_1 array. Have a look at Alex' answer to get the correct reference address: https://stackoverflow.com/a/61930295/6669161

genie HashTable of string, STRUCT

NOTE: my question is array, not [ Array or GenericArray ]
this is my code:
init
var h = new HashTable of string, Int? (str_hash, str_equal)
h["a"] = Int ({1, 2, 3})
h["b"] = Int ({5, 6, 7}) // HERE: WORKS FINE
// ERROR HERE:
// Array concatenation not supported for public array variables and parameters
h["a"].data += 4
struct Int
data: array of int
construct (a: array of int)
this.data = a
how to fix this?
Not really an answer, but an alternative way to express this:
init
var h = new HashTable of string, Int? (str_hash, str_equal)
h["a"] = Int ({1, 2, 3})
h["b"] = Int ({5, 6, 7})
h["a"].append ({4})
struct Int
data: array of int
construct (a: array of int)
this.data = a
def append (a: array of int)
this.data = this.data + a
Now there is no mixing of "variables and parameters" going on anymore, which solves the compiler error your original code is triggering.
The problem is that this also results in a compiler error:
resize_array.gs:14.21-14.33: error: Incompatible operand
this.data = this.data + a
Which can be simplified to this code:
init
x: array of int = {1, 2, 3}
y: array of int = {4, 5, 6}
z: array of int = x + y
Which also produces the same compiler error.
resize_array.gs:21.23-21.27: error: Incompatible operand
z: array of int = x + y
I have added a new question based on this:
How to concatenate two arrays?
As it turns out concating arrays (it works for string though!) is not a trivial task in Vala/Genie.
See the other question for solutions on how to do this.
I'd personally use Gee containers for this (if I don't have to frequently call some C functions that need a plain array).
The solution using Array of int:
init
var h = new HashTable of string, Int? (str_hash, str_equal)
h["a"] = Int ({1, 2, 3})
h["b"] = Int ({5, 6, 7})
h["a"].append ({4})
struct Int
data: Array of int
construct (a: array of int)
data = new Array of int;
append (a)
def append (a: array of int)
data.append_vals (a, a.length)
A bug of Genie? maybe?
I try that in Vala, Works fine.
The output:
1, 2, 3, 4, 55, 666,
struct Int {
int[] data;
Int(int[] a){
this.data = a;
}
}
void main(){
var h = new HashTable<string, Int?> (str_hash, str_equal);
h["a"] = Int({1, 2, 3});
h["b"] = Int({4, 5, 6});
h["a"].data += 4;
h["a"].data += 55;
h["a"].data += 666;
for (var i = 0; i < h["a"].data.length; i++) {
stdout.printf("%d, ", h["a"].data[i]);
}
}

pointer to arrays of struct

struct a{
double array[2][3];
};
struct b{
double array[3][4];
};
void main(){
a x = {{1,2,3,4,5,6}};
b y = {{1,2,3,4,5,6,7,8,9,10,11,12}};
}
I have two structs, inside which there are two dim arrays with different sizes. If I want to define only one function, which can deal with both x and y (one for each time), i.e., the function allows both x.array and y.array to be its argument. How can I define the input argument? I think I should use a pointer.... But **x.array seems not to work.
For example, I want to write a function PrintArray which can print the input array.
void PrintArray( ){}
What should I input into the parenthesis? double ** seems not work for me... (we can let dimension to be the PrintArray's argument as well, telling them its 2*3 array)
Write a function that takes three parameters: a pointer, the number of rows, and the number of columns. When you call the function, reduce the array to a pointer.
void PrintArray(const double *a, int rows, int cols) {
int r, c;
for (r = 0; r < rows; ++r) {
for (c = 0; c < cols; ++c) {
printf("%3.1f ", a[r * cols + c]);
}
printf("\n");
}
}
int main(){
struct a x = {{{1,2,3},{4,5,6}}};
struct b y = {{{1,2,3,4},{5,6,7,8},{9,10,11,12}}};
PrintArray(&x.array[0][0], 2, 3);
PrintArray(&y.array[0][0], 3, 4);
return 0;
}

Resources