001package jmri.jmrit.logixng.util.parser.functions; 002 003import java.util.HashSet; 004import java.util.List; 005import java.util.Set; 006 007import jmri.JmriException; 008import jmri.jmrit.logixng.SymbolTable; 009import jmri.jmrit.logixng.util.parser.*; 010import jmri.util.TypeConversionUtil; 011 012import org.openide.util.lookup.ServiceProvider; 013 014/** 015 * Implementation of conversion functions. 016 * 017 * @author Daniel Bergqvist 2020 018 */ 019@ServiceProvider(service = FunctionFactory.class) 020public class ConvertFunctions implements FunctionFactory { 021 022 @Override 023 public String getModule() { 024 return "Convert"; 025 } 026 027 @Override 028 public Set<Function> getFunctions() { 029 Set<Function> functionClasses = new HashSet<>(); 030 031 addIsIntFunction(functionClasses); 032 addIsFloatFunction(functionClasses); 033 addBoolFunction(functionClasses); 034 addBoolJythonFunction(functionClasses); 035 addIntFunction(functionClasses); 036 addFloatFunction(functionClasses); 037 addStrFunction(functionClasses); 038 addHex2DecFunction(functionClasses); 039 040 return functionClasses; 041 } 042 043 @Override 044 public Set<Constant> getConstants() { 045 return new HashSet<>(); 046 } 047 048 @Override 049 public String getConstantDescription() { 050 // This module doesn't define any constants 051 return null; 052 } 053 054 private void addIsIntFunction(Set<Function> functionClasses) { 055 functionClasses.add(new AbstractFunction(this, "isInt", Bundle.getMessage("Convert.isInt")) { 056 @Override 057 public Object calculate(SymbolTable symbolTable, List<ExpressionNode> parameterList) 058 throws JmriException { 059 060 if (parameterList.size() != 1) { 061 throw new WrongNumberOfParametersException(Bundle.getMessage("WrongNumberOfParameters2", getName(), 1)); 062 } 063 try { 064 TypeConversionUtil.convertToLong( 065 parameterList.get(0).calculate(symbolTable), 066 true, true); 067 return true; 068 } catch (NumberFormatException e) { 069 return false; 070 } 071 } 072 }); 073 } 074 075 private void addIsFloatFunction(Set<Function> functionClasses) { 076 functionClasses.add(new AbstractFunction(this, "isFloat", Bundle.getMessage("Convert.isFloat")) { 077 @Override 078 public Object calculate(SymbolTable symbolTable, List<ExpressionNode> parameterList) 079 throws JmriException { 080 081 try { 082 switch (parameterList.size()) { 083 case 1: 084 TypeConversionUtil.convertToDouble(parameterList.get(0).calculate(symbolTable), false, true, true); 085 break; 086 case 2: 087 boolean do_i18n = TypeConversionUtil.convertToBoolean( 088 parameterList.get(0).calculate(symbolTable), false); 089 TypeConversionUtil.convertToDouble( 090 parameterList.get(0).calculate(symbolTable), do_i18n, true, true); 091 break; 092 default: 093 throw new WrongNumberOfParametersException(Bundle.getMessage("WrongNumberOfParameters2", getName(), 1)); 094 } 095 return true; 096 } catch (NumberFormatException e) { 097 return false; 098 } 099 } 100 }); 101 } 102 103 private void addBoolFunction(Set<Function> functionClasses) { 104 functionClasses.add(new AbstractFunction(this, "bool", Bundle.getMessage("Convert.bool")) { 105 @Override 106 public Object calculate(SymbolTable symbolTable, List<ExpressionNode> parameterList) 107 throws JmriException { 108 109 switch (parameterList.size()) { 110 case 1: 111 return TypeConversionUtil.convertToBoolean(parameterList.get(0).calculate(symbolTable), false); 112 case 2: 113 boolean do_i18n = TypeConversionUtil.convertToBoolean( 114 parameterList.get(0).calculate(symbolTable), false); 115 return TypeConversionUtil.convertToBoolean( 116 parameterList.get(0).calculate(symbolTable), do_i18n); 117 default: 118 throw new WrongNumberOfParametersException(Bundle.getMessage("WrongNumberOfParameters2", getName(), 1)); 119 } 120 } 121 }); 122 } 123 124 private void addBoolJythonFunction(Set<Function> functionClasses) { 125 functionClasses.add(new AbstractFunction(this, "boolJython", Bundle.getMessage("Convert.boolJython")) { 126 @Override 127 public Object calculate(SymbolTable symbolTable, List<ExpressionNode> parameterList) 128 throws JmriException { 129 130 switch (parameterList.size()) { 131 case 1: 132 return TypeConversionUtil.convertToBoolean_JythonRules(parameterList.get(0).calculate(symbolTable), false); 133 case 2: 134 boolean do_i18n = TypeConversionUtil.convertToBoolean_JythonRules( 135 parameterList.get(0).calculate(symbolTable), false); 136 return TypeConversionUtil.convertToBoolean( 137 parameterList.get(0).calculate(symbolTable), do_i18n); 138 default: 139 throw new WrongNumberOfParametersException(Bundle.getMessage("WrongNumberOfParameters2", getName(), 1)); 140 } 141 } 142 }); 143 } 144 145 private void addIntFunction(Set<Function> functionClasses) { 146 functionClasses.add(new AbstractFunction(this, "int", Bundle.getMessage("Convert.int")) { 147 @Override 148 public Object calculate(SymbolTable symbolTable, List<ExpressionNode> parameterList) 149 throws JmriException { 150 151 if (parameterList.size() != 1) { 152 throw new WrongNumberOfParametersException(Bundle.getMessage("WrongNumberOfParameters2", getName(), 1)); 153 } 154 return TypeConversionUtil.convertToLong( 155 parameterList.get(0).calculate(symbolTable)); 156 } 157 }); 158 } 159 160 private void addFloatFunction(Set<Function> functionClasses) { 161 functionClasses.add(new AbstractFunction(this, "float", Bundle.getMessage("Convert.float")) { 162 @Override 163 public Object calculate(SymbolTable symbolTable, List<ExpressionNode> parameterList) 164 throws JmriException { 165 166 switch (parameterList.size()) { 167 case 1: 168 return TypeConversionUtil.convertToDouble(parameterList.get(0).calculate(symbolTable), false); 169 case 2: 170 boolean do_i18n = TypeConversionUtil.convertToBoolean( 171 parameterList.get(0).calculate(symbolTable), false); 172 return TypeConversionUtil.convertToDouble( 173 parameterList.get(0).calculate(symbolTable), do_i18n); 174 default: 175 throw new WrongNumberOfParametersException(Bundle.getMessage("WrongNumberOfParameters2", getName(), 1)); 176 } 177 } 178 }); 179 } 180 181 private void addStrFunction(Set<Function> functionClasses) { 182 functionClasses.add(new AbstractFunction(this, "str", Bundle.getMessage("Convert.str_Descr")) { 183 @Override 184 public Object calculate(SymbolTable symbolTable, List<ExpressionNode> parameterList) 185 throws JmriException { 186 187 switch (parameterList.size()) { 188 case 1: 189 return TypeConversionUtil.convertToString(parameterList.get(0).calculate(symbolTable), false); 190 case 2: 191 boolean do_i18n = TypeConversionUtil.convertToBoolean( 192 parameterList.get(0).calculate(symbolTable), false); 193 return TypeConversionUtil.convertToString( 194 parameterList.get(0).calculate(symbolTable), do_i18n); 195 default: 196 throw new WrongNumberOfParametersException(Bundle.getMessage("WrongNumberOfParameters2", getName(), 1)); 197 } 198 } 199 }); 200 } 201 202 private void addHex2DecFunction(Set<Function> functionClasses) { 203 functionClasses.add(new AbstractFunction(this, "hex2dec", Bundle.getMessage("Convert.hex2dec")) { 204 @Override 205 public Object calculate(SymbolTable symbolTable, List<ExpressionNode> parameterList) 206 throws JmriException { 207 208 if (parameterList.size() != 1) { 209 throw new WrongNumberOfParametersException(Bundle.getMessage("WrongNumberOfParameters2", getName(), 1)); 210 } 211 Object o = parameterList.get(0).calculate(symbolTable); 212 if (o != null) { 213 return Long.parseLong(o.toString(), 16); 214 } else { 215 throw new NullPointerException("value is null"); 216 } 217 } 218 }); 219 } 220 221}