File indexing completed on 2024-12-08 11:06:54

0001 /***************************************************************************
0002  *   Copyright (C) 2003 by David Saxton                                    *
0003  *   david@bluehaze.org                                                    *
0004  *                                                                         *
0005  *   This program is free software; you can redistribute it and/or modify  *
0006  *   it under the terms of the GNU General Public License as published by  *
0007  *   the Free Software Foundation; either version 2 of the License, or     *
0008  *   (at your option) any later version.                                   *
0009  ***************************************************************************/
0010 
0011 #include "varcomparison.h"
0012 
0013 #include "flowcode.h"
0014 #include "libraryitem.h"
0015 #include "icndocument.h"
0016 
0017 #include <KLocalizedString>
0018 
0019 Item *VarComparison::construct(ItemDocument *itemDocument, bool newItem, const char *id)
0020 {
0021     return new VarComparison(static_cast<ICNDocument *>(itemDocument), newItem, id);
0022 }
0023 
0024 LibraryItem *VarComparison::libraryItem()
0025 {
0026     return new LibraryItem(QStringList(QString("flow/varcomparison")), i18n("Comparison"), i18n("Variables"), "branch.png", LibraryItem::lit_flowpart, VarComparison::construct);
0027 }
0028 
0029 VarComparison::VarComparison(ICNDocument *icnDocument, bool newItem, const char *id)
0030     : FlowPart(icnDocument, newItem, id ? id : "varcomparison")
0031 {
0032     m_name = i18n("Variable Comparison");
0033     initDecisionSymbol();
0034     createStdInput();
0035     createStdOutput();
0036     createAltOutput();
0037 
0038     createProperty("0var1", Variant::Type::Combo);
0039     property("0var1")->setCaption(i18n("Variable"));
0040     property("0var1")->setValue("x");
0041 
0042     createProperty("1op", Variant::Type::Select);
0043     property("1op")->setAllowed((QStringList("==") << "<"
0044                                                    << ">"
0045                                                    << "<="
0046                                                    << ">="
0047                                                    << "!="));
0048     property("1op")->setValue("==");
0049     property("1op")->setToolbarCaption(" ");
0050     property("1op")->setEditorCaption(i18n("Operation"));
0051 
0052     createProperty("2var2", Variant::Type::Combo);
0053     property("2var2")->setToolbarCaption(" ");
0054     property("2var2")->setEditorCaption(i18n("Value"));
0055     property("2var2")->setValue("0");
0056 
0057     addDisplayText("output_false", QRect(offsetX() + width(), 2, 40, 20), "No");
0058     addDisplayText("output_true", QRect(0, offsetY() + height(), 50, 20), "Yes");
0059 }
0060 
0061 VarComparison::~VarComparison()
0062 {
0063 }
0064 
0065 void VarComparison::dataChanged()
0066 {
0067     setCaption(dataString("0var1") + " " + dataString("1op") + " " + dataString("2var2") + " ?");
0068 }
0069 
0070 QString VarComparison::oppOp(const QString &op)
0071 {
0072     if (op == "==")
0073         return "!=";
0074     if (op == "!=")
0075         return "==";
0076     else if (op == "<")
0077         return ">=";
0078     else if (op == ">=")
0079         return "<";
0080     else if (op == ">")
0081         return "<=";
0082     else if (op == "<=")
0083         return ">";
0084     else
0085         return "__UNKNOWN_OP__";
0086 }
0087 
0088 void VarComparison::generateMicrobe(FlowCode *code)
0089 {
0090     QString var1 = dataString("0var1");
0091     QString var2 = dataString("2var2");
0092     QString test = dataString("1op");
0093 
0094     handleIfElse(code, var1 + " " + test + " " + var2, var1 + " " + oppOp(test) + " " + var2, "stdoutput", "altoutput");
0095 
0096 #if 0
0097     code->addCode( "if "+var1+" "+test+" "+var2+"\n{\n" );
0098     code->addCodeBranch( outputPart("stdoutput") );
0099     code->addCode("}");
0100     if ( outputPart("altoutput") )
0101     {
0102         code->addCode("else\n{");
0103         code->addCodeBranch( outputPart("altoutput") );
0104         code->addCode("}");
0105     }
0106 #endif
0107 
0108 #if 0
0109     QString newCode;
0110     
0111     if ( FlowCode::isLiteral(var2) ) newCode += "movlw " + var2 + " ; Move literal to register w\n";
0112     else
0113     {
0114         code->addVariable(var2);
0115         newCode += "movf " + var2 + ",0 ; Move " + var2 + " to register w\n";
0116     }
0117     
0118     if ( FlowCode::isLiteral(var1) ) newCode += "sublw " + var1 + " ; Subtract register w from " + var1 + ", placing result in w\n";
0119     else
0120     {
0121         code->addVariable(var1);
0122         newCode += "subwf " + var1 + ",0 ; Subtract register w from " + var1 + ", placing result in w\n";
0123     }
0124     
0125     
0126     if      ( test == "==" )
0127     {
0128         // check: works
0129         newCode += "btfss STATUS,2 ; Check if zero flag is set\n";
0130         newCode += gotoCode("altoutput") + " ; Result from calculation was non-zero; hence comparison is false\n";
0131         newCode += gotoCode("stdoutput") + " ; Ouput was zero; hence comparison is true, so continue from this point\n";
0132     }
0133     else if ( test == "!=" )
0134     {
0135         // check: works
0136         newCode += "btfsc STATUS,2 ; Check if zero flag is clear\n";
0137         newCode += gotoCode("altoutput") + " ; Result from calculation was zero; hence comparison is false\n";
0138         newCode += gotoCode("stdoutput") + " ; Output was non-zero; hence comparison is true, so continue from this point\n";
0139     }
0140     else if ( test == ">=" )
0141     {
0142         // check: works
0143         newCode += "btfss STATUS,0 ; Check if carry flag is set\n";
0144         newCode += gotoCode("altoutput") + " ; Result from calculation is negative; hence comparison is false\n";
0145         newCode += gotoCode("stdoutput") + " ; Result from calculation is positive or zero; so continue from this point\n";
0146     }
0147     else if ( test == ">" )
0148     {
0149         // check: works
0150         newCode += "btfss STATUS,0 ; Check if carry flag is set\n";
0151         newCode += gotoCode("altoutput") + " ; Result is negative; hence comparison is false\n";
0152         newCode += "btfsc STATUS,2 ; Check if zero flag is set\n";
0153         newCode += gotoCode("altoutput") + " ; Result is zero; hence comparison is false\n";
0154         newCode += gotoCode("stdoutput") + " ; Comparison is true, so continue from this point\n";
0155     }
0156     else if ( test == "<" )
0157     {
0158         // check: works
0159         newCode += "btfsc STATUS,0 ; Check if carry flag is set\n";
0160         newCode += gotoCode("altoutput");
0161         newCode += gotoCode("stdoutput");
0162     }
0163     else if ( test == "<=" )
0164     {
0165         // check: works
0166         newCode += "btfsc STATUS,2 ; Check if result is zero\n";
0167         newCode += gotoCode("stdoutput") + " ; Result is zero; hence comparison is true\n";
0168         newCode += "btfsc STATUS,0 ; Check if carry flag is set\n";
0169         newCode += gotoCode("altoutput") + " ; Result is positive (not zero, has already tested for this); hence comparison is false\n";
0170         newCode += gotoCode("stdoutput") + " ; Result is negative, hence comparison is true\n";
0171     }
0172     
0173     code->addCodeBlock( id(), newCode );
0174 #endif
0175 }