Skip to content

Commit

Permalink
feat(objectionary#344): solve the problem with primitive types in the…
Browse files Browse the repository at this point in the history
… return instruction
  • Loading branch information
volodya-lombrozo committed Aug 6, 2024
1 parent 8fcba34 commit 46a838b
Show file tree
Hide file tree
Showing 4 changed files with 254 additions and 30 deletions.
60 changes: 50 additions & 10 deletions src/main/java/org/eolang/opeo/ast/Constant.java
Original file line number Diff line number Diff line change
Expand Up @@ -54,20 +54,27 @@ public final class Constant implements AstNode, Typed {
*/
private final Object value;

private final Type type;

/**
* Constructor.
* @param node The XMIR node with value to parse.
*/
public Constant(final XmlNode node) {
this(Constant.parse(node));
this(Constant.xvalue(node), Constant.xtype(node));
}

/**
* Constructor.
* @param value The constant value.
*/
public Constant(final Object value) {
this(value, Type.getType(value.getClass()));
}

public Constant(final Object value, final Type type) {
this.value = value;
this.type = type;
}

@Override
Expand All @@ -85,26 +92,59 @@ public Iterable<Directive> toXmir() {

@Override
public Type type() {
final Type result;
if (this.value instanceof Type) {
result = (Type) this.value;
} else {
result = Type.getType(this.value.getClass());
return this.type;
// final Type result;
// if (this.value instanceof Type) {
// result = (Type) this.value;
// } else {
// result = Type.getType(this.value.getClass());
// }
// return result;
}

private static Type xtype(final XmlNode node) {
final XmlNode child = node.firstChild();
final DataType type = DataType.find(
child.attribute("base").orElseThrow(
() -> new IllegalStateException("Constant node has no 'base' attribute")
)
);
switch (type) {
case INT:
return Type.INT_TYPE;
case LONG:
return Type.LONG_TYPE;
case FLOAT:
return Type.FLOAT_TYPE;
case DOUBLE:
return Type.DOUBLE_TYPE;
case CHAR:
return Type.CHAR_TYPE;
case BYTE:
return Type.BYTE_TYPE;
case SHORT:
return Type.SHORT_TYPE;
case STRING:
return Type.getType(String.class);
case TYPE_REFERENCE:
return Type.getType(Type.class);
default:
return Type.getType(type.type());
}
return result;
}

/**
* Parse the Constant value from XMIR representation.
* @param node The node to parse.
* @return The parsed value.
*/
private static Object parse(final XmlNode node) {
private static Object xvalue(final XmlNode node) {
final XmlNode child = node.firstChild();
return DataType.find(
final DataType type = DataType.find(
child.attribute("base").orElseThrow(
() -> new IllegalStateException("Constant node has no 'base' attribute")
)
).decode(child.text());
);
return type.decode(child.text());
}
}
29 changes: 24 additions & 5 deletions src/main/java/org/eolang/opeo/ast/Return.java
Original file line number Diff line number Diff line change
Expand Up @@ -92,19 +92,38 @@ public List<AstNode> opcodes() {
* @checkstyle CyclomaticComplexityCheck (20 lines)
*/
private Opcode opcode() {
// final Type type = this.type();
// final Opcode result;
// if (type.equals(Type.VOID_TYPE)) {
// result = new Opcode(Opcodes.RETURN);
// } else if (type.equals(Type.INT_TYPE) || type.equals(Type.getType(Integer.class))) {
// result = new Opcode(Opcodes.IRETURN);
// } else if (type.equals(Type.LONG_TYPE) || type.equals(Type.getType(Long.class))) {
// result = new Opcode(Opcodes.LRETURN);
// } else if (type.equals(Type.FLOAT_TYPE) || type.equals(Type.getType(Float.class))) {
// result = new Opcode(Opcodes.FRETURN);
// } else if (type.equals(Type.DOUBLE_TYPE) || type.equals(Type.getType(Double.class))) {
// result = new Opcode(Opcodes.DRETURN);
// } else if (type.equals(Type.BOOLEAN_TYPE) || type.equals(Type.getType(Boolean.class))) {
// result = new Opcode(Opcodes.IRETURN);
// } else {
// result = new Opcode(Opcodes.ARETURN);
// }
// return result;

final Type type = this.type();
final Opcode result;
if (type.equals(Type.VOID_TYPE)) {
result = new Opcode(Opcodes.RETURN);
} else if (type.equals(Type.INT_TYPE) || type.equals(Type.getType(Integer.class))) {
} else if (type.equals(Type.INT_TYPE)) {
result = new Opcode(Opcodes.IRETURN);
} else if (type.equals(Type.LONG_TYPE) || type.equals(Type.getType(Long.class))) {
} else if (type.equals(Type.LONG_TYPE)) {
result = new Opcode(Opcodes.LRETURN);
} else if (type.equals(Type.FLOAT_TYPE) || type.equals(Type.getType(Float.class))) {
} else if (type.equals(Type.FLOAT_TYPE)) {
result = new Opcode(Opcodes.FRETURN);
} else if (type.equals(Type.DOUBLE_TYPE) || type.equals(Type.getType(Double.class))) {
} else if (type.equals(Type.DOUBLE_TYPE)) {
result = new Opcode(Opcodes.DRETURN);
} else if (type.equals(Type.BOOLEAN_TYPE) || type.equals(Type.getType(Boolean.class))) {
} else if (type.equals(Type.BOOLEAN_TYPE)) {
result = new Opcode(Opcodes.IRETURN);
} else {
result = new Opcode(Opcodes.ARETURN);
Expand Down
37 changes: 22 additions & 15 deletions src/test/java/it/JeoAndOpeoTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
*/
package it;

import com.jcabi.xml.XML;
import com.jcabi.xml.XMLDocument;
import java.util.List;
import org.cactoos.bytes.BytesOf;
Expand All @@ -33,6 +34,7 @@
import org.eolang.jeo.representation.bytecode.Bytecode;
import org.eolang.jeo.representation.xmir.XmlBytecodeEntry;
import org.eolang.jeo.representation.xmir.XmlLabel;
import org.eolang.jeo.representation.xmir.XmlMethod;
import org.eolang.jeo.representation.xmir.XmlProgram;
import org.eolang.opeo.ast.Opcode;
import org.eolang.opeo.compilation.JeoCompiler;
Expand Down Expand Up @@ -132,16 +134,19 @@ void compilesDecompiled(final String path) {
"xmir/disassembled/DefaultRouterFunctionSpec.xmir",
"xmir/disassembled/SpringBootExceptionHandler$LoggedExceptionHandlerThreadLocal.xmir",
"xmir/disassembled/ApplicationContextAssertProvider.xmir",
"xmir/disassembled/Sum.xmir"
"xmir/disassembled/Sum.xmir",
"xmir/disassembled/CachingJupiterConfiguration2.xmir"
})
void decompilesCompilesAndKeepsTheSameInstructions(final String path) throws Exception {
final XMLDocument original = new XMLDocument(new BytesOf(new ResourceOf(path)).asBytes());
final XML decompiled = new JeoDecompiler(original).decompile();
System.out.println(decompiled);
MatcherAssert.assertThat(
"The original and compiled instructions are not equal",
new JeoInstructions(
new XmlProgram(
new JeoCompiler(
new JeoDecompiler(original).decompile()
decompiled
).compile()
).top().methods().get(0)
).instuctionNames(),
Expand Down Expand Up @@ -169,20 +174,22 @@ void decompilesCompilesAndKeepsTheSameInstructionsWithTheSameOperands(
new JeoDecompiler(original).decompile()
).compile()
).top().methods().get(0).instructions();
final List<XmlBytecodeEntry> expected = new XmlProgram(original).top().methods().get(0)
.instructions();
final int size = expected.size();
for (int index = 0; index < size; ++index) {
final XmlBytecodeEntry expect = expected.get(index);
final XmlBytecodeEntry act = actual.get(index);
if (expect instanceof XmlLabel && act instanceof XmlLabel) {
continue;
final List<XmlMethod> methods = new XmlProgram(original).top().methods();
for (final XmlMethod method : methods) {
final List<XmlBytecodeEntry> expected = method.instructions();
final int size = expected.size();
for (int index = 0; index < size; ++index) {
final XmlBytecodeEntry expect = expected.get(index);
final XmlBytecodeEntry act = actual.get(index);
if (expect instanceof XmlLabel && act instanceof XmlLabel) {
continue;
}
MatcherAssert.assertThat(
"The original and compiled instructions are not equal",
act,
Matchers.equalTo(expect)
);
}
MatcherAssert.assertThat(
"The original and compiled instructions are not equal",
act,
Matchers.equalTo(expect)
);
}
}

Expand Down
Loading

0 comments on commit 46a838b

Please sign in to comment.