Skip to content

Commit

Permalink
codegen for comparision
Browse files Browse the repository at this point in the history
  • Loading branch information
PtrMan committed Dec 12, 2015
1 parent 7fdc547 commit 7428f95
Show file tree
Hide file tree
Showing 5 changed files with 158 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -74,26 +74,43 @@ public InlinedResultCodeWithType generateBodyForwardPass(Element astElement, Map
}*/
if( astElement.type.isEqualWithType(new Type(Type.EnumType.FUNCTION_CALL))) {
if( astElement.identifier == null ) {
if( astElement.callType == Element.EnumCallType.ADD ) {
throw new RuntimeException("Internal Error!");
}
else {
if( astElement.identifier.equals("cond") ) {
return generateBodyForwardPassForCondition(astElement, typeinfoOfVariables);
}
else if( astElement.identifier.equals("+") ) {
return generateBodyForwardPassForMathematicalAccumulatorOperation("+", EnumMathematicalAccumulatorInitialValue.ZERO, astElement, typeinfoOfVariables);
}
else if( astElement.callType == Element.EnumCallType.SUB ) {
else if( astElement.identifier.equals("-") ) {
return generateBodyForwardPassForMathematicalAccumulatorOperation("-", EnumMathematicalAccumulatorInitialValue.ZERO, astElement, typeinfoOfVariables);
}
else if( astElement.callType == Element.EnumCallType.MUL ) {
else if( astElement.identifier.equals("*") ) {
return generateBodyForwardPassForMathematicalAccumulatorOperation("*", EnumMathematicalAccumulatorInitialValue.ONE, astElement, typeinfoOfVariables);
}
else if( astElement.callType == Element.EnumCallType.DIV ) {
else if( astElement.identifier.equals("/") ) {
return generateBodyForwardPassForMathematicalAccumulatorOperation("/", EnumMathematicalAccumulatorInitialValue.ONE, astElement, typeinfoOfVariables);
}
else {
throw new RuntimeException("Internal Error!");
else if( astElement.identifier.equals("==") ) {
return generateBodyForwardPassForComparision("==", astElement, typeinfoOfVariables);
}
}
else {
if( astElement.identifier.equals("cond") ) {
return generateBodyForwardPassForCondition(astElement, typeinfoOfVariables);
else if( astElement.identifier.equals(">") ) {
return generateBodyForwardPassForComparision(">", astElement, typeinfoOfVariables);
}
else if( astElement.identifier.equals(">=") ) {
return generateBodyForwardPassForComparision(">=", astElement, typeinfoOfVariables);
}
else if( astElement.identifier.equals("<") ) {
return generateBodyForwardPassForComparision("<", astElement, typeinfoOfVariables);
}
else if( astElement.identifier.equals("<=") ) {
return generateBodyForwardPassForComparision("<=", astElement, typeinfoOfVariables);
}
else if( astElement.identifier.equals("/=") ) {
return generateBodyForwardPassForComparision("/=", astElement, typeinfoOfVariables);
}



throw new RuntimeException("TODO< generate code for call of function >");
Expand All @@ -111,6 +128,93 @@ else if( astElement.type.isEqualWithType(new Type(Type.EnumType.VARIABLE)) ) {
}
}

private InlinedResultCodeWithType generateBodyForwardPassForComparision(String operationString, Element astElement, Map<String, Typeinfo> typeinfoOfVariables) throws CannotCompileException {
// check if types are all equal
final List<InlinedResultCodeWithType> inlinedResultCodeForArguments = inlineResultCodeForAllArguments(astElement, typeinfoOfVariables);
final List<Typeinfo> typesOfArguments = getTypesOfInlinedResultCodeWithType(inlinedResultCodeForArguments);
final boolean allTypesAreEqual = areTypesEqual(typesOfArguments);
if( !allTypesAreEqual ) {
throw new RuntimeException("Compilation Error: types are not equal!");
}
final Typeinfo resultType = new Typeinfo(Typeinfo.EnumType.BOOLEAN);

final InlinedResultCodeWithType inlinedOperand0 = inlinedResultCodeForArguments.get(0);
final InlinedResultCodeWithType inlinedOperand1 = inlinedResultCodeForArguments.get(1);

StringBuilder resultCodeBuilder = new StringBuilder();
resultCodeBuilder.append("// codegen: first two arguments\n");
resultCodeBuilder.append(String.format("%s operand0 = %s;\n", RESULT_AND_PROPAGATION_TYPENAME, getJavaFunctioncallForFunction(inlinedOperand0.functionInfo)));
resultCodeBuilder.append(String.format("%s operand1 = %s;\n", RESULT_AND_PROPAGATION_TYPENAME, getJavaFunctioncallForFunction(inlinedOperand1.functionInfo)));
resultCodeBuilder.append("\n");
resultCodeBuilder.append("\n");


resultCodeBuilder.append(String.format("%s operand0Value = %s.%s(operand0);\n", resultType.getJavaTypeString(), RESULT_AND_PROPAGATION_TYPENAME, ResultAndControlflowPropagationInfo.codegenGetJavaFunctionnameForExtractionOfValueOfType(resultType)));
resultCodeBuilder.append(String.format("%s operand1Value = %s.%s(operand1);\n", resultType.getJavaTypeString(), RESULT_AND_PROPAGATION_TYPENAME, ResultAndControlflowPropagationInfo.codegenGetJavaFunctionnameForExtractionOfValueOfType(resultType)));
resultCodeBuilder.append("\n");
resultCodeBuilder.append("\n");

// generate code to compare first two values
// depending on the comparision we return a boolean or we continue comparision until we are done with all
final String javaComparision = getJavaComparisionForFunctionalComparision(operationString);

resultCodeBuilder.append(String.format("if( !(operand%sValue %s operand%sValue) ) {\n", 0, javaComparision, 1));
resultCodeBuilder.append(String.format(" return %s.%s(false);\n", RESULT_AND_PROPAGATION_TYPENAME, ResultAndControlflowPropagationInfo.codegenGetJavaFunctionnameForCreationOfType(new Typeinfo(Typeinfo.EnumType.BOOLEAN))));
resultCodeBuilder.append( "}\n");
resultCodeBuilder.append( "\n");


// generate code for compare remaining operands
for( int operandI = 2; operandI < inlinedResultCodeForArguments.size(); operandI++ ) {
resultCodeBuilder.append(String.format("%s operand%s = %s;\n", RESULT_AND_PROPAGATION_TYPENAME, operandI, getJavaFunctioncallForFunction(inlinedOperand1.functionInfo)));
resultCodeBuilder.append(String.format("%s operand%sValue = %s.%s(operand%s);\n", resultType.getJavaTypeString(), operandI, RESULT_AND_PROPAGATION_TYPENAME, ResultAndControlflowPropagationInfo.codegenGetJavaFunctionnameForExtractionOfValueOfType(resultType), operandI));

resultCodeBuilder.append(String.format("if( !(operand%sValue %s operand%sValue) ) {\n", operandI-1, javaComparision, operandI));
resultCodeBuilder.append(String.format(" return %s.%s(false);\n", RESULT_AND_PROPAGATION_TYPENAME, ResultAndControlflowPropagationInfo.codegenGetJavaFunctionnameForCreationOfType(new Typeinfo(Typeinfo.EnumType.BOOLEAN))));
resultCodeBuilder.append( "}\n");
resultCodeBuilder.append( "\n");
}

resultCodeBuilder.append(String.format("return %s.%s(true);\n", RESULT_AND_PROPAGATION_TYPENAME, ResultAndControlflowPropagationInfo.codegenGetJavaFunctionnameForCreationOfType(new Typeinfo(Typeinfo.EnumType.BOOLEAN))));


final String resultCode = resultCodeBuilder.toString();
final GeneratedFunctionInfo generatedFunctionInfo = emitInternalFunction(resultType, resultCode);

return new InlinedResultCodeWithType(resultType, generatedFunctionInfo);
}

private boolean areTypesEqual(List<Typeinfo> types) {
final Typeinfo comparisonType = types.get(0);

for( int i = 1; i < types.size(); i++ ) {
final Typeinfo iterationType = types.get(1);

if( !comparisonType.isEqual(iterationType) ) {
return false;
}
}

return true;
}

private static String getJavaComparisionForFunctionalComparision(String comparision) {
if( comparision.equals("/=") ) {
return "!=";
}

switch (comparision) {
case "==":
case ">=":
case ">":
case "<=":
case "<":
return comparision;
default:
throw new RuntimeException("Internal Error: " + comparision + " is not a valid comparision!");
}
}

private InlinedResultCodeWithType generateBodyForwardPassForVariable(Element astElement, Map<String, Typeinfo> typeinfoOfVariables) throws CannotCompileException {
final String variableName = astElement.identifier;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@
* typeinfo for a variable
*/
public class Typeinfo {
public boolean isEqual(Typeinfo other) {
return type == other.type;
}

public enum EnumType {
BOOLEAN, INTEGER
}
Expand All @@ -18,6 +22,9 @@ public String getJavaTypeString() {
if( type == EnumType.INTEGER ) {
return "int";
}
else if( type == EnumType.BOOLEAN ) {
return "boolean";
}

throw new RuntimeException("Internal error!");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,14 +42,7 @@ Rule variableOrConstantOrStandardCallBraces() {
}

Rule identifierOrFunctionOrOperator() {
// TODO< other cases >
return firstOf(
sequence(basicIdentifier(), push(new HasChildrenParseTreeElement(HasChildrenParseTreeElement.EnumType.IDENTIFIER_OR_FUNCTION_OR_OPERATOR, new ParseTreeElement[]{pop()}))),
sequence('+', push(new HasChildrenParseTreeElement(HasChildrenParseTreeElement.EnumType.IDENTIFIER_OR_FUNCTION_OR_OPERATOR, new ParseTreeElement[]{new HasChildrenParseTreeElement(HasChildrenParseTreeElement.EnumType.PLUS, new ParseTreeElement[]{})}))),
sequence('-', push(new HasChildrenParseTreeElement(HasChildrenParseTreeElement.EnumType.IDENTIFIER_OR_FUNCTION_OR_OPERATOR, new ParseTreeElement[]{new HasChildrenParseTreeElement(HasChildrenParseTreeElement.EnumType.MINUS, new ParseTreeElement[]{})}))),
sequence('*', push(new HasChildrenParseTreeElement(HasChildrenParseTreeElement.EnumType.IDENTIFIER_OR_FUNCTION_OR_OPERATOR, new ParseTreeElement[]{new HasChildrenParseTreeElement(HasChildrenParseTreeElement.EnumType.MUL, new ParseTreeElement[]{})}))),
sequence('/', push(new HasChildrenParseTreeElement(HasChildrenParseTreeElement.EnumType.IDENTIFIER_OR_FUNCTION_OR_OPERATOR, new ParseTreeElement[]{new HasChildrenParseTreeElement(HasChildrenParseTreeElement.EnumType.DIV, new ParseTreeElement[]{})})))
);
return sequence(extendedIdentifier(), push(new HasChildrenParseTreeElement(HasChildrenParseTreeElement.EnumType.IDENTIFIER_OR_FUNCTION_OR_OPERATOR, new ParseTreeElement[]{pop()})));
}

Rule variable() {
Expand All @@ -67,6 +60,18 @@ Rule basicIdentifier() {
);
}

Rule extendedIdentifier() {
StringVar var = new StringVar();

return sequence(
anyOf("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+-*/=<>"),
var.append(match()),
zeroOrMore(anyOf("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+-*/=<>")),
push(new BasicIdentifierParseTreeElement(var.get() + match()))
);
}


Rule integer() {
StringVar var = new StringVar();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,18 @@ public static ResultAndControlflowPropagationInfo createResultForBoolean(final b
return result;
}

// called from generated code
public static boolean extractBoolean(ResultAndControlflowPropagationInfo info) {
return info.resultBoolean;
}

// called from generated code
public static int extractInteger(ResultAndControlflowPropagationInfo info) {
return info.resultInteger;
}




// used by codegeneration
public static String codegenGetJavaFunctionnameForCreationOfType(Typeinfo typeinfo) {
Expand All @@ -37,4 +49,15 @@ else if( typeinfo.type == Typeinfo.EnumType.BOOLEAN ) {
throw new RuntimeException("Internal Error: No function for Static Runtime found to create value of type!");
}

// used by codegeneration
public static String codegenGetJavaFunctionnameForExtractionOfValueOfType(Typeinfo typeinfo) {
if( typeinfo.type == Typeinfo.EnumType.BOOLEAN ) {
return "extractBoolean";
}
else if( typeinfo.type == Typeinfo.EnumType.INTEGER ) {
return "extractInteger";
}

throw new RuntimeException("Internal Error: No function for Static Runtime found to extract value of type!");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public static void main(String[] args) {
CtClass class0 = ctPool.makeClass("GeneratedCode");


ParseTreeElement parseTree = Parse.parse("(cond booleanX 5 6)");
ParseTreeElement parseTree = Parse.parse("(cond (< 5 9) 5 6)");
Element ast = ConvertParseTreeToAst.convert(parseTree);


Expand Down

0 comments on commit 7428f95

Please sign in to comment.