Skip to content

Need syntax for passing CPtrs to structs and arrays of structs #1799

Closed
@dylon

Description

@dylon

The following works perfectly well in LPython and LPython generates valid C code from it, but the syntax is not supported by CPython:

# file: main.py
from lpython import i32, dataclass

from numpy import empty

@dataclass
class Foo:
     x: i32
     y: i32

def init(foos: Foo[:]) -> None:
    foos[0] = Foo(1, 2)

def main() -> None:
    foos: Foo[1] = empty(1, dtype=Foo)
    init(foos)
    print("foos[0].x =", foos[0].x)

main()
$ lpython --show-c main.py > main.c

$ clang -o app main.c

$ ./app
foos[0].x = 1

$ lpython main.py
foos[0].x = 1

$ python main.py
Traceback (most recent call last):
  File "main.py", line 10, in <module>
    def init(foos: Foo[:]) -> None:
TypeError: 'type' object is not subscriptable
// file: main.c
#include <complex.h>
#include <inttypes.h>

#include <stdlib.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <lfortran_intrinsics.h>

#define ASSERT(cond)                                                           \
    {                                                                          \
        if (!(cond)) {                                                         \
            printf("%s%s", "ASSERT failed: ", __FILE__);                       \
            printf("%s%s", "\nfunction ", __func__);                           \
            printf("%s%d%s", "(), line number ", __LINE__, " at \n");          \
            printf("%s%s", #cond, "\n");                                       \
            exit(1);                                                           \
        }                                                                      \
    }
#define ASSERT_MSG(cond, msg)                                                  \
    {                                                                          \
        if (!(cond)) {                                                         \
            printf("%s%s", "ASSERT failed: ", __FILE__);                       \
            printf("%s%s", "\nfunction ", __func__);                           \
            printf("%s%d%s", "(), line number ", __LINE__, " at \n");          \
            printf("%s%s", #cond, "\n");                                       \
            printf("%s", "ERROR MESSAGE:\n");                                  \
            printf("%s%s", msg, "\n");                                         \
            exit(1);                                                           \
        }                                                                      \
    }


struct dimension_descriptor
{
    int32_t lower_bound, length;
};
struct Foo {
 int32_t x;
 int32_t y;
};


struct xFoo
{
    struct Foo *data;
    struct dimension_descriptor dims[32];
    int32_t n_dims;
    bool is_allocated;
};


// Implementations
void init(void* foos_ptr)
{
    struct xFoo foos_value;
    struct xFoo* foos = &foos_value;
    struct Foo foos_data[1];
    foos->data = foos_data;
    foos->n_dims = 1;
    foos->dims[0].lower_bound = 0;
    foos->dims[0].length = 1;
    foos->n_dims = 1;
    foos->dims[0].lower_bound = 0;
    foos->dims[0].length = 1;
    foos->data = (struct Foo*) foos_ptr;
    foos->data[(0 - foos->dims[0].lower_bound)].x = 1;
    foos->data[(0 - foos->dims[0].lower_bound)].y = 2;
}

void _xx_lcompilers_changed_main_xx()
{
    struct xFoo foos_value;
    struct xFoo* foos = &foos_value;
    struct Foo foos_data[1];
    foos->data = foos_data;
    foos->n_dims = 1;
    foos->dims[0].lower_bound = 0;
    foos->dims[0].length = 1;
    void* foos_ptr;
    foos_ptr = (void*) foos->data;
    init(foos_ptr);
    printf("%s%s%d\n", "foos[0].x =", " ", foos->data[(0 - foos->dims[0].lower_bound)].x);
}

void _lpython_main_program()
{
    _xx_lcompilers_changed_main_xx();
}

float _lfortran_caimag(float complex x);

double _lfortran_zaimag(double complex x);

float pi_32 =   3.14159265358979312e+00;
double pi_64 =   3.14159265358979312e+00;
double _lfortran_dacos(double x);

double _lfortran_dacosh(double x);

double _lfortran_dasin(double x);

double _lfortran_dasinh(double x);

double _lfortran_datan(double x);

double _lfortran_datanh(double x);

double _lfortran_dcos(double x);

double _lfortran_dcosh(double x);

double _lfortran_dexp(double x);

double _lfortran_dlog(double x);

double _lfortran_dlog10(double x);

double _lfortran_dsin(double x);

double _lfortran_dsinh(double x);

double _lfortran_dtan(double x);

double _lfortran_dtanh(double x);

float _lfortran_sacos(float x);

float _lfortran_sacosh(float x);

float _lfortran_sasin(float x);

float _lfortran_sasinh(float x);

float _lfortran_satan(float x);

float _lfortran_satanh(float x);

float _lfortran_scos(float x);

float _lfortran_scosh(float x);

float _lfortran_sexp(float x);

float _lfortran_slog(float x);

float _lfortran_slog10(float x);

float _lfortran_ssin(float x);

float _lfortran_ssinh(float x);

float _lfortran_stan(float x);

float _lfortran_stanh(float x);

int main(int argc, char* argv[])
{
    _lpython_main_program();
    return 0;
}

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions