/[svn]/linuxsampler/trunk/src/scriptvm/common.cpp
ViewVC logotype

Annotation of /linuxsampler/trunk/src/scriptvm/common.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3581 - (hide annotations) (download)
Fri Aug 30 11:40:25 2019 UTC (4 years, 7 months ago) by schoenebeck
File size: 8548 byte(s)
NKSP: Allow more wider support of standard measuring units & 'final'ness.

* Raised compiler requirement to be C++14 compliant (due to severe
  restrictions regarding C-style aggregate initializer lists in C++11
  which are now massively used throughout the code base).

* NKSP VM API: Allow units and 'final'ness to be returned as result from
  built-in functions (added methods VMFunction::returnUnitType() and
  VMFunction::returnsFinal() for that purpose which must be implemented by
  built-in function implementations).

* NKSP language: Allow metric unit prefixes of numeric scalar and array
  variables to be changed freely at runtime (unlike unit types like Hz etc.
  which are still sticky parse-time features of variables which cannot be
  changed at runtime for the intentional sake of determinism).

* NKSP language: 'final' values are prohibited for array variables for now
  (attempt causes a parsers error).

* NKSP language: expressions with unit types (e.g. Hz) are prohibited for
  conditions of runtime control structures like if(), while(), select()
  (attempt causes a parser error).

* NKSP VM API: Allow built-in functions to perform their own, individual
  parse time checks of arguments going to be passed to the function at
  runtime (added method VMFunction::checkArgs() for that purpose).

* NKSP language: raise parser warning if only one operand of binary
  operators (like logical 'or' comparison) contain a 'final' value (because
  it would always yield in a 'final' result in such cases).

* NKSP language: Allow comparison (=, #, <, >, <=, >=) of values with
  different metric unit prefixes, which will behave as expected (e.g.
  result of expression '1000us < 2ms' is true).

* NKSP language: Allow adding values with different metric unit prefixes
  (e.g. result of expression '100Hz + 5kHz' is '5100Hz').

* NKSP language: Allow subtracting values with different metric unit
  prefixes (e.g. result of expression '1ms - 20us' is '980us').

* NKSP language: Allow multiplying with any metric unit prefixes
  (e.g. result of expression '2k * 3ms' is '6s'), however multiplications
  with unit types on both sides (e.g. '2s * 2s') is still prohibited since
  we don't have any considerable practical use for a term like '4s^2'
  (hence any attempt multiplying two unit types still causes parser error).

* NKSP language: Allow dividing by any metric unit prefixes and allow
  division of same unit type on both sides (e.g. expression '8kHz / 1000Hz'
  yields in unit free result '8'). So this is now a way to cast units away
  e.g. for passing the result to other expressions, certain function calls
  or variables which are not accepting any units (or that specific unit).

* NKSP language: integer arrays and real number arrays can now be converted
  to strings (e.g. for dumping their content with message() calls for
  script debugging purposes).

* NKSP language: expressions and variables with units are now correctly
  casted to strings (e.g. with message() calls).

* NKSP language: comparing real numbers for equalness (e.g. '~foo = 3.1') or
  unequalness (e.g. '~foo # 3.1') is now less strict and takes the expected
  floating point tolerances into account.

* NKSP VM API: Added methods VMScalarNumberExpr::evalCastInt() and
  VMScalarNumberExpr::evalCastReal().

* NKSP VM API: Added base class 'VMNumberArrayExpr' for classes
  'VMIntArrayExpr' and 'VMRealArrayExpr'.

* NKSP VM API: replaced all unitPrefix() (parse time) methods by
  unitFactor() (runtime) methods.

* Built-in function "exit()" supports now returning units and 'final'ness
  exclusively for test cases.

* The following built-in functions support now units as well: "abs()",
  "random()", "inc()", "dec()", "in_range()", "min()", "max()",
  "real_to_int()", "int()", "int_to_real()" and "real()".

* Built-in functions "array_equal()", "search()" and "sort()" support now
  real number arrays (correctly) as well.

* Added individual parse time checks of arguments to be passed to built-in
  functions "random()", "inc()", "dec()", "in_range()", "min()", "max()",
  "array_equal()" and "search()" specific for their individual purposes.

* Test cases: Added massive amount of NKSP test cases for standard
  measuring units and 'final' operator usage cases.

* Test cases: Added NKSP test cases for (floating point tolerance aware)
  real number equalness / unequalness comparison.

* Bumped version (2.1.1.svn8).

1 schoenebeck 2596 /*
2 schoenebeck 3561 * Copyright (c) 2014-2019 Christian Schoenebeck
3 schoenebeck 2596 *
4     * http://www.linuxsampler.org
5     *
6     * This file is part of LinuxSampler and released under the same terms.
7     * See README file for details.
8     */
9    
10     #include "common.h"
11 schoenebeck 2598 #include <iostream>
12 schoenebeck 2885 #include "editor/SourceToken.h"
13 schoenebeck 2596
14     namespace LinuxSampler {
15    
16 schoenebeck 3561 ///////////////////////////////////////////////////////////////////////
17     // class 'VMUnit'
18    
19     static vmfloat _unitFactor(MetricPrefix_t prefix) {
20     switch (prefix) {
21     case VM_NO_PREFIX: return 1.f;
22     case VM_KILO: return 1000.f;
23     case VM_HECTO: return 100.f;
24     case VM_DECA: return 10.f;
25     case VM_DECI: return 0.1f;
26     case VM_CENTI: return 0.01f;
27     case VM_MILLI: return 0.001f;
28     case VM_MICRO: return 0.000001f;
29     }
30     return 1.f;
31     }
32    
33     vmfloat VMUnit::unitFactor(MetricPrefix_t prefix) {
34     return _unitFactor(prefix);
35     }
36    
37     vmfloat VMUnit::unitFactor(MetricPrefix_t prefix1, MetricPrefix_t prefix2) {
38     return _unitFactor(prefix1) * _unitFactor(prefix2);
39     }
40    
41 schoenebeck 3581 vmfloat VMUnit::unitFactor(const MetricPrefix_t* prefixes, vmuint size) {
42     vmfloat f = VM_NO_FACTOR;
43     for (vmuint i = 0; i < size && prefixes[i]; ++i)
44     f *= _unitFactor(prefixes[i]);
45 schoenebeck 3561 return f;
46     }
47    
48 schoenebeck 3581 bool VMUnit::hasUnitFactorNow() const {
49     return unitFactor() != VM_NO_FACTOR;
50     }
51    
52 schoenebeck 3561 ///////////////////////////////////////////////////////////////////////
53     // class 'VMExpr'
54    
55 schoenebeck 2596 VMIntExpr* VMExpr::asInt() const {
56     return const_cast<VMIntExpr*>( dynamic_cast<const VMIntExpr*>(this) );
57     }
58    
59 schoenebeck 3573 VMRealExpr* VMExpr::asReal() const {
60     return const_cast<VMRealExpr*>( dynamic_cast<const VMRealExpr*>(this) );
61     }
62    
63     VMScalarNumberExpr* VMExpr::asScalarNumberExpr() const {
64     return const_cast<VMScalarNumberExpr*>(
65     dynamic_cast<const VMScalarNumberExpr*>(this)
66     );
67     }
68    
69 schoenebeck 2596 VMStringExpr* VMExpr::asString() const {
70     return const_cast<VMStringExpr*>( dynamic_cast<const VMStringExpr*>(this) );
71     }
72    
73 schoenebeck 2619 VMIntArrayExpr* VMExpr::asIntArray() const {
74     return const_cast<VMIntArrayExpr*>( dynamic_cast<const VMIntArrayExpr*>(this) );
75     }
76    
77 schoenebeck 3573 VMRealArrayExpr* VMExpr::asRealArray() const {
78     return const_cast<VMRealArrayExpr*>(
79     dynamic_cast<const VMRealArrayExpr*>(this)
80     );
81     }
82    
83 schoenebeck 3581 VMArrayExpr* VMExpr::asArray() const {
84     return const_cast<VMArrayExpr*>(
85     dynamic_cast<const VMArrayExpr*>(this)
86     );
87     }
88    
89 schoenebeck 2945 bool VMExpr::isModifyable() const {
90     const VMVariable* var = dynamic_cast<const VMVariable*>(this);
91     return (!var) ? false : var->isAssignable();
92     }
93    
94 schoenebeck 3561 bool VMFunction::acceptsArgUnitType(vmint iArg, StdUnit_t type) const {
95     return type == VM_NO_UNIT;
96     }
97    
98 schoenebeck 3564 bool VMFunction::acceptsArgUnitPrefix(vmint iArg, StdUnit_t type) const {
99 schoenebeck 3561 return false;
100     }
101    
102     bool VMFunction::acceptsArgFinal(vmint iArg) const {
103     return false;
104     }
105    
106 schoenebeck 3581 void VMFunction::checkArgs(VMFnArgs* args,
107     std::function<void(String)> err,
108     std::function<void(String)> wrn)
109     {
110     }
111    
112 schoenebeck 2598 void VMFunction::wrnMsg(const String& txt) {
113     std::cout << "[ScriptVM] " << txt << std::endl;
114     }
115    
116     void VMFunction::errMsg(const String& txt) {
117     std::cerr << "[ScriptVM] " << txt << std::endl;
118     }
119 schoenebeck 3561
120     ///////////////////////////////////////////////////////////////////////
121 schoenebeck 3581 // class 'VMScalarNumberExpr'
122    
123     vmint VMScalarNumberExpr::evalCastInt() {
124     if (exprType() == INT_EXPR)
125     return asInt()->evalInt();
126     else
127     return vmint( asReal()->evalReal() );
128     }
129    
130     vmfloat VMScalarNumberExpr::evalCastReal() {
131     if (exprType() == REAL_EXPR)
132     return asReal()->evalReal();
133     else
134     return vmfloat( asInt()->evalInt() );
135     }
136    
137     ///////////////////////////////////////////////////////////////////////
138 schoenebeck 3561 // class 'VMIntExpr'
139    
140     vmint VMIntExpr::evalInt(MetricPrefix_t prefix) {
141     vmfloat f = (vmfloat) evalInt();
142     vmfloat factor = unitFactor() / _unitFactor(prefix);
143     return (vmint) f * factor;
144     }
145    
146     vmint VMIntExpr::evalInt(MetricPrefix_t prefix1, MetricPrefix_t prefix2) {
147     vmfloat f = (vmfloat) evalInt();
148     vmfloat factor = unitFactor() /
149     ( _unitFactor(prefix1) * _unitFactor(prefix2) );
150     return (vmint) f * factor;
151     }
152 schoenebeck 3573
153 schoenebeck 2885 ///////////////////////////////////////////////////////////////////////
154 schoenebeck 3573 // class 'VMRealExpr'
155    
156     vmfloat VMRealExpr::evalReal(MetricPrefix_t prefix) {
157     vmfloat f = evalReal();
158     vmfloat factor = unitFactor() / _unitFactor(prefix);
159     return f * factor;
160     }
161    
162     vmfloat VMRealExpr::evalReal(MetricPrefix_t prefix1, MetricPrefix_t prefix2) {
163     vmfloat f = evalReal();
164     vmfloat factor = unitFactor() /
165     ( _unitFactor(prefix1) * _unitFactor(prefix2) );
166     return f * factor;
167     }
168    
169     ///////////////////////////////////////////////////////////////////////
170 schoenebeck 2885 // class 'VMSourceToken'
171 schoenebeck 2598
172 schoenebeck 2885 VMSourceToken::VMSourceToken() : m_token(NULL) {
173     }
174    
175     VMSourceToken::VMSourceToken(SourceToken* ct) : m_token(ct) {
176     }
177    
178     VMSourceToken::VMSourceToken(const VMSourceToken& other) {
179     if (other.m_token) {
180     m_token = new SourceToken;
181     *m_token = *other.m_token;
182     } else m_token = NULL;
183     }
184    
185     VMSourceToken::~VMSourceToken() {
186     if (m_token) {
187     delete m_token;
188     m_token = NULL;
189     }
190     }
191    
192     VMSourceToken& VMSourceToken::operator=(const VMSourceToken& other) {
193     if (m_token) delete m_token;
194     if (other.m_token) {
195     m_token = new SourceToken;
196     *m_token = *other.m_token;
197     } else m_token = NULL;
198     return *this;
199     }
200    
201     String VMSourceToken::text() const {
202     return (m_token) ? m_token->text() : "";
203     }
204    
205     int VMSourceToken::firstLine() const {
206     return (m_token) ? m_token->firstLine() : 0;
207     }
208    
209     int VMSourceToken::firstColumn() const {
210     return (m_token) ? m_token->firstColumn() : 0;
211     }
212    
213     bool VMSourceToken::isEOF() const {
214     return (m_token) ? m_token->isEOF() : true;
215     }
216    
217     bool VMSourceToken::isNewLine() const {
218     return (m_token) ? m_token->isNewLine() : false;
219     }
220    
221     bool VMSourceToken::isKeyword() const {
222     return (m_token) ? m_token->isKeyword() : false;
223     }
224    
225     bool VMSourceToken::isVariableName() const {
226     return (m_token) ? m_token->isVariableName() : false;
227     }
228    
229     bool VMSourceToken::isIdentifier() const {
230     return (m_token) ? m_token->isIdentifier() : false;
231     }
232    
233     bool VMSourceToken::isNumberLiteral() const {
234     return (m_token) ? m_token->isNumberLiteral() : false;
235     }
236    
237     bool VMSourceToken::isStringLiteral() const {
238     return (m_token) ? m_token->isStringLiteral() : false;
239     }
240    
241     bool VMSourceToken::isComment() const {
242     return (m_token) ? m_token->isComment() : false;
243     }
244    
245     bool VMSourceToken::isPreprocessor() const {
246     return (m_token) ? m_token->isPreprocessor() : false;
247     }
248    
249 schoenebeck 3562 bool VMSourceToken::isMetricPrefix() const {
250     return (m_token) ? m_token->isMetricPrefix() : false;
251     }
252    
253     bool VMSourceToken::isStdUnit() const {
254     return (m_token) ? m_token->isStdUnit() : false;
255     }
256    
257 schoenebeck 2885 bool VMSourceToken::isOther() const {
258     return (m_token) ? m_token->isOther() : true;
259     }
260    
261     bool VMSourceToken::isIntegerVariable() const {
262     return (m_token) ? m_token->isIntegerVariable() : false;
263     }
264    
265 schoenebeck 3573 bool VMSourceToken::isRealVariable() const {
266     return (m_token) ? m_token->isRealVariable() : false;
267     }
268    
269 schoenebeck 2885 bool VMSourceToken::isStringVariable() const {
270     return (m_token) ? m_token->isStringVariable() : false;
271     }
272    
273 schoenebeck 3573 bool VMSourceToken::isIntArrayVariable() const {
274     return (m_token) ? m_token->isIntegerArrayVariable() : false;
275 schoenebeck 2885 }
276    
277 schoenebeck 3573 bool VMSourceToken::isRealArrayVariable() const {
278     return (m_token) ? m_token->isRealArrayVariable() : false;
279     }
280    
281     bool VMSourceToken::isArrayVariable() const { // deprecated API: will be removed !
282     return isIntArrayVariable();
283     }
284    
285 schoenebeck 2885 bool VMSourceToken::isEventHandlerName() const {
286     return (m_token) ? m_token->isEventHandlerName() : false;
287     }
288    
289 schoenebeck 2596 } // namespace LinuxSampler

  ViewVC Help
Powered by ViewVC