blech-lang / blech

Blech is a language for developing reactive, real-time critical embedded software.
Apache License 2.0
64 stars 5 forks source link

cannot use external const for array declaration #9

Open mterber opened 2 years ago

mterber commented 2 years ago

Describe the bug The following code

@[CConst (binding = "MAX_FROM_C", header = "strb.h")]
extern const MAX: nat8

@[EntryPoint]
activity Main () ()
    var arr: [MAX]nat8
    await true
end

leads to this compile error:

~/git/str-test$ blechc bug.blc 
error: The expression MAX must be a compile-time constant.
 --> bug.blc:6:15 [typing]

Means the external C constant cannot be used for declaring the array size in Blech.

Expected behaviour I would expect that above approach works since MAX actually is a compile-time constant.

Or is this a deliberate restriction since Blech cannot verify that MAX is actually constant at compile time?

Screenshots If applicable, add screenshots to help explain your problem.

Additional context Add any other context about the problem here.

FriedrichGretz commented 2 years ago

You already gave the answer. :-) Since by design we do not parse and interpret C code we cannot know for sure what value MAX has. Only local Blech constants can be used in this declaration.

mterber commented 2 years ago

Okay, thanks for the quick reply! :-)

Does that mean that there is no way in sharing the size of an array between Blech and C?

FriedrichGretz commented 2 years ago

But you could define the size in Blech using param. Would that be a solution?

mterber commented 2 years ago

Unfortunately not – at least not as of my understanding. I tried the following:

  1. Use param directly:
    
    module

param SIZE: nat8 = 42

struct Test var arr: [SIZE]nat8 end

This leads to

~/tmp$ blechc test.blc error: The expression SIZE must be a compile-time constant. --> test.blc:6:15 [typing]


2. Use `const` and `param` in combination:

module

const SIZE_FOR_BLECH: nat8 = 42 param SIZE_FOR_C: nat8 = SIZE_FOR_BLECH

struct Test var arr: [SIZE_FOR_BLECH]nat8 end

This compiles, but still does not solve the problem. The `param` is generated as a static variable inside `test.c`:

/* * parameters /

static blc_nat8 blc_01test01_SIZE_FOR_C = 42;

This means I cannot access blc_01test01_SIZE_FOR_C from outside, e.g. another C module, and – even if I could – I cannot use a variable for declaring the size of an array in C in a struct (which does not make any sense by the way), e.g.

int SIZE = 6;

struct test { char str[SIZE]; };

leads to

main.c:13:8: error: variably modified ‘str’ at file scope 13 | char str[SIZE]; | ^~~

FriedrichGretz commented 2 years ago

Oh yes, sorry, you are right. We cannot use param because their intention was to be re-parameterized in a binary.

The C error makes sense in my opinion. SIZE is a global variable which can be changed after compile time and then the size of the str array would not match the value of SIZE anymore. It is then not clear what size the type "struct test" has.

So sharing constants between Blech and C is an issue at the moment. I'll reopen.

FriedrichGretz commented 2 years ago

One possible way to fix this is to generate a const declaration into the .h file even though we substitute their occurrences in the generated code.