How to use mutual struct?


#1

Recursion in views cannot be handled this way. You need to define
dataviews for this.On Friday, August 19, 2016 at 7:01:35 AM UTC-4, Kiwamu Okabe wrote:

Hi all,

Now I’m trying to define mutual struct:

https://github.com/jats-ug/practice-ats/blob/master/struct/main.dats

They are defined following in C:

{^ 
struct foo; 
struct bar { 
  int a; 
  struct foo *p; 
}; 
struct foo { 
  int b; 
  struct bar *p; 
}; 
%} 

And they are imported into ATS world with following:

absvt@ype struct_foo 
vtypedef struct_bar = $extype_struct"struct bar" of { 
  a = int, 
  p = [l:addr] (struct_foo@l | ptr l) 
} 
vtypedef struct_foo_impl = $extype_struct"struct foo" of { 
  a = int, 
  p = [l:addr] (struct_bar@l | ptr l) 
} 
assume struct_foo = struct_foo_impl 

But the code using these causes compile error at ATS… What’s wrong???

implement main0 () = { 
  var foo: struct_foo 
  var bar: struct_bar 
//  val () = foo.p := (view@bar | addr@bar) // Error! 
//  val () = bar.p := (view@foo | addr@foo) // Error! 
  val () = println! (foo.p) 
  val () = println! (bar.p) 
//  val () = println! (foo.a) // Error! 
//  val () = println! (bar.a) // Error! 
} 

Best regards,

Kiwamu Okabe at METASEPI DESIGN


#2

addback_struct_foo should be a prfun (instead of a castfn).On Friday, August 19, 2016 at 7:01:35 AM UTC-4, Kiwamu Okabe wrote:

Hi all,

Now I’m trying to define mutual struct:

https://github.com/jats-ug/practice-ats/blob/master/struct/main.dats

They are defined following in C:

{^ 
struct foo; 
struct bar { 
  int a; 
  struct foo *p; 
}; 
struct foo { 
  int b; 
  struct bar *p; 
}; 
%} 

And they are imported into ATS world with following:

absvt@ype struct_foo 
vtypedef struct_bar = $extype_struct"struct bar" of { 
  a = int, 
  p = [l:addr] (struct_foo@l | ptr l) 
} 
vtypedef struct_foo_impl = $extype_struct"struct foo" of { 
  a = int, 
  p = [l:addr] (struct_bar@l | ptr l) 
} 
assume struct_foo = struct_foo_impl 

But the code using these causes compile error at ATS… What’s wrong???

implement main0 () = { 
  var foo: struct_foo 
  var bar: struct_bar 
//  val () = foo.p := (view@bar | addr@bar) // Error! 
//  val () = bar.p := (view@foo | addr@foo) // Error! 
  val () = println! (foo.p) 
  val () = println! (bar.p) 
//  val () = println! (foo.a) // Error! 
//  val () = println! (bar.a) // Error! 
} 

Best regards,

Kiwamu Okabe at METASEPI DESIGN


#3

Please try:

val () = foo_ptr.b(9)

The following article is on dot-symbol overloading:

http://ats-lang.sourceforge.net/DOCUMENT/ATS2TUTORIAL/HTML/HTMLTOC/c260.htmlOn Monday, August 22, 2016 at 6:00:55 AM UTC-4, Kiwamu Okabe wrote:

Hi Hongwei,

On Mon, Aug 22, 2016 at 2:28 PM, Hongwei Xi <…> wrote:

Basically, I think that every struct in C should be first mapped to an
abstract type.

I used mutual struct in your style:

https://github.com/jats-ug/practice-ats/blob/4af1b892edc700d33312b9289ff7a72861b9a4a1/template_struct/main.dats#L134

However, following code at line 134 causes error…

  val foo_ptr = takeout_struct_foo_ptr (addr@foo) 
  val () = foo_ptr.b := 9 // error(3): the type 
[S2Eapp(S2Ecst(struct_foo_ptr); S2Evar(foo(8452)))] is expected to be 
a tyrec(record). 

Also, there is no need to start with C syntax. You can (and probably
should)
start
with some syntax of your design and then later find a way to translate C
syntax into
your designed syntax. I call this doing-things-in-stages. Trying to do a
complex thing
in one step usually ends up with a failure and some frustration.

Yes. You know that I already made some code for kernel.

https://github.com/metasepi/linux-bohai-s2/blob/bohai-s2/metasepi/include/linux/SATS/statfs.sats#L10

Now, I need some semi-automatically-generate tool to try rewriting
such kernel widely.
Such kernel has many many interfaces written by C language!!!

Best regards,

Kiwamu Okabe at METASEPI DESIGN


#4

The reason is that you used:

abst@ype struct_foo

Instead, you need the following line:

abst@ype struct_foo = $extype"struct foo"

The compiler needs to know the size of struct_foo during compilation.On Monday, August 22, 2016 at 6:44:08 AM UTC-4, Kiwamu Okabe wrote:

Also I have another question.

I split template_struct/main.dats file into following three files:

https://github.com/jats-ug/practice-ats/blob/ac1e4fd22035e643d5211891c16564dda6ff5fcc/template_struct/gen.sats

https://github.com/jats-ug/practice-ats/blob/ac1e4fd22035e643d5211891c16564dda6ff5fcc/template_struct/gen_tmpl.dats

https://github.com/jats-ug/practice-ats/blob/ac1e4fd22035e643d5211891c16564dda6ff5fcc/template_struct/main.dats

But I have following error on gcc side…

$ pwd 
/home/kiwamu/src/practice-ats/template_struct 
$ make 
/home/kiwamu/src/ATS-Postiats/bin/patscc -o a.out main.dats 
-DATS_MEMALLOC_LIBC 
In file included from main_dats.c:15:0: 
main_dats.c: In function 'mainats_void_0': 
main_dats.c:1380:21: error: unknown type name 'struct_foo' 
 ATStmpdec(tmpref48, struct_foo) ; 
                     ^ 
/home/kiwamu/src/ATS-Postiats/ccomp/runtime/pats_ccomp_instrset.h:199:29: 
note: in definition of macro 'ATStmpdec' 
 #define ATStmpdec(tmp, hit) hit tmp 
                             ^~~ 
main_dats.c:1381:21: error: unknown type name 'struct_bar' 
 ATStmpdec(tmpref49, struct_bar) ; 
                     ^ 
/home/kiwamu/src/ATS-Postiats/ccomp/runtime/pats_ccomp_instrset.h:199:29: 
note: in definition of macro 'ATStmpdec' 
 #define ATStmpdec(tmp, hit) hit tmp 
                             ^~~ 
Makefile:7: recipe for target 'a.out' failed 
make: *** [a.out] Error 1 

… Why???

Best regards,

Kiwamu Okabe


#5

I see.

I would suggest a slight different approach.

Basically, I think that every struct in C should be first mapped to an
abstract type.

Let us take the inode as an example.

absvtype inode_ptr(l:addr) = ptr(l)

For each field in inode, you can generate a get function and a set function.
For instance, imagine that the following functions are generated:

fun inode_get_i_gid{l:agz} (x: !inode_ptr(l)): gid(type)
fun inode_set_i_gid{l:agz} (x: !inode_ptr(l), v: gid): void
overload .i_gid with inode_get_i_gid
overload .i_gid with inode_set_i_gid

fun inode_get_i_e2fs_gid{l:agz} (x: !inode_ptr(l)): gid(type)
fun inode_set_i_e2fs_gid{l:agz} (x: !inode_ptr(l), v: gid): void
overload .i_gid with inode_get_i_e2fs_gid
overload .i_gid with inode_set_i_e2fs_gid

Then you can write code like:

x.i_gid(x.i_e2fs_gid()) // for x->i_gid = x.i_e2fs_gid

At the beginning, please don’t try to do too much. Once you have gathered
enough experience, you can start to generate functions with more informative
types. As always, please try to find a good naming scheme to name the
generated
functions.

Also, there is no need to start with C syntax. You can (and probably
should) start
with some syntax of your design and then later find a way to translate C
syntax into
your designed syntax. I call this doing-things-in-stages. Trying to do a
complex thing
in one step usually ends up with a failure and some frustration.On Mon, Aug 22, 2016 at 12:52 AM, Kiwamu Okabe kiw...@debian.or.jp wrote:

Hi Hongwei,

On Mon, Aug 22, 2016 at 1:24 PM, gmhwxi gmh...@gmail.com wrote:

As I see it, compiling C into ATS is very meaningful but also very
challenging. At this point, it is still unclear to me what your primary
objective is for compiling C into ATS. It would definitely help if you
could present some (potential) use cases.

In the past, I create a tool translating Haskell into C, such like c2ats:

https://github.com/ajhc/struct2hs

With the tool, I can partly rewrite NetBSD kernel:

https://github.com/metasepi/netbsd-arafura-s1/tree/
arafura-s1/metasepi/sys/hssrc

The Haskell code imports many C language interface, translated by
struct2hs tool:

Today, I would like to rewrite NetBSD kernel using ATS language with
same method.
I think the method will be like following:

$1. Choose a .c file in NetBSD kernel to rewrite.
Let’s choose
https://github.com/IIJ-NetBSD/netbsd-src/blob/master/sys/
ufs/ext2fs/ext2fs_vfsops.c.
$2. Translate C interface into ATS .sats file using c2ats tool,
semi-automatically.
It should make many many .sats files in output directory.
$3. Create ext2fs_vfsops.dats file include ext2fs_vfsops.c with "%{"
declaration and staload .sats files created by $2.
And check the ext2fs_vfsops.dats file is ready to be compiled.
$4. Rewrite a function in ext2fs_vfsops.dats file using some types in
.sats files.
$5. Do refactoring the ATS function. Sometimes I’ll rewrite typedef in
.sats with dataview.
$6. …

I would like to choose a method to rewrite C code with ATS,
incrementally.

Best regards,

Kiwamu Okabe at METASEPI DESIGN


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 https://groups.google.com/group/ats-lang-users.
To view this discussion on the web visit https://groups.google.com/d/
msgid/ats-lang-users/CAEvX6d%3DZ8zVncN43c8rNrCBb%
3D9qPDxLBxhzZzEJ%2BsdZbnTTRwg%40mail.gmail.com.


#6

A function like struct_foo_get_b can be defined (automatically) as a macro
in C:

fun{}
struct_foo_get_b{l:agz}(x: !struct_foo_ptr(l)): int = ret where {
val (pf | p) = takeout_struct_foo (x)
val ret = p->b
val () = addback_struct_foo (pf | p)
}

In this way, you do not need to implement struct_foo in ATS. That is, the
following line is not needed:

assume struct_foo = struct_foo_implOn Monday, August 22, 2016 at 6:00:55 AM UTC-4, Kiwamu Okabe wrote:

Hi Hongwei,

On Mon, Aug 22, 2016 at 2:28 PM, Hongwei Xi <…> wrote:

Basically, I think that every struct in C should be first mapped to an
abstract type.

I used mutual struct in your style:

https://github.com/jats-ug/practice-ats/blob/4af1b892edc700d33312b9289ff7a72861b9a4a1/template_struct/main.dats#L134

However, following code at line 134 causes error…

  val foo_ptr = takeout_struct_foo_ptr (addr@foo) 
  val () = foo_ptr.b := 9 // error(3): the type 
[S2Eapp(S2Ecst(struct_foo_ptr); S2Evar(foo(8452)))] is expected to be 
a tyrec(record). 

Also, there is no need to start with C syntax. You can (and probably
should)
start
with some syntax of your design and then later find a way to translate C
syntax into
your designed syntax. I call this doing-things-in-stages. Trying to do a
complex thing
in one step usually ends up with a failure and some frustration.

Yes. You know that I already made some code for kernel.

https://github.com/metasepi/linux-bohai-s2/blob/bohai-s2/metasepi/include/linux/SATS/statfs.sats#L10

Now, I need some semi-automatically-generate tool to try rewriting
such kernel widely.
Such kernel has many many interfaces written by C language!!!

Best regards,

Kiwamu Okabe at METASEPI DESIGN


#7

If ‘x’ is a true field name in p0, then you can use p0.x.
If ‘x’ is an overloaded symbol, then you need to use p0.x() (to access) and
p0.x(v) (to update).On Mon, Aug 22, 2016 at 10:57 AM, Kiwamu Okabe kiw...@debian.or.jp wrote:

On Mon, Aug 22, 2016 at 10:53 PM, gmhwxi gmh...@gmail.com wrote:

Please try:

val () = foo_ptr.b(9)

Thanks. Fixed.

The following article is on dot-symbol overloading:

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

For ptr, we can use “val () = p0.x := y0” style.
For absvtype, we can use “val () = p0.x(y0)” tyle.
Correct?

Best regards,

Kiwamu Okabe at METASEPI DESIGN


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 https://groups.google.com/group/ats-lang-users.
To view this discussion on the web visit https://groups.google.com/d/
msgid/ats-lang-users/CAEvX6dkHZK4bdQeN0XYhVvdPmVbD7
Dy0D2j3g-Sxi_eOrNwBkQ%40mail.gmail.com.


#8

Hi Kiwamu,

As I see it, compiling C into ATS is very meaningful but also very
challenging. At this point, it is still unclear to me what your primary
objective is for compiling C into ATS. It would definitely help if you
could present some (potential) use cases.On Saturday, August 20, 2016 at 8:07:37 PM UTC-4, Kiwamu Okabe wrote:

Hi Hongwei,

On Sun, Aug 21, 2016 at 8:16 AM, Kiwamu Okabe <…> wrote:

The dataview can be used at interface between C and ATS?
Or we need cast the dataview into vtypedef at the interface?

Ah, dataview is algebraic data type. I think it doesn’t match C
language struct…

Totally, I should use following policy to translate C interface into
ATS sats file?

  • Define it as typedef $extype_struct
  • Simply map primitive type
  • Map array to @[TYPE][SIZE]
  • Map any pointer to ptr
  • Use mutual struct with casting ptr member of the struct

I’m happy, if getting your comment.

Best regards,

Kiwamu Okabe at METASEPI DESIGN


#9

I see. There is a bit of subtlety here.

If you write ‘p0.x := y0’, then the type of ‘p0’ is required to be non
linear.On Monday, August 22, 2016 at 11:09:24 AM UTC-4, Kiwamu Okabe wrote:

On Tue, Aug 23, 2016 at 12:00 AM, Hongwei Xi <…> wrote:

If ‘x’ is a true field name in p0, then you can use p0.x.
If ‘x’ is an overloaded symbol, then you need to use p0.x() (to access)
and
p0.x(v) (to update).

Umm? Not make sense.

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

This document say:

abstype point = ptr // boxed 
extern fun point_make (x: double, y: double): point 
extern fun point_set_x (p: point, x: double): void 
overload .x with point_set_x 
val () = p0.x := y0 // point_set_x (p0, y0) 

I think the x should be overloaded symbol. But above code can use
p0.x := y0 style…

Best regards,

Kiwamu Okabe at METASEPI DESIGN