:- module(nllex,[clpilha/0,lex/3,lex2/3,set_string/1,set_file/1,
                 jjconsume/1,jjconsume/2,jjconsume/3]).
:- use_module(library(charsio),[read_from_chars/2]).

clpilha:- recorded(pilha,_,H),erase(H),fail.

set_file(S):-
   (clpilha;true),!,
   aux_set_file(S).

set_string(S):-
   (clpilha;true),!,
   aux_set_string(S).

jjconsume(X):-
  (recorded(pilha,B,R),erase(R),! ;
   init_lex2(_,B)),
  (B=X ;
   recorda(pilha,B,_),fail).


jjconsume(X,Y) :-
  recorded(pilha,B,R) -> 
   ( erase(R),
     (lex(B,X,Y) 
     ;
      recorda(pilha,B,_),fail
     )
   )
 ;
   ( init_lex2(Ref,B),
     ( next_anal(Ref,X,Y)
       ;
       recorda(pilha,B,_),fail
     )
   ).

jjconsume(W,X,Y) :-
  recorded(pilha,B,R) -> 
   ( B=W,
     erase(R),
     (lex(W,X,Y) 
     ;
      recorda(pilha,B,_),fail
     )
   )
 ;
   ( init_lex2(Ref,B),
     ( W=B,
       next_anal(Ref,X,Y)
       ;
       recorda(pilha,B,_),fail
     )
   ).

%next_anal(+Ref,-Categoria,-Semantica) % read word from current string ...
next_anal(Ref,Categoria,Semantica) :-
	repeat,
	get_lex(Ref,Cat,Sem,Flag),
	(Flag=1 -> (
            name(Sem,Seml),
	    read_from_chars(Seml,Semantica),
	    name(Cat,Catl),
	    read_from_chars(Catl,Categoria))
         ; !, fail).

%lex2(-Palavra,-Categoria,-Semantica) % read word from current string ...
lex2(Pal,Categoria,Semantica) :-
	init_lex2(Ref,Pal),
        next_anal(Ref,Categoria,Semantica).
	
%lex(+Palavra,-Categoria,-Semantica)
lex(eof,_,_):- !, fail.
lex(Palavra,Categoria,Semantica) :-
        aux_set_string(Palavra),
	init_lex(Ref),
        unset,
        next_anal(Ref,Categoria,Semantica).

foreign_file('nllex.o',[init_lex,get_lex,aux_set_string,
                        init_lex2,aux_set_file,unset]).

foreign(aux_set_string,c,aux_set_string(+string)).
%foreign(set_stream,c,set_stream(+string)).
foreign(unset,c,unset).
foreign(aux_set_file,c,aux_set_file(+string)).
foreign(init_lex,c,init_lex(-address('State'))).
foreign(init_lex2,c,init_lex2(-address('State'),-string)).
foreign(get_lex,c,get_lex(+address('State'),-string,-string,[-integer])).

:-load_foreign_files('nllex.o',['-ljspell','-lfl']),
     abolish(foreign,3),
     abolish(foreign_file,2).

:-set_string('').

:- op(600,xfy,'::').    % tipagem  classe::instancia
