Search code examples
compiler-errorscode-generationats

How to use the funset_avltree library?


I am trying to use the funset_avltree library, but the compiler generates invalid C code. I am using ATS/Postiats version 0.2.10.

My code is fairly straightforward:

(* ast.sats *)
staload "libats/SATS/funset_avltree.sats"

datatype ast =
  | ast_var of string

fun free_vars (ast : ast) :<> set string
(* ast.dats *)
#include "share/atspre_staload.hats"
staload "./ast.sats"
staload "libats/SATS/funset_avltree.sats"
dynload "libats/DATS/funset_avltree.dats"

implement free_vars (ast : ast) : set string =
  case+ ast of
  | ast_var name => funset_sing name

The compiler output, however, is rather confusing:

ast_dats.c:359:51: warning: implicit declaration of function 'S2EVar' is invalid
      in C99 [-Wimplicit-function-declaration]
ATSINSmove(tmpret0, PMVtmpltcstmat[0](funset_sing<S2EVar(4713)>)(tmp1)) ;
                                                  ^

ast_dats.c:359:39: error: use of undeclared identifier 'funset_sing'
ATSINSmove(tmpret0, PMVtmpltcstmat[0](funset_sing<S2EVar(4713)>)(tmp1)) ;
                                      ^

ast_dats.c:359:64: error: expected expression
ATSINSmove(tmpret0, PMVtmpltcstmat[0](funset_sing<S2EVar(4713)>)(tmp1)) ;
                                                               ^

I get similar errors with funset and funset_listord. I must be missing something trivial. Do I need to include something or pass some flag to the compiler?


Solution

  • the root cause is you didn't statically load AVL tree templates provided by the library.

    In the error message, PMVtmpltcstmat usually indicates something is wrong with templates. It is usually the case that programmers forget to include the templates, or forget to supply template variables. You are the first case.

    Please add this line,

    staload _ = "libats/DATS/funset_avltree.dats"
    

    to statically load templates, and make them available to the compiler. See an working example here, https://glot.io/snippets/eiu6f3dd2r


    Besides, dynload is needed when you have "global" values that needs evaluation. In your case, you do not need to dynload the avl tree library. Also, in your own file ast.dats, there is no such global value. You can define

    #define ATS_DYNLOADFLAG 0
    

    to tell compiler not to generate dynamic loading code for ast.dats.