Re: Some advice on a "simple" thing...

Daniel Diaz <[email protected]>
Newsgroups gmane.comp.gnu.prolog.general
Message-ID <[email protected]>
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)).

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.

On 9 Apr 2014, at 09:18, Daniel Diaz <[email protected] >
wrote:

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

_______________________________________________
Users-prolog mailing list
[email protected]
https://lists.gnu.org/mailman/listinfo/users-prolog
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.