objectionary / eo

EOLANG, an Experimental Pure Object-Oriented Programming Language Based on 𝜑-calculus
https://www.eolang.org
MIT License
1.01k stars 127 forks source link

let's create a Java SDK for XMIR editing #2813

Open levBagryansky opened 9 months ago

levBagryansky commented 9 months ago

Right now, all we have to modify xmir is xsl and java tools for working with xml. In my opinion, this is not the most convenient and appropriate way to work with the intermediate representation of the language, since it forces you to work with the language at the level and in terms of xml: Nodes, attributes, and so on. Perhaps xml does a good job of representing a program in eo, but working with it is not abstract and high-level enough. For example, try changing the name of an object that is used in many places. Or try adding another abstract object as an attribute to the object - at the xmir level, this is not a trivial task. As for me, an example of a more convenient interaction with an internal representation is LLVM. They do not change the file itself, but interact with a special api, where there is, for example, the IRBuilder class- to add instructions or functions, BasicBlock, Instruction, and so on. Moving away from the topic, they have a rather complicated class hierarchy for all occasions (https://llvm.org/doxygen/classllvm_1_1Value.html ). In short, they work in terms of the entities of their ir, not in terms of a specific representation. Therefore, it seems to me it would be convenient to make an abstract api specifically for working with eo and in terms of eo from the outside, and rely on xmir inside.

yegor256 commented 9 months ago

@levBagryansky good idea! What would be the interface of this API? Can you draft an example: how someone can build/modify a EO program using API calls?

c71n93 commented 8 months ago

There is simple example of analyzing EO code with IRBuilder, that may be useful.

IRBuilder builder = new XMIRBuilder("example.xmir");
Collection<AbstractObj> abstracts = builder.getAbstracts();
for (AbstractObj abstr : abstracts) {
    if (abstr.isDecorator()) {
        System.out.println(abstr.name() + " decorates " + abstr.getAttr("@").base().toString())
    }
}

This code should for every top level abstract object print what it decorates.

For this EO example:

[] > parent
  [] > attr1
    1 > @

[] > child
  parent.attr1 > @
  [] > attr2
    2 > @

Output will be:

child decorates parent.attr1

@levBagryansky Do you have any thoughts?

levBagryansky commented 8 months ago
IRBuilder builder = new XMIRBuilder("example.xmir");
Collection<AbstractObj> abstracts = builder.getAbstracts();
for (AbstractObj abstr : abstracts) {
    if (abstr.hasAttr("@")) {
        System.out.println(abstr.name() + " decorates " + abstr.getAttr("@").base().toString())
    }
}
Obj child = builder.getObjs().filter(obj -> "child".equals(obj.name)).toList().get(0);
Expr valueOfPhiAt = child.getAttr("@").base();  // Actually is expression with application and dot.notation
obj.getRoot()     // parent
levBagryansky commented 8 months ago

@c71n93 take a look at the eo code:

[] > person
  world.society > @
  [] > age
    2 > @

We can split this NamedObject into two parts: right part is the name "person" and left part is an expression:

[]
  world.society > @
  [] > age
    2 > @

This like "base" in XMIR. 1) Expression can be an abstraction like in the example above. Then it has a list of attributes (free and bound). We have taken the induction step because each attribute is similar to the example we are considering at the beginning. 2) Expression an application: 2.plus 3 4 5 There is an abstraction with following parts: source- 2.plus, and args: 3, 4, 5. 3) Expression can be a dot.notation: 2.plus is a dot.notation. 4) Expression can be a link to other object. Thus the API can be following:

List<NamedObject> objs = builder.getNamed();
NamedObject person = objs.stream().filter(obj -> "person".equal(obj.name())).getFirst();
sout(person.name()); // "person"
Expression abstr = child.value(); 
sout(abstr.getClass());  // Abstraction
NamedObj firstAttr = ((Abstraction) abstr).attr(0 /* or "@" */); // world.society > @
sout("should be @: " + firstAttr).name())
firstAttr.value()   // Expression that is DotNotation, world.society
    .getArg(0)        // world
    .getClass()       // Link

Changing the name would be via method Expression::setName. Adding an attribute: Abstraction::addAttribute(Expression) and so on.

levBagryansky commented 8 months ago

@yegor256 please take a look

c71n93 commented 8 months ago

@levBagryansky I like the idea. But I have several questions

levBagryansky commented 8 months ago

@c71n93