Le 09/04/2014 15:07, Sean Charles a
écrit :
Some clarificaation…. a while back you helped me write a testing
framework…here is the code:
get_all_tests(Tests) :- setof(Line-Name, get_one_test(Name, Line), Tests).
get_one_test(Name, Line) :- current_predicate(Name/0), atom_concat('test_', _, Name), predicate_property(Name, prolog_line(Line)). !
pre>
It uses ‘pairs’ as I understand them, using the ‘-‘ to
combine the key and value, so in your response, what is ‘=‘
doing in this context in the list of flags????
There is no special meaning for '-' (except keysort/2 which sorts a
list of pairs of the form Key-Value according to the Keys). In the
above code
I used a functor - but a = would work as well. We only need a
structure to group 2 values (the functor does not care in this
case).
Daniel
Just when I thouthgh I was beginning to understand! LMAO
Thanks once again,
Sean.
Hello Sean,
you can do this with your own loop or use findall like
this:
flag(public, 0x0001).
flag(final, 0x0010).
flag(super, 0x0020).
flag(interface, 0x0200).
flag(abstract, 0x0400).
flag(synthetic, 0x1000).
flag(annotation, 0x2000).
flag(enum, 0x4000).
get_java_flags(Value, Flags) :-
findall(Name, has_flag(Value, Name),
Flags).
has_flag(Value, Name) :-
flag(Name, Mask),
Value /\ Mask =\= 0.
then call it with:
| ?- get_java_flags(0x421, Flags).
Flags = [public,super,abstract]
I have detailed a bit to be more comprehensive: the
has_flag/2 predicate could be inlined inside the findall
surrounding with ().
If you prefer to have the flags as a parameter pass them
as a list and use member to handle backtracking (done by
get_flags/3 here):
get_java_flags(Value, Flags) :-
FlagNames = [public = 0x0001,
final = 0x0010,
super = 0x0020,
interface = 0x0200,
abstract = 0x0400,
synthetic = 0x1000,
annotation = 0x2000,
enum = 0x4000],
get_flags(FlagNames, Value, Flags).
get_flags(FlagNames, Value, Flags) :-
findall(Name, has_flag(FlagNames, Value,
Name), Flags).
has_flag(NameFlags, Value, Name) :-
member(Name=Mask, NameFlags),
Value /\ Mask =\= 0.
Daniel
Le 09/04/2014 01:02, Sean Charles a écrit :
Hello list,
I have almost completed a predicate called ‘jread’
which parses a Java .class file into a term that will
allow me to create a database of all of the methods,
fields, superclass and interfaces for that class and
ultimately create a database for a complete
“android.jar” file of any required API level.
I am, for educational purposes and my own
learning, trying to build a system like Hoogle/Hayoo
for Android. I do a lot of Android and I wanted to
create a sytem I can wire into Emacs/IntelliJ or
anything for that matter, a simple HTTP server that
can supply a list of methods that have a certain
type signature using a si mple query language.
Searching by types it very very useful when using
Haskell and I wanted to improve my Prolog so I
figured why not do something like that in GNU
Prolog? I have already started a simple HTTP library
in pure GNU Prolog as well but this comes first now.
Progress so far is good…if I run it like this
from a folder containing the unpacked android.jar
file...
| ?-
jread('javax/net/SocketFactory.class',X).
X =
javaclass(super('java/lang/Object'),class('javax/net/SocketFactory'),implements([]),
methods([method(access_flags(4),name('<init>'),returns('()V'),[attr(9,
[0,3,0,1,0,0,0,14,42,183,0,1,187,0,2,89,18,3,183,0,4,191,0,0,0,2,0,10,0,0,0,6,0,1,0,0,0
,4,0,11,0,0,0,12,0,1,0,0,0,14,0,12,0,13,0,0])]),method(access_flags(41),name(getDefault)
,returns('()Ljavax/net/SocketFactory;'),attr(9,0,3,0,0,0,0,0,10,187,0,2,89,18,3,183,0,4,
191,0,0,0,1,0,10,0,0,0,6,0,1,0,0,0,5])]),method(access_flags(1),name(createSocket),
returns('()Ljava/net/Socket;'),[attr(9,0,3,0,1,0,0,0,10,187,0,2,89,18,3,183,0,4,191,
0,0,0,2,0,10,0,0,0,6,0,1,0,0,0,6,0,11,0,0,0,12,0,1,0,0,0,10,0,12,0,13,0,0]),
attr(18,0,1,0,19])]),method(access_flags(1025),name(createSocket),
returns('(Ljava/lang/String;I)Ljava/net/Socket;'),[attr(18,[0,2,0,19,0,21])]),
method(access_flags(1025),name(createSocket),
returns('(Ljava/lang/String;ILjava/net/InetAddress;I)Ljava/net/Socket;’),
[attr(18,[0,2,0,19,0,21])]),method(access_flags(1025),name(createSocket),
returns('(Ljava/net/InetAddress;I)Ljava/net/Socket;’),[attr(18[0,1,0,19])]),method(access_flags(1025),name(createSocket),
returns('(Ljava/net/InetAddress;ILjava/net/InetAddress;I)Ljava/net/Socket;'),[attr(18,[0,1,0,19])])]))
?
The place I am at now is decoding the bit flags
for the class (and eventually the methods etc)
into a term.
A typical value would be “1057” decimal, 0x421,
this contains the flags:
ACC_PUBLIC |
0x0001 |
Declared public ;
may be accessed from outside its package. |
ACC_FINAL |
0x0010 |
Declared final ;
no subclasses allowed. |
ACC_SUPER |
0x0020 |
Treat superclass methods specially when
invoked by the invokespecial
instruction. |
ACC_INTERFACE |
0x0200 |
Is an interface, not a class. |
ACC_ABSTRACT |
0x0400 |
Declared abstract ;
must not be instantiated. |
ACC_SYNTHETIC |
0x1000 |
Declared synthetic; not present in the
source code. |
ACC_ANNOTATION |
0x2000 |
Declared as an annotation type. |
ACC_ENUM |
0x4000 |
Declared as an enum
type. |
So you can see that 0x421 means “ACC_PUBLIC,
ACC_SUPER and ACC_ABSTRACT”. I would like to produce
a term something like this:
access_flags(public,super,abstract)
It’s not that I don’t know how to do it or that I
can’t do it but I am not sure what is the *most
elegant* way to do it in Prolog! Heaven knows I have
written bit shifting loops to test for flags in a
dozen languages but not in Prolog.
So, there’s the challenge, what is the most
elegant way to turn a list of bits into a list of
atom terms. Ideally I would make the list of atoms a
parameter so that I can reuse it for the other flag
based values.
Consider the gauntlet thrown! In the meantime I
am continuing to research the possibilities for
myself. I will of course put it all on GitHub along
with my Redis client. I may even create a Redis
database with the information!
:)
Sean.
--
Ce message a été vérifié par
MailScanner
pour des virus ou des polluriels et rien de
suspect n'a été trouvé.
|