diff --git a/java/ptrman/causalReasoningSystem/functional/language/codegen/CodegenJava.java b/java/ptrman/causalReasoningSystem/functional/language/codegen/CodegenJava.java index 0975834..573db29 100644 --- a/java/ptrman/causalReasoningSystem/functional/language/codegen/CodegenJava.java +++ b/java/ptrman/causalReasoningSystem/functional/language/codegen/CodegenJava.java @@ -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 >"); @@ -111,6 +128,93 @@ else if( astElement.type.isEqualWithType(new Type(Type.EnumType.VARIABLE)) ) { } } + private InlinedResultCodeWithType generateBodyForwardPassForComparision(String operationString, Element astElement, Map typeinfoOfVariables) throws CannotCompileException { + // check if types are all equal + final List inlinedResultCodeForArguments = inlineResultCodeForAllArguments(astElement, typeinfoOfVariables); + final List 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 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 typeinfoOfVariables) throws CannotCompileException { final String variableName = astElement.identifier; diff --git a/java/ptrman/causalReasoningSystem/functional/language/codegen/Typeinfo.java b/java/ptrman/causalReasoningSystem/functional/language/codegen/Typeinfo.java index 0ae6c32..47bdf75 100644 --- a/java/ptrman/causalReasoningSystem/functional/language/codegen/Typeinfo.java +++ b/java/ptrman/causalReasoningSystem/functional/language/codegen/Typeinfo.java @@ -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 } @@ -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!"); } diff --git a/java/ptrman/causalReasoningSystem/functional/language/parser/Parser.java b/java/ptrman/causalReasoningSystem/functional/language/parser/Parser.java index 5c62816..580199f 100644 --- a/java/ptrman/causalReasoningSystem/functional/language/parser/Parser.java +++ b/java/ptrman/causalReasoningSystem/functional/language/parser/Parser.java @@ -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() { @@ -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(); diff --git a/java/ptrman/causalReasoningSystem/functional/language/runtime/ResultAndControlflowPropagationInfo.java b/java/ptrman/causalReasoningSystem/functional/language/runtime/ResultAndControlflowPropagationInfo.java index 04b9eee..4eb8a38 100644 --- a/java/ptrman/causalReasoningSystem/functional/language/runtime/ResultAndControlflowPropagationInfo.java +++ b/java/ptrman/causalReasoningSystem/functional/language/runtime/ResultAndControlflowPropagationInfo.java @@ -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) { @@ -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!"); + } } diff --git a/java/ptrman/causalReasoningSystem/interactiveTests/CodeGenTest.java b/java/ptrman/causalReasoningSystem/interactiveTests/CodeGenTest.java index 9353c5b..d5db057 100644 --- a/java/ptrman/causalReasoningSystem/interactiveTests/CodeGenTest.java +++ b/java/ptrman/causalReasoningSystem/interactiveTests/CodeGenTest.java @@ -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);