| 88 | | protected |
| 89 | | encapsulated function term "Evaluate term of an expression" |
| 90 | | import Modelica.Utilities.Types; |
| 91 | | import Modelica.Utilities.Strings; |
| 92 | | import Modelica.Utilities.Examples.expression.primary; |
| 93 | | import Modelica.Icons; |
| 94 | | extends Icons.Function; |
| 95 | | input String string; |
| 96 | | input Integer startIndex; |
| 97 | | input String message=""; |
| 98 | | output Real result; |
| 99 | | output Integer nextIndex; |
| 100 | | protected |
| 101 | | Real result2; |
| 102 | | Boolean scanning=true; |
| 103 | | String operator; |
| 104 | | algorithm |
| 105 | | // scan for "primary * primary" or "primary / primary" |
| 106 | | (result, nextIndex) := primary(string, startIndex, message); |
| 107 | | while scanning loop |
| 108 | | (operator, nextIndex) := Strings.scanDelimiter( |
| 109 | | string, nextIndex, {"*","/",""}, message); |
| 110 | | if operator == "" then |
| 111 | | scanning := false; |
| 112 | | else |
| 113 | | (result2, nextIndex) := primary(string, nextIndex, message); |
| 114 | | result := if operator == "*" then result*result2 else result/result2; |
| 115 | | end if; |
| 116 | | end while; |
| 117 | | end term; |
| 118 | | |
| 119 | | encapsulated function primary "Evaluate primary of an expression" |
| 120 | | import Modelica.Math; |
| 121 | | import Modelica.Constants; |
| 122 | | import Modelica.Utilities.Types; |
| 123 | | import Modelica.Utilities.Strings.*; |
| 124 | | import Modelica.Utilities.Examples.expression; |
| 125 | | import Modelica.Icons; |
| 126 | | extends Icons.Function; |
| 127 | | |
| 128 | | input String string; |
| 129 | | input Integer startIndex; |
| 130 | | input String message=""; |
| 131 | | output Real result; |
| 132 | | output Integer nextIndex; |
| 133 | | protected |
| 134 | | Types.TokenValue token; |
| 135 | | Real result2; |
| 136 | | String delimiter; |
| 137 | | String functionName; |
| 138 | | Real pi = Constants.pi; |
| 139 | | algorithm |
| 140 | | (token,nextIndex) := scanToken(string, startIndex,unsigned=true); |
| 141 | | if token.tokenType == Types.TokenType.DelimiterToken and token.string == "(" then |
| 142 | | (result,nextIndex) := expression(string, nextIndex,message); |
| 143 | | (delimiter,nextIndex) := scanDelimiter(string,nextIndex,{")"}, message); |
| 144 | | |
| 145 | | elseif token.tokenType == Types.TokenType.RealToken then |
| 146 | | result := token.real; |
| 147 | | |
| 148 | | elseif token.tokenType == Types.TokenType.IntegerToken then |
| 149 | | result := token.integer; |
| 150 | | |
| 151 | | elseif token.tokenType == Types.TokenType.IdentifierToken then |
| 152 | | if token.string == "pi" then |
| 153 | | result := pi; |
| 154 | | else |
| 155 | | functionName := token.string; |
| 156 | | (delimiter,nextIndex) := scanDelimiter(string,nextIndex,{"("}, message); |
| 157 | | (result,nextIndex) := expression(string, nextIndex, message); |
| 158 | | (delimiter,nextIndex) := scanDelimiter(string,nextIndex,{")"}, message); |
| 159 | | if functionName == "sin" then |
| 160 | | result := Math.sin(result); |
| 161 | | elseif functionName == "cos" then |
| 162 | | result := Math.cos(result); |
| 163 | | elseif functionName == "tan" then |
| 164 | | result := Math.tan(result); |
| 165 | | elseif functionName == "sqrt" then |
| 166 | | if result < 0.0 then |
| 167 | | syntaxError(string, startIndex, "Argument of call \"sqrt(" + String(result) + ")\" is negative.\n" + |
| 168 | | "Imaginary numbers are not supported by the calculator.\n" + message); |
| 169 | | end if; |
| 170 | | result := sqrt(result); |
| 171 | | else |
| 172 | | syntaxError(string, startIndex, "Function \"" + functionName + "\" is unknown (not supported)\n" + |
| 173 | | message); |
| 174 | | end if; |
| 175 | | end if; |
| 176 | | |
| 177 | | else |
| 178 | | syntaxError(string, startIndex, "Invalid primary of expression.\n" + message); |
| 179 | | end if; |
| 180 | | end primary; |
| 181 | | |
| 182 | | Real result2; |
| 183 | | String signOfNumber; |
| 184 | | Boolean scanning=true; |
| 185 | | String operator; |
| 186 | | algorithm |
| 187 | | // scan for optional leading "+" or "-" sign |
| 188 | | (signOfNumber, nextIndex) :=Strings.scanDelimiter( |
| 189 | | string, startIndex, {"+","-",""}, message); |
| 190 | | |
| 191 | | // scan for "term + term" or "term - term" |
| 192 | | (result, nextIndex) := term(string, nextIndex, message); |
| 193 | | if signOfNumber == "-" then |
| 194 | | result := -result; |
| 195 | | end if; |
| 196 | | |
| 197 | | while scanning loop |
| 198 | | (operator, nextIndex) := Strings.scanDelimiter( |
| 199 | | string, nextIndex, {"+","-",""}, message); |
| 200 | | if operator == "" then |
| 201 | | scanning := false; |
| 202 | | else |
| 203 | | (result2, nextIndex) := term(string, nextIndex, message); |
| 204 | | result := if operator == "+" then result+result2 else result-result2; |
| 205 | | end if; |
| 206 | | end while; |
| | 167 | |
| | 168 | protected |
| | 169 | function term "Evaluate term of an expression" |
| | 170 | extends Modelica.Icons.Function; |
| | 171 | input String string; |
| | 172 | input Integer startIndex; |
| | 173 | input String message=""; |
| | 174 | output Real result; |
| | 175 | output Integer nextIndex; |
| | 176 | protected |
| | 177 | Real result2; |
| | 178 | Boolean scanning=true; |
| | 179 | String operator; |
| | 180 | algorithm |
| | 181 | // scan for "primary * primary" or "primary / primary" |
| | 182 | (result, nextIndex) := primary(string, startIndex, message); |
| | 183 | while scanning loop |
| | 184 | (operator, nextIndex) := Strings.scanDelimiter( |
| | 185 | string, nextIndex, {"*","/",""}, message); |
| | 186 | if operator == "" then |
| | 187 | scanning := false; |
| | 188 | else |
| | 189 | (result2, nextIndex) := primary(string, nextIndex, message); |
| | 190 | result := if operator == "*" then result*result2 else result/result2; |
| | 191 | end if; |
| | 192 | end while; |
| | 193 | end term; |
| | 194 | |
| | 195 | function primary "Evaluate primary of an expression" |
| | 196 | extends Modelica.Icons.Function; |
| | 197 | |
| | 198 | input String string; |
| | 199 | input Integer startIndex; |
| | 200 | input String message=""; |
| | 201 | output Real result; |
| | 202 | output Integer nextIndex; |
| | 203 | protected |
| | 204 | Types.TokenValue token; |
| | 205 | Real result2; |
| | 206 | String delimiter; |
| | 207 | String functionName; |
| | 208 | Real pi = Constants.pi; |
| | 209 | algorithm |
| | 210 | (token,nextIndex) := Strings.scanToken(string, startIndex,unsigned=true); |
| | 211 | if token.tokenType == Types.TokenType.DelimiterToken and token.string == "(" then |
| | 212 | (result,nextIndex) := expression(string, nextIndex,message); |
| | 213 | (delimiter,nextIndex) := Strings.scanDelimiter(string,nextIndex,{")"}, message); |
| | 214 | |
| | 215 | elseif token.tokenType == Types.TokenType.RealToken then |
| | 216 | result := token.real; |
| | 217 | |
| | 218 | elseif token.tokenType == Types.TokenType.IntegerToken then |
| | 219 | result := token.integer; |
| | 220 | |
| | 221 | elseif token.tokenType == Types.TokenType.IdentifierToken then |
| | 222 | if token.string == "pi" then |
| | 223 | result := pi; |
| | 224 | else |
| | 225 | functionName := token.string; |
| | 226 | (delimiter,nextIndex) := Strings.scanDelimiter(string,nextIndex,{"("}, message); |
| | 227 | (result,nextIndex) := expression(string, nextIndex, message); |
| | 228 | (delimiter,nextIndex) := Strings.scanDelimiter(string,nextIndex,{")"}, message); |
| | 229 | if functionName == "sin" then |
| | 230 | result := Math.sin(result); |
| | 231 | elseif functionName == "cos" then |
| | 232 | result := Math.cos(result); |
| | 233 | elseif functionName == "tan" then |
| | 234 | result := Math.tan(result); |
| | 235 | elseif functionName == "sqrt" then |
| | 236 | if result < 0.0 then |
| | 237 | Strings.syntaxError(string, startIndex, "Argument of call \"sqrt(" + String(result) + ")\" is negative.\n" + |
| | 238 | "Imaginary numbers are not supported by the calculator.\n" + message); |
| | 239 | end if; |
| | 240 | result := sqrt(result); |
| | 241 | else |
| | 242 | Strings.syntaxError(string, startIndex, "Function \"" + functionName + "\" is unknown (not supported)\n" + |
| | 243 | message); |
| | 244 | end if; |
| | 245 | end if; |
| | 246 | |
| | 247 | else |
| | 248 | Strings.syntaxError(string, startIndex, "Invalid primary of expression.\n" + message); |
| | 249 | end if; |
| | 250 | end primary; |
| | 251 | |
| | 252 | Real result2; |
| | 253 | String signOfNumber; |
| | 254 | Boolean scanning=true; |
| | 255 | String operator; |
| | 256 | algorithm |
| | 257 | // scan for optional leading "+" or "-" sign |
| | 258 | (signOfNumber, nextIndex) :=Strings.scanDelimiter( |
| | 259 | string, startIndex, {"+","-",""}, message); |
| | 260 | |
| | 261 | // scan for "term + term" or "term - term" |
| | 262 | (result, nextIndex) := term(string, nextIndex, message); |
| | 263 | if signOfNumber == "-" then |
| | 264 | result := -result; |
| | 265 | end if; |
| | 266 | |
| | 267 | while scanning loop |
| | 268 | (operator, nextIndex) := Strings.scanDelimiter( |
| | 269 | string, nextIndex, {"+","-",""}, message); |
| | 270 | if operator == "" then |
| | 271 | scanning := false; |
| | 272 | else |
| | 273 | (result2, nextIndex) := term(string, nextIndex, message); |
| | 274 | result := if operator == "+" then result+result2 else result-result2; |
| | 275 | end if; |
| | 276 | end while; |
| | 277 | |
| | 288 | |
| | 289 | annotation (Documentation(info="<html> |
| | 290 | <h4>Syntax</h4> |
| | 291 | <blockquote><pre> |
| | 292 | result = <b>readRealParameter</b>(fileName, name); |
| | 293 | </pre></blockquote> |
| | 294 | <h4>Description</h4> |
| | 295 | <p> |
| | 296 | This function demonstrates how a function can be implemented |
| | 297 | that reads the value of a parameter from file. The function |
| | 298 | performs the following actions: |
| | 299 | </p> |
| | 300 | <ol> |
| | 301 | <li> It opens file \"fileName\" and reads the lines of the file.</li> |
| | 302 | <li> In every line, Modelica line comments (\"// ... end-of-line\") |
| | 303 | are skipped </li> |
| | 304 | <li> If a line consists of \"name = expression\" and the \"name\" |
| | 305 | in this line is identical to the second argument \"name\" |
| | 306 | of the function call, the expression calculator Examples.expression |
| | 307 | is used to evaluate the expression after the \"=\" character. |
| | 308 | The expression can optionally be terminated with a \";\".</li> |
| | 309 | <li> The result of the expression evaluation is returned as |
| | 310 | the value of the parameter \"name\". </li> |
| | 311 | </ol> |
| | 312 | <h4>Example</h4> |
| | 313 | <p> |
| | 314 | On file \"test.txt\" the following lines might be present: |
| | 315 | </p> |
| | 316 | <blockquote><pre> |
| | 317 | // Motor data |
| | 318 | J = 2.3 // inertia |
| | 319 | w_rel0 = 1.5*2; // relative angular velocity |
| | 320 | phi_rel0 = pi/3 |
| | 321 | </pre></blockquote> |
| | 322 | <p> |
| | 323 | The function returns the value \"3.0\" when called as: |
| | 324 | </p> |
| | 325 | <blockquote><pre> |
| | 326 | readRealParameter(\"test.txt\", \"w_rel0\") |
| | 327 | </pre></blockquote> |
| | 328 | </html>")); |
| | 329 | |
| 331 | | annotation (preferedView="info",Documentation(info="<html> |
| 332 | | <h4>Syntax</h4> |
| 333 | | <blockquote><pre> |
| 334 | | result = <b>readRealParameter</b>(fileName, name); |
| 335 | | </pre></blockquote> |
| 336 | | <h4>Description</h4> |
| 337 | | <p> |
| 338 | | This function demonstrates how a function can be implemented |
| 339 | | that reads the value of a parameter from file. The function |
| 340 | | performs the following actions: |
| 341 | | </p> |
| 342 | | <ol> |
| 343 | | <li> It opens file \"fileName\" and reads the lines of the file.</li> |
| 344 | | <li> In every line, Modelica line comments (\"// ... end-of-line\") |
| 345 | | are skipped </li> |
| 346 | | <li> If a line consists of \"name = expression\" and the \"name\" |
| 347 | | in this line is identical to the second argument \"name\" |
| 348 | | of the function call, the expression calculator Examples.expression |
| 349 | | is used to evaluate the expression after the \"=\" character. |
| 350 | | The expression can optionally be terminated with a \";\".</li> |
| 351 | | <li> The result of the expression evaluation is returned as |
| 352 | | the value of the parameter \"name\". </li> |
| 353 | | </ol> |
| 354 | | <h4>Example</h4> |
| 355 | | <p> |
| 356 | | On file \"test.txt\" the following lines might be present: |
| 357 | | </p> |
| 358 | | <blockquote><pre> |
| 359 | | // Motor data |
| 360 | | J = 2.3 // inertia |
| 361 | | w_rel0 = 1.5*2; // relative angular velocity |
| 362 | | phi_rel0 = pi/3 |
| 363 | | </pre></blockquote> |
| 364 | | <p> |
| 365 | | The function returns the value \"3.0\" when called as: |
| 366 | | </p> |
| 367 | | <blockquote><pre> |
| 368 | | readRealParameter(\"test.txt\", \"w_rel0\") |
| 369 | | </pre></blockquote> |
| 370 | | </html>")); |
| | 374 | |