`dynload` and `atscc2js`: is there anything special?

64 views
Skip to first unread message

Yannick Duchêne

unread,
May 11, 2015, 11:09:00 AM5/11/15
to ats-lan...@googlegroups.com
As I'm not yet really used to ATS, I may miss something, but the sample is simple enough, so may be the question is worth to be asked.

If some module defines some values of some implementations, it has to be dynloaded additionally to being staloaded. Trying to dynload anything, with ATSCC2JS I always get an error. I came to this reduced sample, made of `test-1.dats` and `test-2.dats`.

Test-1.dats is:

#include "share/atspre_define.hats"
#include "{$LIBATSCC2JS}/staloadall.hats"

staload NS
= "test-2.dats"
dynload
"test-2.dats"

#define ATS_MAINATSFLAG 1
#define ATS_DYNLOADNAME "js_main_dynload"

%{$
  js_main_dynload
();
%}


Test-2.dats is just empty:

// Empty.


Then I run this:

patsopt -d "test-1.dats" >"test-1.c"

… which is OK.

Then I run this:

atscc2js -o "test-1.js" <"test-1.c"

I always get this error:

Hello from atscc2js!
ParsingErrors:
: 5408(line=198, offs=1) -- 5414(line=198, offs=7): error(parsing): the keyword [EOF] is needed.
exit(ATS): uncaught exception at run-time: […]/JavaScript/catsparse.sats:FatalErrorExn(1024)


At line 198 of test-1.c, is this:

extern atsvoid_t0ype

As this a very simple sample, I wonder if dynloading is to be used with the JavaScript target too or if this is something special with this target and dynloading.

gmhwxi

unread,
May 11, 2015, 11:32:34 AM5/11/15
to ats-lan...@googlegroups.com
>>dynload "test_2.dats"

This is not yet supported by atscc2js. For now, you need to explicitly
name the dynload function for test_2.dats. For insta ce, add the following
line in test_2.dats:

#defined ATS_DYNLOADNAME "test_2_dynload"

Then you can add the following line in test_1.dats:

val () = test_2_dynload ()

gmhwxi

unread,
May 11, 2015, 11:33:52 AM5/11/15
to ats-lan...@googlegroups.com
>>val () = test_2_dynload ()

should be

val () = $extfcall(void, "test_2_dynload")

Yannick Duchêne

unread,
May 11, 2015, 12:29:33 PM5/11/15
to ats-lan...@googlegroups.com


Le lundi 11 mai 2015 17:33:52 UTC+2, gmhwxi a écrit :
>>val () = test_2_dynload ()

should be

val () = $extfcall(void, "test_2_dynload")


This one works. Still remains at least another issue (may be more, I don't know), although I'm not sure it's not my own fault: if in test-2.dats I add `val x = "y"` then in test-1.dats I add `val z = $NS.x + "something"`  I get errors too, and the first one seems to be a variant, as on the incriminated line there is a `ATSextern()`.

Should I try to restrict to using `#include` for now instead? Or is this a different error from me?

gmhwxi

unread,
May 11, 2015, 12:41:49 PM5/11/15
to ats-lan...@googlegroups.com
'x' is not exported. So using $NS.x leads to an error.

In this case, the error reporting is rather mysterious. If you read the output from
patsopt, you can see the error: PMVerr(...)

I will try to improve the error reporting when I have time.

Yannick Duchêne

unread,
May 11, 2015, 2:17:43 PM5/11/15
to ats-lan...@googlegroups.com


Le lundi 11 mai 2015 18:41:49 UTC+2, gmhwxi a écrit :
'x' is not exported. So using $NS.x leads to an error.


Using something like this, professor?

extern val x: string
implement x
= "aaaaa"

I tried this after http://ats-lang.sourceforge.net/DOCUMENT/INT2PROGINATS/HTML/HTMLTOC/c1696.html , but I get an error too. It's OK with `extern val x: string = "mac#"`, but I prefer a proper ATS value.

In this case, the error reporting is rather mysterious. If you read the output from
patsopt, you can see the error: PMVerr(...)


Yes, I noticed it, but though this was another related error. What's miss-leading, is that it says it's a parsing error.

gmhwxi

unread,
May 11, 2015, 5:20:48 PM5/11/15
to ats-lan...@googlegroups.com

Okay, I will try to fix this one tonight.

The truth is that atscc2js has not been extensively used. Your trying
it is very helpful.

Yannick Duchêne

unread,
May 11, 2015, 7:09:01 PM5/11/15
to ats-lan...@googlegroups.com


Le lundi 11 mai 2015 23:20:48 UTC+2, gmhwxi a écrit :

Okay, I will try to fix this one tonight.

The truth is that atscc2js has not been extensively used. Your trying
it is very helpful.

Thanks professor, you make me feel better, I was afraid to be either annoying or unable to decipher anything.

If there are issues with ATSCC2JS, I will test C compilation prior to anything, to check if it's the JS target or anything else.
 

gmhwxi

unread,
May 11, 2015, 7:24:04 PM5/11/15
to ats-lan...@googlegroups.com

You are very welcome.

Please feel free to ask questions.

By the way, I have fixed the issue with dynload functions. You
should be able to use

dynload "test_2.dats"

in your code if you update your atscc2js with the version at Github.

gmhwxi

unread,
May 11, 2015, 8:10:47 PM5/11/15
to ats-lan...@googlegroups.com

extern val x: string
implement x
= "aaaaa"

With the newest version of atscc2js, you should be able to
use the above code in test_2.dats

Yannick Duchêne

unread,
May 11, 2015, 8:38:16 PM5/11/15
to ats-lan...@googlegroups.com


Le mardi 12 mai 2015 02:10:47 UTC+2, gmhwxi a écrit :

extern val x: string
implement x
= "aaaaa"

With the newest version of atscc2js, you should be able to
use the above code in test_2.dats


Checked! I will test more in the days to come, as I'm to port a tiny web application to ATS.

I also just wanted to know if this is the proper way to define a constant. When I tried this, I wasn't sure (while I guess, probably, as that's the way functions are defined).

Hongwei Xi

unread,
May 11, 2015, 9:37:03 PM5/11/15
to ats-lan...@googlegroups.com
>>I also just wanted to know if this is the proper way to define a constant. When I tried this, I wasn't sure (while I guess, probably, as that's the way functions are defined).

Yes, it is. I would often prefer to use a template:

extern
fun{} my_x(): int

This means that you can re-implement my_x if needed.

--
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/57080c81-2021-42fb-99a9-033b385febfa%40googlegroups.com.

Yannick Duchêne

unread,
May 12, 2015, 6:16:49 AM5/12/15
to ats-lan...@googlegroups.com


Le mardi 12 mai 2015 01:24:04 UTC+2, gmhwxi a écrit :

By the way, I have fixed the issue with dynload functions. You
should be able to use

dynload "test_2.dats"

My bad, I did not check this one yesterday, and 2JS still complains on this.

If still using `val () = $extfcall(void, "test_2_dynload")` , there are errors in the generated JS.

Using this:

test-1.dats
#define ATS_MAINATSFLAG 1
#define ATS_DYNLOADNAME "js_main_dynload"

#include "share/atspre_define.hats"
#include "{$LIBATSCC2JS}/staloadall.hats"

staload NS
= "test-2.dats"
//dynload "test-2.dats"

val
() = $extfcall(void, "test_2_dynload")

val y
= $NS.x + "b"

%{$
  js_main_dynload
();
%}



test-2.dats
#define ATS_DYNLOADNAME "test_2_dynload"


#include "share/atspre_define.hats"
#include "{$LIBATSCC2JS}/staloadall.hats"

extern val x: string
implement x
= "a"


There are errors in the generated test-1.js and test-2.js.

At line 24 of test-1.js, there is an access to an undefined variable, “[…]_test_055_2_056_dats__x”. It's erroneously defined in test-2.js. It's defined at line 19 of test-2.js, but inside a function named “[…]_test_055_2_056_dats__dynload”, so only in its internal scope and not in the outer scope, that's why it appears as undefined from test-1.js

Then at line 17 of test-2.js, there is an access to an undefined “[…]_test_055_2_056_dats__dynloadflag”, which I guess should be defined at the top of test-2.js, as test-1.js do. The corresponding dynload-flag is defined at line 10 of test-1.js, but test-2.js has none.

I will look at the C files to see if it's from the C files or from ATSCC2JS.

Yannick Duchêne

unread,
May 12, 2015, 7:23:50 AM5/12/15
to ats-lan...@googlegroups.com


Le mardi 12 mai 2015 12:16:49 UTC+2, Yannick Duchêne a écrit :
At line 24 of test-1.js, there is an access to an undefined variable, “[…]_test_055_2_056_dats__x”. It's erroneously defined in test-2.js. It's defined at line 19 of test-2.js, but inside a function named “[…]_test_055_2_056_dats__dynload”, so only in its internal scope and not in the outer scope, that's why it appears as undefined from test-1.js

 I don't really understand it, by my raw guess is that it come from `catsparse_emit2_js.dats` at line 943, which says ` D0Cdyncst_valimp _ => ()`, which seems to output nothing, while I guess it should output something like `var name`.

Yannick Duchêne

unread,
May 12, 2015, 7:55:05 AM5/12/15
to ats-lan...@googlegroups.com


Le mardi 12 mai 2015 13:23:50 UTC+2, Yannick Duchêne a écrit :

 I don't really understand it, by my raw guess is that it come from `catsparse_emit2_js.dats` at line 943, which says ` D0Cdyncst_valimp _ => ()`, which seems to output nothing, while I guess it should output something like `var name`.

May be my first ATS fix, I'm very happy.

In catspars_emit2_js.dats , at line 942…

I changed this:
| D0Cdyncst_valdec _ => ()
| D0Cdyncst_valimp _ => ()


into this:
| D0Cdyncst_valdec (name, _) =>
 
{
    val
() = emit_text (out, "var ")
    val
() = emit_text (out, symbol_get_name(name.i0de_sym))
    val
() = emit_text (out, ";")
 
}
| D0Cdyncst_valimp (name, _) =>
 
{
    val
() = emit_text (out, "var ")
    val
() = emit_text (out, symbol_get_name(name.i0de_sym))
    val
() = emit_text (out, ";")
 
}



and it solved the missing declaration issue.

Still looking at how to fix the dynload-flag issue.

Yannick Duchêne

unread,
May 12, 2015, 8:14:38 AM5/12/15
to ats-lan...@googlegroups.com


Le mardi 12 mai 2015 13:55:05 UTC+2, Yannick Duchêne a écrit :
into this:
| D0Cdyncst_valdec (name, _) =>
 
{
    val
() = emit_text (out, "var ")
    val
() = emit_text (out, symbol_get_name(name.i0de_sym))
    val
() = emit_text (out, ";")
 
}
| D0Cdyncst_valimp (name, _) =>
 
{
    val
() = emit_text (out, "var ")
    val
() = emit_text (out, symbol_get_name(name.i0de_sym))
    val
() = emit_text (out, ";")
 
}



While for D0Cdyncst_valdec, it should be something like this (I forget the initialization):

| D0Cdyncst_valdec (name, s0e) =>

 
{
    val
() = emit_text (out, "var ")
    val
() = emit_text (out, symbol_get_name(name.i0de_sym))

    val
() = emit_text (out, " = ")
    val
() = emit_s0exp (out, s0e)

    val
() = emit_text (out, ";")
 
}


but no 
emit_s0exp is defined (it is for some other target, but not for JS)

Yannick Duchêne

unread,
May 12, 2015, 8:27:01 AM5/12/15
to ats-lan...@googlegroups.com


Le mardi 12 mai 2015 13:55:05 UTC+2, Yannick Duchêne a écrit :

Still looking at how to fix the dynload-flag issue.


I have a feeling a `ATSdynloadflag_init`  is missing in `test-2.c`, so may be for this one it's an error in ATSCC2JS, or may be something I don't understand. There is one in `test-1.c`, and there is no in `test-1.c`.

Hongwei Xi

unread,
May 12, 2015, 10:09:57 AM5/12/15
to ats-lan...@googlegroups.com
dyncst_valdec means a global variable is used in the current file
but it is declared in another file. In C, dyncst_valdec translates to
an extern declaration. What should it be translated into in JS?

dyncst_valimp means a global variable is implemented in the current
file. So it should translate into something like:

var _the_implemented_variable_

--
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.

Hongwei Xi

unread,
May 12, 2015, 10:43:55 AM5/12/15
to ats-lan...@googlegroups.com
You need to put the following line in test-2.dats to resolve the issue:

#define ATS_MAINATSFLAG 1

After combining C code, we link the generated object code. But JS does
not have a link-time. I do not have a good solution to this problem...


--
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.

gmhwxi

unread,
May 12, 2015, 10:50:45 AM5/12/15
to ats-lan...@googlegroups.com
s0e means type (static expression). It is not needed or used for compiling into JS.

gmhwxi

unread,
May 12, 2015, 10:58:20 AM5/12/15
to ats-lan...@googlegroups.com
Because there is no link-time for JS, using global value
declaration is a risky business when you want to compile into JS.
My attitude is that this practice should be avoided unless there
is a very good reason to justify it. It can be readily avoided: You
just turn a global value into a global function:

val foo = 0

changes into

fun foo_get(): int = 0

If efficiency is of the concern, then Closure should be able to inline
calls to foo_get.


On Tuesday, May 12, 2015 at 10:43:55 AM UTC-4, gmhwxi wrote:
You need to put the following line in test-2.dats to resolve the issue:

#define ATS_MAINATSFLAG 1

After combining C code, we link the generated object code. But JS does
not have a link-time. I do not have a good solution to this problem...

Yannick Duchêne

unread,
May 12, 2015, 11:00:36 AM5/12/15
to ats-lan...@googlegroups.com


Le mardi 12 mai 2015 16:09:57 UTC+2, gmhwxi a écrit :
dyncst_valdec means a global variable is used in the current file
but it is declared in another file. In C, dyncst_valdec translates to
an extern declaration. What should it be translated into in JS?


OK. So it should be translated into nothing, as it was. 

Yannick Duchêne

unread,
May 12, 2015, 11:02:00 AM5/12/15
to ats-lan...@googlegroups.com


Le mardi 12 mai 2015 16:43:55 UTC+2, gmhwxi a écrit :
You need to put the following line in test-2.dats to resolve the issue:

#define ATS_MAINATSFLAG 1

I did, but though it was a hack. So  ATS_MAINATSFLAG is not just for the main module? I though it was to say a module defines the `main()` equivalent.

Hongwei Xi

unread,
May 12, 2015, 11:09:45 AM5/12/15
to ats-lan...@googlegroups.com
>>I though it was to say a module defines the `main()` equivalent.

Yes, this is true for C.

The side-effect of defining ATS_MAINATSFLAG is that the compiler (patsopt)
also generates a variable to indicate whether the compiled file is initialized. This
is precisely what is needed here.


--
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.

gmhwxi

unread,
May 12, 2015, 11:21:50 AM5/12/15
to ats-lan...@googlegroups.com
I have incorporated a fix like yours for ATSdyncst_valimp.
Changes have been uploaded into Github.

Yannick Duchêne

unread,
May 12, 2015, 11:51:28 AM5/12/15
to ats-lan...@googlegroups.com


Le mardi 12 mai 2015 16:58:20 UTC+2, gmhwxi a écrit :
Because there is no link-time for JS, using global value
declaration is a risky business when you want to compile into JS.
My attitude is that this practice should be avoided unless there
is a very good reason to justify it. It can be readily avoided: You
just turn a global value into a global function:

val foo = 0

changes into

fun foo_get(): int = 0

The issue I would see, is rather with writing. I agree a constant is many times a parameterless (and side-effectless) function, the difference is in the required `()`. I already had this same though with SML, and wished the name of a function could stand its evaluation with no `()` if it has no parameter, and use a syntactical operator to say we want to refer to the function as a function and not its evaluation. The rational is that references to a function's evaluation occurs more often than references to function's proper expression.

Hongwei Xi

unread,
May 12, 2015, 12:12:10 PM5/12/15
to ats-lan...@googlegroups.com
Do you mean you want the following:

macdef foo = foo_get()


--
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.

Hongwei Xi

unread,
May 12, 2015, 12:15:27 PM5/12/15
to ats-lan...@googlegroups.com
>>Do you mean you want the following:

>>macdef foo = foo_get()

I think that this is a personal preference issue. I personally like '()' very much :)

Yannick Duchêne

unread,
May 12, 2015, 12:46:16 PM5/12/15
to ats-lan...@googlegroups.com


Le mardi 12 mai 2015 18:15:27 UTC+2, gmhwxi a écrit :
>>Do you mean you want the following:

>>macdef foo = foo_get()

I think that this is a personal preference issue. I personally like '()' very much :)

I feel I prefer parentheses around the expression, like in `(function-name parameter)` . A matter of taste :-p .

Thanks for the reminder about `macdef`. Something related: what's the recommended page to read about `#define` in ATS?

gmhwxi

unread,
May 12, 2015, 1:58:21 PM5/12/15
to ats-lan...@googlegroups.com

>>Something related: what's the recommended page to read about `#define` in ATS?

#define and macdef are largely undocumented.

#define is similar to its counterpart in C. At the beginning of the following page, there
are some interesting cases of using #define:

http://www.ats-lang.org/SERVER/MYCODE/Patsoptaas_serve.php?mycode_url=https://raw.githubusercontent.com/githwxi/ATS-Postiats/master/doc/EXAMPLE/ARITH/tally-of-powers.dats

The following old page contains some explanation on macdef:

http://ats-lang.sourceforge.net/htdocs-old/TUTORIAL/contents/macros.html
Reply all
Reply to author
Forward
0 new messages