Assigning value to reference does not work

47 views
Skip to first unread message

Mike Jones

unread,
Oct 12, 2015, 9:45:55 PM10/12/15
to ats-lang-users
I tried to make a reference to some memory per our previous discussion, but the value is zero afterwards.

This code reveals the problem. "by" prints out the value 2. And "!packetCount" prints out zero. Further debugging a loop that takes the value !packetCount confirms it is zero.

Am I using incorrect syntax for "val _ = !packetCount = by"

%{^
const uint8_t packet[131];
const uint8_t *packetCount      = packet;
const uint8_t *packetHeader     = packet + 1;
const uint8_t *packetContents   = packet + 2;

%}

macdef packet =
  $extval(arrayref(uint8, 131),"packet")

macdef packetCount =
  $extval(ref(uint8),"packetCount")

    val by = serial_poll_for_byte(): uint8
    val _ = print! by

    val _ = !packetCount = by
    val _ = print! (!packetCount)





Chris Double

unread,
Oct 12, 2015, 9:53:25 PM10/12/15
to ats-lan...@googlegroups.com
On Tue, Oct 13, 2015 at 2:45 PM, Mike Jones <proc...@gmail.com> wrote:
>
> Am I using incorrect syntax for "val _ = !packetCount = by"

Use := for assignment:

val () = !packetCount := by

'=' is equality and returns a boolean. If the type of the return value
had been included instead of wildcarded with '_' this would have been
picked up as an errror.

--
http://bluishcoder.co.nz

Hongwei Xi

unread,
Oct 12, 2015, 9:54:17 PM10/12/15
to ats-lan...@googlegroups.com
Change = to :=

that is, do

!packetCount := by

--
You received this message because you are subscribed to the Google Groups "ats-lang-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ats-lang-user...@googlegroups.com.
To post to this group, send email to ats-lan...@googlegroups.com.
Visit this group at http://groups.google.com/group/ats-lang-users.
To view this discussion on the web visit https://groups.google.com/d/msgid/ats-lang-users/00418f48-119e-4792-8d5f-de27bd760f41%40googlegroups.com.

Hongwei Xi

unread,
Oct 12, 2015, 9:59:01 PM10/12/15
to ats-lan...@googlegroups.com

I suggest that you read the Chapter on extvar-declaration in the following book,
which is currently Chapter 24:

http://ats-lang.sourceforge.net/DOCUMENT/ATS2TUTORIAL/HTML/HTMLTOC/book1.html

gmhwxi

unread,
Oct 12, 2015, 10:36:04 PM10/12/15
to ats-lang-users
This example actually shows why it is good idea to write

val () = !a := b

instead of

val _ = !a := b

In the case where := is replaced with =, the former results in a type-error
while the latter may be well-typed.

Mike Jones

unread,
Oct 12, 2015, 11:57:15 PM10/12/15
to ats-lang-users
Ok, so val () = basically says the result must be void aka (), and not ignored. Makes sense.

I have a similar problem passing a value used in an arrayref. In the code below, if I do this:

crcLookupTable[n8(u8(4)]

it will print the value in the forth element of the array.

If I call pec_add(u8(4)), it prints 0. Basically, it seems not to pass into the call, or the cast somehow turns a 4 into a 0.

I assume the arrayref is ok or hard coding u8(4) would fail.

What can make 4 become zero?


// SATS file

fun pec_add (old: uint8, new: uint8): uint8


// DATS file

extern fun{} n8 (x: uint8): natLt(256) 
implement{} n8 (x)  = cast{natLt(256)}(x) // Can't go wrong because they are the same size

%{^
const uint8_t crcLookupTable[256] PROGMEM  = { 0, 7, 14, 9, 28, 27, 18, 21,
                                       56, 63, 54, 49, 36, 35, 42, 45,
                                       112, 119, 126, 121, 108, 107, 98, 101,......
                                     };
%}

macdef crcLookupTable =
  $extval(arrayref(uint8,256),"crcLookupTable")

implement pec_add (old, new) = crcLookupTable[n8(new)]

// APP DATS File

    val pec = pec_add(ZERO, u8(4))
    val _ = print! pec



Hongwei Xi

unread,
Oct 13, 2015, 9:27:18 AM10/13/15
to ats-lan...@googlegroups.com
I could not reproduce your error.

When I tried this example, I saw 28 being printed out.


--
You received this message because you are subscribed to the Google Groups "ats-lang-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ats-lang-user...@googlegroups.com.
To post to this group, send email to ats-lan...@googlegroups.com.
Visit this group at http://groups.google.com/group/ats-lang-users.

Mike Jones

unread,
Oct 13, 2015, 9:43:25 AM10/13/15
to ats-lang-users
Ok, I'll experiment, perhaps put the function in the same file, etc.

If I can't find something else, I can post my version of arduino-ats and try to make a test case.

Mike Jones

unread,
Oct 13, 2015, 9:53:10 AM10/13/15
to ats-lang-users
I pushed a copy of my arduino-ats to https://github.com/Proclivis/arduino-ats.git. It does not have an app to demonstrate the problem. It just contains the CRC functions in DATS/i2c.dats which I use from my application.

I can work on a test cast tonight or tomorrow, but you are free to reference it and try if you want. You can just take something like the blinky example and hack it. My top of file for the app is:

#include "config.hats"
#include "{$TOP}/avr_prelude/kernel_staload.hats"
staload "prelude/SATS/bool.sats"
staload "prelude/SATS/unsafe.sats"

staload "{$TOP}/SATS/arduino.sats"
staload "{$TOP}/SATS/hardware_serial.sats"
staload "{$TOP}/SATS/i2c.sats"


Mike Jones

unread,
Oct 14, 2015, 4:17:58 PM10/14/15
to ats-lang-users
By compiling a linux exe, this works. My unworking case is on Arduino. I'll dig deeper, try not to use PROGMEM, etc and see if I can find clues.

Mike Jones

unread,
Oct 14, 2015, 8:13:13 PM10/14/15
to ats-lang-users
I have determined that using PROGMEM results in zero (failure) and without PROGMEM results in working.

There is a site that describes the problem here progmem

Which says I need code like this:

byte = pgm_read_byte(&(mydata[i][j]));

So now I have the problem of how to wrap an arrayref around something that needs a macro.

Unwinding the macros:

#define pgm_read_byte( address_short)   pgm_read_byte_near(address_short)
#define pgm_read_byte_near( address_short)   __LPM((uint16_t)(address_short))

#define __LPM_enhanced__(addr)  \
(__extension__({                \
    uint16_t __addr16
= (uint16_t)(addr); \
    uint8_t __result
;           \
    __asm__                    
\
   
(                           \
       
"lpm %0, Z" "\n\t"      \
       
: "=r" (__result)       \
       
: "z" (__addr16)        \
   
);                          \
    __result
;                   \
}))

So it takes an assembly instruction "lpm" to get the data.

Based on my limited understanding:

abstype
arrayref_vt0ype_int_type
  (a:vt@ype(*elt*), n:int(*size*)) = ptr
stadef arrayref = arrayref_vt0ype_int_type

This view type wraps around a ptr, so there is no way to get a special assembly instruction involved.

Is there any similar problem solved in ATS that might be used as a model for making an arrayrefavr that would be able to use the macro under the hood?

gmhwxi

unread,
Oct 14, 2015, 9:35:53 PM10/14/15
to ats-lang-users

Exposing crcLookupTable as arrayref brings a little bit of convenience but it is
largely a bad idea in my opinion.

Here is a way to do it:

https://github.com/githwxi/ATS-Postiats-test/blob/master/contrib/hwxi/TEST10/test19.dats

If needed, we could also introduce a type for progmem pointers but it seems to be an overkill
for this particular problem.
Reply all
Reply to author
Forward
0 new messages