/**
* Copyright 2016 Nabarun Mondal
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.noga.njexl.lang.extension.oop;
import com.noga.njexl.lang.Interpreter;
import com.noga.njexl.lang.Main;
import java.util.regex.Pattern;
/**
* Created by noga on 08/04/15.
*/
public final class ScriptClassBehaviour {
/**
* string representation function name
*/
public static final String STR = "__str__" ;
/**
* object equal function name
*/
public static final String EQ = "__eq__" ;
/**
* hash code function name
*/
public static final String HC = "__hc__" ;
/**
* object compare function name
*/
public static final String CMP = "__cmp__" ;
/**
* This is used to compare nJexl extended types
*/
public interface TypeAware{
/**
* if the object is of type of o
* @param o the other object
* @return true if this isa o type ( derivable from ) else false
*/
boolean isa( Object o);
}
/**
* Used in eventing before/after method call using namespaces
*/
public interface Eventing {
/**
* Method name for before event
*/
String BEFORE = "__before__" ;
/**
* Method name for after event
*/
String AFTER = "__after__" ;
/**
* Thus, only 4 types of waiting pattern are possible
* You should choose wisely
*/
Pattern EVENTS = Pattern.compile("^[@\\$][@\\$].+", Pattern.DOTALL );
/**
* Before event call
* @param event what event occurred
*/
void before(Event event) ;
/**
* After event call
* @param event what event occurred
*/
void after(Event event) ;
/**
* an implementation of the eventing
*/
final class Timer implements Eventing{
public static final Timer TIMER = new Timer();
long t;
@Override
public void after(Event event) {
long ts = System.currentTimeMillis() - t ;
System.out.printf("<<%s%s:%d>>\n", event.pattern, event.method, ts);
}
@Override
public void before(Event event) {
t = System.currentTimeMillis();
}
}
/**
* Event container
*/
final class Event{
/**
* the pattern
*/
public final String pattern;
/**
* the method
*/
public final Object method;
/**
* the arguments to the method
*/
public final Object[] args;
/**
* The return value : will be null for before event
*/
public final Object result;
/**
* The error if any : will be null for before event
*/
public final Throwable error;
/**
* cached copy of the description
*/
public final String description;
/**
* Creates an event object for before call
* @param p what pattern was used
* @param m what method was called
* @param a what argument was passed
*/
public Event(String p, Object m, Object[] a){
this(p,m,a,null,null);
}
/**
* Creates an event object for after call
* @param p what pattern was used
* @param m what method was called
* @param a what argument was passed
* @param r the return value
* @param e the error if any
*/
public Event(String p, Object m, Object[] a, Object r, Throwable e){
pattern = p;
method = m;
args = a;
result = r;
error = e;
description = String.format( "%s | %s | %s | %s | %s" , p,m, Main.strArr(a), result, error );
}
@Override
public String toString(){
return description;
}
}
}
/**
* This lets one execute arbitrary method, given args
*/
public interface Executable {
/**
* Execute a method
* This design avoids GIL
* @param method name of the method
* @param interpreter the interpreter on which to run
* @param args to be passed as argument
* @return result of the method
*/
Object execMethod(String method, Interpreter interpreter, Object[] args) ;
/**
* Gets a property
* @param prop name of the property
* @return the property if exists, null otherwise
* @throws Exception when property is not found
*/
Object get(String prop) throws Exception;
}
/**
* This lets us do arithmetic
*/
public interface Arithmetic{
/**
* name of the negation function
*/
String NEG = "__neg__" ;
/**
* negates the object
* @return new object which is the negation of the object
*/
Object neg() ;
/**
* name of addition function
*/
String ADD = "__add__" ;
/**
* Addition operation
* @param o other object
* @return a new object with this + other
*/
Object add(Object o) ;
String SUB = "__sub__" ;
/**
* Subtraction operation
* @param o other object
* @return a new object with this - other
*/
Object sub(Object o) ;
/**
* name of multiplication function
*/
String MUL = "__mul__" ;
/**
* Multiplication operation
* @param o other object
* @return a new object with this X other
*/
Object mul(Object o) ;
/**
* name of division function
*/
String DIV = "__div__" ;
/**
* Division operation
* @param o other object
* @return a new object with this divide other
*/
Object div(Object o) ;
/**
* name of exponentiation function
*/
String EXP = "__exp__" ;
/**
* Exponentiation operation
* @param o other object
* @return a new object with this exponent the other
*/
Object exp(Object o) ;
}
public interface Logic{
/**
* name of complementing function
*/
String COMPLEMENT = "__complement__" ;
/**
* complement operation
* @return a new object which is complement of this
*/
Object complement() ;
/**
* name of OR function
*/
String OR = "__or__" ;
/**
* OR operation
* @param o other object
* @return a new object with this OR other
*/
Object or(Object o) ;
/**
* name of AND function
*/
String AND = "__and__" ;
/**
* AND operation
* @param o other object
* @return a new object with this AND other
*/
Object and(Object o) ;
/**
* name of XOR function
*/
String XOR = "__xor__" ;
/**
* XOR operation
* @param o other object
* @return a new object with this XOR other
*/
Object xor(Object o) ;
}
}