Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error with order of functions #231

Open
antoyo opened this issue Jan 24, 2019 · 2 comments
Open

Error with order of functions #231

antoyo opened this issue Jan 24, 2019 · 2 comments

Comments

@antoyo
Copy link

antoyo commented Jan 24, 2019

Hi.
Here's the code with the error:

(* lib.dats *)
#include "share/atspre_staload.hats"
#include "share/atspre_staload_libats_ML.hats"

#define ATS_DYNLOADFLAG 0

staload UN = "prelude/SATS/unsafe.sats"
staload "./lib.sats"

implement alpha() =
    one_of("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")

implement alpha_num() =
    or(alpha(), num())

implement {a} or(parser1, parser2) =
   '{ parser = lam(stream) =>
        case+ parser1.parser(stream) of
        | Ok(@(stream, value)) => Ok((stream, value))
        | Err(_) => parser2.parser(stream)
    }

implement num() =
    one_of("0123456789")

implement one_of(chars) =
   '{ parser = lam(stream) =>
        case+ stream of
        | list0_nil() => Err(Eof)
        | list0_cons(first, rest) =>
            if first <> 0 && string_find_index(chars, $UN.cast{charNZ}(first)) <> i2ssz(~1) then
                Ok((rest, first))
            else
                Err(Unexpected(
                   '{ actual = char2string(first)
                    , expected = "one of " + chars
                    }
                ))
    }

and:

(* lib.sats *)
#include "share/atspre_staload_libats_ML.hats"

datatype Result(value:t@ype, error: t@ype) =
    | Ok of value
    | Err of error

typedef UnexpectedError =
   '{ actual = string
    , expected = string
    }

datatype Error =
    | Eof
    | Unexpected of UnexpectedError

typedef Stream = list0(char)

typedef Parser(a: t@ype) =
  '{ parser = (Stream) -<cloref1> Result((Stream, a), Error)
   }

fun alpha(): Parser(char)

fun alpha_num(): Parser(char)

fun num(): Parser(char)

fun one_of(chars: string): Parser(char)

fun {a: t@ype} or(parser1: Parser(a), parser2: Parser(a)): Parser(a)

I've tried to reproduce the issue with a small example, but I was unable to do so, so I've simplified my example to a minimum.
Here's the error that is produced:

In file included from lib_dats.c:15:
lib_dats.c: Dans la fonction « _057_Tests_057_ATS_057_order_bug_057_lib_056_sats__alpha_num »:
lib_dats.c:1799:21: error: « PMVtmpltcstmat » non déclaré (première utilisation dans cette fonction)
 ATSINSmove(tmpret1, PMVtmpltcstmat[0](or<S2Ecst(char_t0ype)>)(tmp2, tmp3)) ;
                     ^~~~~~~~~~~~~~
/usr/lib/ats2-postiats-0.3.11/ccomp/runtime/pats_ccomp_instrset.h:276:37: note: dans la définition de la macro « ATSINSmove »
 #define ATSINSmove(tmp, val) (tmp = val)
                                     ^~~
lib_dats.c:1799:21: note: chaque identificateur non déclaré est rapporté une seule fois pour chaque fonction dans laquelle il apparaît
 ATSINSmove(tmpret1, PMVtmpltcstmat[0](or<S2Ecst(char_t0ype)>)(tmp2, tmp3)) ;
                     ^~~~~~~~~~~~~~
/usr/lib/ats2-postiats-0.3.11/ccomp/runtime/pats_ccomp_instrset.h:276:37: note: dans la définition de la macro « ATSINSmove »
 #define ATSINSmove(tmp, val) (tmp = val)
                                     ^~~
lib_dats.c:1799:39: error: « or » non déclaré (première utilisation dans cette fonction)
 ATSINSmove(tmpret1, PMVtmpltcstmat[0](or<S2Ecst(char_t0ype)>)(tmp2, tmp3)) ;
                                       ^~
/usr/lib/ats2-postiats-0.3.11/ccomp/runtime/pats_ccomp_instrset.h:276:37: note: dans la définition de la macro « ATSINSmove »
 #define ATSINSmove(tmp, val) (tmp = val)
                                     ^~~
lib_dats.c:1799:42: warning: déclaration implicite de la fonction « S2Ecst » [-Wimplicit-function-declaration]
 ATSINSmove(tmpret1, PMVtmpltcstmat[0](or<S2Ecst(char_t0ype)>)(tmp2, tmp3)) ;
                                          ^~~~~~
/usr/lib/ats2-postiats-0.3.11/ccomp/runtime/pats_ccomp_instrset.h:276:37: note: dans la définition de la macro « ATSINSmove »
 #define ATSINSmove(tmp, val) (tmp = val)
                                     ^~~
lib_dats.c:1799:49: error: « char_t0ype » non déclaré (première utilisation dans cette fonction); vouliez-vous utiliser « wchar_t » ?
 ATSINSmove(tmpret1, PMVtmpltcstmat[0](or<S2Ecst(char_t0ype)>)(tmp2, tmp3)) ;
                                                 ^~~~~~~~~~
/usr/lib/ats2-postiats-0.3.11/ccomp/runtime/pats_ccomp_instrset.h:276:37: note: dans la définition de la macro « ATSINSmove »
 #define ATSINSmove(tmp, val) (tmp = val)
                                     ^~~
lib_dats.c:1799:61: error: expected expression before « ) » token
 ATSINSmove(tmpret1, PMVtmpltcstmat[0](or<S2Ecst(char_t0ype)>)(tmp2, tmp3)) ;
                                                             ^
/usr/lib/ats2-postiats-0.3.11/ccomp/runtime/pats_ccomp_instrset.h:276:37: note: dans la définition de la macro « ATSINSmove »
 #define ATSINSmove(tmp, val) (tmp = val)
                                     ^~~

If I put the implement or before the call to or, the code compiles fine:

implement {a} or(parser1, parser2) =
   '{ parser = lam(stream) =>
        case+ parser1.parser(stream) of
        | Ok(@(stream, value)) => Ok((stream, value))
        | Err(_) => parser2.parser(stream)
    }

implement alpha_num() =
    or(alpha(), num())

I believe this is a bug as this seems to work in other scenarios.
Thanks to fix the issue.

@githwxi
Copy link
Owner

githwxi commented Jan 26, 2019

This is not a bug.

It is actually a very important feature. A template function can always be re-implemented. And lexical scoping is used to determine which implementation of the template is supposed to be used.

@antoyo
Copy link
Author

antoyo commented Jan 27, 2019

Ok, having an error reporting in ATS instead of in C (gcc) would be great to explain what is going on.
It seemed strange to me that function without generic parameters have a different behavior.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants