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

shares not working #4

Open MohamedGhardallou opened 2 years ago

MohamedGhardallou commented 2 years ago

Describe the bug Hello, when trying to use individual array elements as function outputs

module exposes do_something

function calc_speed()(x : float32 , y : float32)
x = 5
y = 3
end

activity do_something()()
 var V : [2] float32 = { 0, 0 }
 calc_speed()(V[0], V[1] )
 await true
end

I got this error : error: Write-write conflict. V or an alias thereof occurs multiple times in the output list of the sub program call. --> prog.blc:13:2 [causality]

13 | calc_speed()(V[0], V[1] ) | ---- First occurence of output argument. 13 | calc_speed()(V[0], V[1] ) | ^^^^ Subsequent alias of the same output argument.

If this usage is intended, consider using the "shares" keyword when declaring the formal parameters of the subprogram.

Expected behaviour It's clear that this program is safe. in case of runtime indexes it's very difficult for the compiler to verify the safety. in this case the programmer should have a mechanism to disable safety checks

schorg commented 2 years ago

We have thought about an additional syntax for indexing arrays with compile-time constants. Something like: calc_speed()(V.[0], V.[1]) But this is a very subtle difference. V.[0] would require a compile-time constant expression for the index. V[0]is a runtime expression for the index. With compile time indexes the compiler could easily allow this.

For the moment you can use a struct:

struct V
  var x: float32
  var y: float32 
end
...
var v: V = { x = 0, y = 0 }
...
calc_speed()(v.x, v.y)

The compiler can track this.

What do you think about compile-time array indexes ?

MohamedGhardallou commented 2 years ago

The compiler can already tell that a given expression is constant or not without the need for an additional syntax. ( for example in const and param variable definition )

Can't we just use that to verify that two indexes are different and thus these two arrays elements can be safely shared ?

calc_speed()(V[0], V[1]) // should work
calc_speed()(V[1], V[1]) // should not work
var i : int32 = 0
var j : int32 = 1
calc_speed()(V[i], V[j]) // should not work

const K: int32 = 0
const L: int32 = 1
calc_speed()(V[K], V[L]) // should  work