Implementing algorithms in Céu

36 views
Skip to first unread message

Matthias T.

unread,
May 17, 2018, 3:46:07 PM5/17/18
to The Programming Language Céu
Hi,

for a private microcontroller project, I use Céu for the reactive part of my application. In this context, I have to convert rtc time stamps (32 bit integers) into a date and time information (year, month, day, hour, minute, and so on). A working C code example is attached. I wanted to stay in the Céu language and hence decided to reimplement the conversion function in Céu. Since the conversion process is a one-step function which does not involve event handling, I would like to implement it using a code/tight abstraction. My first shot in Céu, which is not working yet, looks like this:

#define EPOCH_YR    2000
#define EPOCH_DOW    6

#define IS_LEAPYEAR(year)        ( ((year)%400==0) or (((year)%4==0) and ((year)%100!=0)) )
#define YEARSIZE(year)            do if IS_LEAPYEAR(year) then escape 366; else escape 365; end end
#define MONTHSIZE(m, isLeap)    do \
   
if m == 0 then \    
        escape
31; \
   
else/if m == 1 then \
        if isLeap then \
            escape 29; \
        else \
            escape 28; \
        end \
    else/
if m == 2 then \
        escape
31; \
   
else/if m == 3 then \
        escape 30; \
    else/
if m == 4 then \
        escape
31; \
   
else/if m == 5 then \
        escape 30; \
    else/
if m == 6 then \
        escape
31; \
   
else/if m == 7 then \
        escape 31; \
    else/
if m == 8 then \
         escape
30; \
   
else/if m == 9 then \
        escape 31; \
    else/
if m == 10 then \
        escape
30; \
   
else/if m == 11 then \
        escape 31; \
    else \
    end \
end

data TimeInformation with
    var u8 second = 0;
    var u8 minute = 0;
    var u8 hour = 0;
    var u16 day = 0;
    var u8 month = 0;
    var u16 year = 0;
    var u8 day_of_week = 0;
end

code/
tight Seconds2Time (var u32 seconds, var& TimeInformation ti) -> none do
   
var u16 year = EPOCH_YR;
   
var u16 days = (seconds / 86400) as u16;
   
var u32 day_seconds = seconds % 86400;

    ti
.second = (day_seconds % 60) as u8;
    ti
.minute = ((day_seconds % 3600) / 60) as u8;
    ti
.hour = (day_seconds / 3600) as u8;

    ti
.day_of_week = ((days + EPOCH_DOW) % 7) as u8;

    loop
do
       
var u16 ysize = YEARSIZE(year);
       
if days < ysize then break; end
        days
= days - ysize;
        year
= year + 1;
   
end
    ti
.year = year;
   
    ti
.month = 0;
   
   
var bool isLeap = IS_LEAPYEAR(ti.year);
    loop
do
       
var u8 msize = MONTHSIZE(ti.month, isLeap);
       
if days < msize then break; end
        days
= days - msize;
        ti
.month = ti.month + 1;
   
end
    ti
.month = ti.month + 1;
    ti
.day = days + 1;
end

I encountered the following difficulties during implementation:
  1. I did not manage to declare a multidimensional array in Céu like it is used for the _ytab in C. Consequently, I ended up with the tedious workaround #define MONTHSIZE...
  2. In order to account for (1), I tried to initialize two one-dimensional vectors within the Seconds2Time function and select the required one during the loop iterations
    var[12] u8 tabL = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; // leap year
    var[12] u8 tabNL = [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; // no leap year
    var&[] u8 tab;
    if <is leap year> then
    tab = &tabL;
    else
    tab = &tabNL;
    end
    <use tab>
    However, I got an compilation error that I cannot declare vectors in a code/tight block.
  3. It appears that there is no while loop in Céu which I can use to check an arbitrary condition. Consequently, I ended up with using an if statement to break the endless loop as soon as the condition is met. Additionally, the Céu compiler outputs a tight loop warning - which is reasonable since there is no upper bound to the maximum number of loop iterations.
Do you have any suggestions/hints on how to implement algorithms, like e.g. the seconds2time conversion from C, in a simple and straight forward manner in Céu? Or should I stick to C for algorithmic operations like this one and use Céu mainly for the controlling and coordinating part?

Thanks in advance!

Regards,
Matthias
time-conversion.c

Francisco Sant'anna

unread,
May 17, 2018, 4:28:42 PM5/17/18
to ceu-...@googlegroups.com
Hi Matthias,

On Thu, May 17, 2018 at 4:46 PM, Matthias T. <matthia...@gmail.com> wrote:

for a private microcontroller project, I use Céu for the reactive part of my application. In this context, I have to convert rtc time stamps (32 bit integers) into a date and time information (year, month, day, hour, minute, and so on). A working C code example is attached. I wanted to stay in the Céu language and hence decided to reimplement the conversion function in Céu. Since the conversion process is a one-step function which does not involve event handling, I would like to implement it using a code/tight abstraction. My first shot in Céu, which is not working yet, looks like this:
<...>

I encountered the following difficulties during implementation:
  1. I did not manage to declare a multidimensional array in Céu like it is used for the _ytab in C. Consequently, I ended up with the tedious workaround #define MONTHSIZE...
Céu does not support multidimensional arrays (and no plans for it now).
  1. In order to account for (1), I tried to initialize two one-dimensional vectors within the Seconds2Time function and select the required one during the loop iterations
    var[12] u8 tabL = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; // leap year
    var[12] u8 tabNL = [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; // no leap year
    var&[] u8 tab;
    if <is leap year> then
    tab = &tabL;
    else
    tab = &tabNL;
    end
    <use tab>
    However, I got an compilation error that I cannot declare vectors in a code/tight block.
The lack of support is due to dynamic vectors which require an implicit `finalize` to release memory.
Again, this is not a priority considering that dynamic arrays would not be supported anyway.
  1. It appears that there is no while loop in Céu which I can use to check an arbitrary condition.
Right, no support for while loop.
This is of course missing in the language and should be added soon, probably as an optional suffix of `loop`:

loop ... until days<ysize do
    ...
end

Do you have any suggestions/hints on how to implement algorithms, like e.g. the seconds2time conversion from C, in a simple and straight forward manner in Céu? Or should I stick to C for algorithmic operations like this one and use Céu mainly for the controlling and coordinating part?

I typically use C for the non-coordinating parts of applications.
Céu can be a pita to program data transformations and the like.
Unfortunately, the tight integration with C discourages the development of Céu towards this goal.
We still have endless issues to address.
So, my suggestion is not to use Céu.
Not for this particular case, but one thing to consider is using the integration with Lua, which is much more productive than Céu and C combined for such cases.

Regards,
Francisco

Matthias T.

unread,
May 18, 2018, 9:59:44 AM5/18/18
to The Programming Language Céu
Hi Francisco,

ok, understand. I have already tried to call the existing C function but was not sure about the correct syntax. I tried something like
native/pre do
##include "rtc.h"
end

native/nohold _seconds2time
native _RTC_Time

var u32 seconds = 123456;
var _RTC_Time time;
_seconds2time
(seconds, time);

This leads to a compiler error due to an access to the uninitialized variable 'time'. I tried different approaches to initialize 'time' but they all resulted in compiler errors. What is the correct syntax in this case?

Thanks and regards,
Matthias

Francisco Sant'anna

unread,
May 18, 2018, 10:09:07 AM5/18/18
to ceu-...@googlegroups.com
var _RTC_time time = _;

I believe you want to pass &&time, no?

Francisco Sant'anna

unread,
May 19, 2018, 7:17:09 AM5/19/18
to ceu-...@googlegroups.com
Sorry, I was commuting and could not explain.
You are trying to pass a non-initialized variable to a function. That's why the compiler complains.
The void initialization `_` tells the compiler that you know what you are doing.

Matthias T.

unread,
May 21, 2018, 1:06:56 PM5/21/18
to The Programming Language Céu
Hi,

sorry for the late reply. Thank you for the explanation - it worked like a charm! I hope you don't mind one last question... Why is the raw pointer '&&time' mandatory in this case? I understood that Céu carefully distinguishes between an alias and a raw pointer. While an alias can be safely shared across reactions, a raw pointer cannot. Since the code above executes all in the same reaction wouldn't it be possible to pass an alias to 'seconds2time'? Or is this generally not possible when dealing with native C calls since the concept of aliases is only known within Céu?

Thanks and regards,
Matthias

Francisco Sant'anna

unread,
May 22, 2018, 6:29:28 PM5/22/18
to ceu-...@googlegroups.com
On Mon, May 21, 2018 at 2:06 PM, Matthias T. <matthia...@gmail.com> wrote:
Why is the raw pointer '&&time' mandatory in this case? I understood that Céu carefully distinguishes between an alias and a raw pointer. While an alias can be safely shared across reactions, a raw pointer cannot. Since the code above executes all in the same reaction wouldn't it be possible to pass an alias to 'seconds2time'? Or is this generally not possible when dealing with native C calls since the concept of aliases is only known within Céu?

At then end of the day, the C function will receive a raw pointer and can use it indiscriminately (e.g., typecast to something else).
I think it is just more honest to treat it as a pointer from the very beginning.
Also, you are only trying to avoid an extra `&`, right? This ugliness is somewhat intended.


Matthias T.

unread,
May 24, 2018, 12:33:07 PM5/24/18
to The Programming Language Céu
At then end of the day, the C function will receive a raw pointer and can use it indiscriminately (e.g., typecast to something else).
I think it is just more honest to treat it as a pointer from the very beginning.
Also, you are only trying to avoid an extra `&`, right? This ugliness is somewhat intended.

Ok, understand. You are right.
Reply all
Reply to author
Forward
0 new messages