4 * Copyright 2004-2007 MTBJ, Inc.
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
19 package com
.dtrules
.interpreter
.operators
;
21 import com
.dtrules
.decisiontables
.RDecisionTable
;
22 import com
.dtrules
.entity
.IREntity
;
23 import com
.dtrules
.infrastructure
.RulesException
;
24 import com
.dtrules
.interpreter
.IRObject
;
25 import com
.dtrules
.interpreter
.RBoolean
;
26 import com
.dtrules
.interpreter
.RInteger
;
27 import com
.dtrules
.interpreter
.RName
;
28 import com
.dtrules
.interpreter
.RNull
;
29 import com
.dtrules
.interpreter
.RString
;
30 import com
.dtrules
.session
.DTState
;
31 import com
.dtrules
.session
.RSession
;
33 public class RMiscOps
{
53 new I(); new J(); new K();
77 * ( -- RNull ) Return the Null object
79 static class Null
extends ROperator
{
83 public void execute(DTState state
) throws RulesException
{
84 state
.datapush(RNull
.getRNull());
90 * ( entity -- RName ) Get the name of the given entity.
92 static class EntityName
extends ROperator
{
96 public void execute(DTState state
) throws RulesException
{
97 IREntity entity
= state
.datapop().rEntityValue();
98 state
.datapush(entity
.getName());
102 * ( Exception message -- ) Throws a RulesException with the given message.
107 static class RError
extends ROperator
{
108 RError(){super("error");}
110 public void execute(DTState state
) throws RulesException
{
111 String message
= state
.datapop().stringValue();
112 String exception
= state
.datapop().stringValue();
114 throw new RulesException(
118 } catch (Exception e
) {
119 throw new RulesException("Type Check",
121 exception
+":"+message
);
127 * ( string -- ) Prints a debug message only if debug output is enabled.
131 static class Debug
extends ROperator
{
132 Debug(){super("debug");}
134 public void execute(DTState state
) throws RulesException
{
135 String msg
= state
.datapop().stringValue();
136 if(state
.testState(DTState
.DEBUG
)){
143 * ( -- ) Turn on the trace flag.
147 static class Traceon
extends ROperator
{
148 Traceon(){super("traceon");}
150 public void execute(DTState state
) throws RulesException
{
151 state
.setState(DTState
.TRACE
);
156 * ( -- ) Turn off the trace flag
160 static class Traceoff
extends ROperator
{
161 Traceoff(){super("traceoff");}
163 public void execute(DTState state
) throws RulesException
{
164 state
.clearState(DTState
.TRACE
);
169 * ( flag -- ) Set the debug state
174 static class SetDebug
extends ROperator
{
175 SetDebug(){super("setdebug");}
177 public void execute(DTState state
) throws RulesException
{
178 boolean flg
= state
.datapop().booleanValue();
180 state
.setState(DTState
.DEBUG
);
182 state
.clearState(DTState
.DEBUG
);
188 * A Noop -- Does nothing.
192 static class Ignore
extends ROperator
{
193 Ignore(){super("ignore"); alias("nop");}
195 public void execute(DTState state
) throws RulesException
{
200 * ( string -- length ) returns the length of the given string
204 static class Stringlength
extends ROperator
{
205 Stringlength(){super("strlength");}
207 public void execute(DTState state
) throws RulesException
{
208 String str
= state
.datapop().stringValue();
209 RInteger len
= RInteger
.getRIntegerValue(str
.length());
215 * ( String -- String ) converts the string to uppercase.
219 static class Touppercase
extends ROperator
{
220 Touppercase(){super("touppercase");}
222 public void execute(DTState state
) throws RulesException
{
223 String str
= state
.datapop().stringValue();
224 String str2
= str
.toUpperCase();
225 state
.datapush(RString
.newRString(str2
));
230 * ( String -- String ) converts the string to lowercase
234 static class Tolowercase
extends ROperator
{
235 Tolowercase(){super("tolowercase");}
237 public void execute(DTState state
) throws RulesException
{
238 String str
= state
.datapop().stringValue();
239 String str2
= str
.toLowerCase();
240 state
.datapush(RString
.newRString(str2
));
245 * ( string -- string ) Trims the string, per trim in Java
249 static class Trim
extends ROperator
{
250 Trim(){super("trim");}
252 public void execute(DTState state
) throws RulesException
{
253 String str
= state
.datapop().stringValue();
254 String str2
= str
.trim();
255 state
.datapush(RString
.newRString(str2
));
260 * (endindex beginindex string -- substring ) Returns the substring
264 static class substring
extends ROperator
{
265 substring(){super("substring");}
267 public void execute(DTState state
) throws RulesException
{
268 String str
= state
.datapop().stringValue();
269 int b
= state
.datapop().intValue();
270 int e
= state
.datapop().intValue();
271 String str2
= str
.substring(b
,e
);
272 state
.datapush(RString
.newRString(str2
));
277 * ( obj1 obj2 -- obj2 obj1 ) swaps the top two elements on the data stack
281 static class Swap
extends ROperator
{
282 Swap(){super("swap"); alias("exch");}
284 public void execute(DTState state
) throws RulesException
{
285 IRObject obj1
= state
.datapop();
286 IRObject obj2
= state
.datapop();
287 state
.datapush(obj1
);
288 state
.datapush(obj2
);
293 * ( obj1 -- obj1 obj2 )
297 static class Dup
extends ROperator
{
300 public void execute(DTState state
) throws RulesException
{
301 IRObject obj1
= state
.datapop();
302 state
.datapush(obj1
);
303 state
.datapush(obj1
);
307 static class Pop
extends ROperator
{
313 public void execute(DTState state
) throws RulesException
{
319 * (obj1 obj2 -- obj1 obj2 obj1 ) copies the element below the top.
323 static class Over
extends ROperator
{
324 Over(){super("over");}
326 public void execute(DTState state
) throws RulesException
{
327 IRObject obj1
= state
.getds(state
.ddepth()-2);
328 state
.datapush(obj1
);
333 * ( entity -- ) push the given entity onto the entity stack
337 static class Entitypush
extends ROperator
{
338 Entitypush(){super("entitypush");}
340 public void execute(DTState state
) throws RulesException
{
341 IREntity e
= state
.datapop().rEntityValue();
342 if(state
.testState(DTState
.TRACE
)){
343 state
.traceInfo("entitypush", "value='"+e
.stringValue()+"' id='"+e
.getID()+"'");
350 * ( -- ) pops the top element from the entity stack and tosses
351 * it into the bit bucket
355 static class Entitypop
extends ROperator
{
356 Entitypop(){super("entitypop");}
358 public void execute(DTState state
) throws RulesException
{
359 if(state
.testState(DTState
.TRACE
)){
360 state
.traceInfo("entitypop","");
367 * Pushes a copy of the top entity on the entity stack on to the
369 * ( index -- element )
373 static class Entityfetch
extends ROperator
{
374 Entityfetch(){super("entityfetch");}
375 public void execute(DTState state
) throws RulesException
{
376 int i
= state
.datapop().intValue();
377 state
.datapush(state
.entityfetch(i
));
382 * Returns the top element from the control stack.
386 static class I
extends ROperator
{
387 I(){super("i"); alias("r@");}
389 public void execute(DTState state
) throws RulesException
{
390 state
.datapush( state
.getcs(state
.cdepth()-1));
395 * Returns the second element from the control stack.
399 static class J
extends ROperator
{
402 public void execute(DTState state
) throws RulesException
{
403 state
.datapush( state
.getcs(state
.cdepth()-2));
408 * Returns the third element from the control stack.
412 static class K
extends ROperator
{
415 public void execute(DTState state
) throws RulesException
{
416 state
.datapush( state
.getcs(state
.cdepth()-3));
421 * ( obj -- ) Pops the top element from the data stack, and pushes
422 * it to the Control stack.
426 static class ToR
extends ROperator
{
429 public void execute(DTState state
) throws RulesException
{
430 state
.cpush(state
.datapop());
435 * ( -- obj ) pops the top element from the control stack, and pushes
436 * it to the data stack.
440 static class FromR
extends ROperator
{
441 FromR(){super("r>");}
443 public void execute(DTState state
) throws RulesException
{
444 state
.datapush(state
.cpop());
450 * Binds the name with the value in the highest entity on the
451 * entity stack which is both writable, and has an entry with
452 * a writiable name that matches.
457 static class Def
extends ROperator
{
460 public void execute(DTState state
) throws RulesException
{
461 IRObject value
= state
.datapop();
462 RName name
= state
.datapop().rNameValue();
463 boolean f
= state
.def(name
, value
, true);
464 if(!f
)throw new RulesException("Undefined",
466 name
+" is undefined");
471 * Looks up the name, and returns the value associated with
472 * the name in the top most entity that defines the name.
473 * Returns RNull if the name isn't found.
477 static class Find
extends ROperator
{
478 Find(){super("find");}
480 public void execute(DTState state
) throws RulesException
{
481 RName name
= state
.datapop().rNameValue();
482 IRObject v
= state
.find(name
);
483 if(v
==null)throw new RulesException("Undefined",
485 name
+" is undefined");
489 * ( obj -- ) Prints the top element of on the data stack to
494 static class Print
extends ROperator
{
495 Print(){super("print"); alias("debug"); }
497 public void execute(DTState state
) throws RulesException
{
498 state
.debug(state
.datapop().toString());
503 * ( obj1 -- obj2 ) Creates a clone of the given object.
507 static class Clone
extends ROperator
{
508 Clone(){super("clone");}
510 public void execute(DTState state
) throws RulesException
{
511 state
.datapush(state
.datapop().clone(state
.getSession()));
517 * Binds the name with the value in the highest entity on the
518 * entity stack which is both writable, and has an entry with
519 * a writiable name that matches.
524 static class Xdef
extends ROperator
{
525 Xdef(){super("xdef");}
527 public void execute(DTState state
) throws RulesException
{
528 RName name
= state
.datapop().rNameValue();
529 IRObject value
= state
.datapop();
530 boolean f
= state
.def(name
, value
, true);
532 if(state
.find(name
)==null){
533 throw new RulesException("Undefined",
535 name
+" is undefined");
537 throw new RulesException("Write Protection",
539 name
+" is Input only, and xdef attempted to write to it");
545 * ( -- ) Prints all the elements on all the stacks non-distructively.
546 * This is purely a debugging aid.
550 static class PStack
extends ROperator
{
551 PStack(){super("pstack");}
553 public void execute(DTState state
) throws RulesException
{
559 * ( RName -- ) Creates an instance of the entity with the given name.
564 static class Createentity
extends ROperator
{
565 Createentity(){super("createentity");}
567 public void execute(DTState state
) throws RulesException
{
568 RName ename
= state
.datapop().rNameValue();
569 IREntity entity
= ((RSession
) state
.getSession()).createEntity(null, ename
);
570 state
.datapush(entity
);
575 * ( Object -- Integer ) Converts to an Integer.
580 static class Cvi
extends ROperator
{
583 public void execute(DTState state
) throws RulesException
{
584 IRObject v
= state
.datapop();
585 IRObject obj
= v
.rIntegerValue();
586 if(state
.testState(DTState
.TRACE
)){
587 if(v
.type()!= IRObject
.iInteger
){
588 state
.traceInfo("cvi", "value='"+v
+"'",obj
.stringValue());
595 * ( Object -- Double ) Converts to an Double.
600 static class Cvr
extends ROperator
{
601 Cvr(){super("cvr"); alias("cvd");}
603 public void execute(DTState state
) throws RulesException
{
604 IRObject v
= state
.datapop();
605 IRObject obj
= v
.rDoubleValue();
606 if(state
.testState(DTState
.TRACE
)){
607 if(v
.type()!= IRObject
.iDouble
){
608 state
.traceInfo("cvr", "value='"+v
+"'",obj
.stringValue());
615 * ( Object -- Boolean ) Converts to an Boolean.
620 static class Cvb
extends ROperator
{
623 public void execute(DTState state
) throws RulesException
{
624 state
.datapush(state
.datapop().rBooleanValue());
628 * ( Object -- Entity ) Converts to an Entity.
633 static class Cve
extends ROperator
{
636 public void execute(DTState state
) throws RulesException
{
637 IRObject v
= state
.datapop();
638 if(v
.type()==IRObject
.iNull
){
641 state
.datapush(v
.rEntityValue());
646 * ( Object -- String ) Converts to a String.
651 static class Cvs
extends ROperator
{
654 public void execute(DTState state
) throws RulesException
{
655 state
.datapush(state
.datapop().rStringValue());
659 * ( Object -- String ) Converts to a Name.
664 static class Cvn
extends ROperator
{
667 public void execute(DTState state
) throws RulesException
{
668 IRObject obj
= state
.datapop();
669 state
.datapush(obj
.rNameValue().getNonExecutable());
673 * ( Object -- Date ) Converts to an Date.
678 static class Cvd
extends ROperator
{
681 public void execute(DTState state
) throws RulesException
{
682 IRObject datevalue
= state
.datapop();
683 state
.datapush(datevalue
.rTimeValue());
688 * ( -- String ) Returns the Decision Table and Action number
693 static class ActionString
extends ROperator
{
694 ActionString(){super("actionstring");}
696 public void execute(DTState state
) throws RulesException
{
697 state
.datapush( RString
.newRString(
698 state
.getCurrentTable().getName().stringValue()+" "+
699 state
.getCurrentTableSection()+" "+
700 (state
.getNumberInSection()+1)));
704 * ( -- String ) Returns the Decision Table and Action number
709 static class GetDescription
extends ROperator
{
710 GetDescription(){super("getdescription");}
712 public void execute(DTState state
) throws RulesException
{
713 String section
= state
.getCurrentTableSection();
714 String description
= "";
715 if(section
.equalsIgnoreCase("action")){
716 RDecisionTable table
= state
.getCurrentTable();
717 description
= table
.getActionsComment()[state
.getNumberInSection()];
718 }else if(section
.equalsIgnoreCase("condition")){
719 RDecisionTable table
= state
.getCurrentTable();
720 description
= table
.getConditionsComment()[state
.getNumberInSection()];
722 state
.datapush( RString
.newRString(description
));
726 * ( regex String -- boolean ) Returns true if the given string is matched
727 * by the given regular expression.
732 static class RegexMatch
extends ROperator
{
733 RegexMatch(){super("regexmatch");}
735 public void execute(DTState state
) throws RulesException
{
736 String string
= state
.datapop().stringValue();
737 String regex
= state
.datapop().stringValue();
738 boolean b
= string
.matches(regex
);
739 state
.datapush( RBoolean
.getRBoolean(b
));