Skip to content

Commit

Permalink
docs, cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
fglock committed Oct 18, 2024
1 parent ac1a2b8 commit aa3ce8f
Show file tree
Hide file tree
Showing 7 changed files with 583 additions and 109 deletions.
102 changes: 80 additions & 22 deletions src/main/java/org/perlonjava/runtime/RuntimeCode.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,43 +14,73 @@
import java.util.HashMap;
import java.util.List;

/**
* The RuntimeCode class represents a compiled code object in the runtime environment.
* It provides functionality to compile, store, and execute Perl subroutines and eval strings.
*/
public class RuntimeCode implements RuntimeScalarReference {

// Temporary storage for anonymous subroutines and eval string compiler context
public static HashMap<String, Class<?>> anonSubs = new HashMap<>(); // temp storage for makeCodeObject()
public static HashMap<String, EmitterContext> evalContext = new HashMap<>(); // storage for eval string compiler context

// Method object representing the compiled subroutine
public Method methodObject;
public Object codeObject; // apply() needs this
// Code object instance used during execution
public Object codeObject;
// Prototype of the subroutine
public String prototype;
// Attributes associated with the subroutine
public List<String> attributes = new ArrayList<>();

/**
* Constructs a RuntimeCode instance with the specified prototype and attributes.
*
* @param prototype the prototype of the subroutine
* @param attributes the attributes associated with the subroutine
*/
public RuntimeCode(String prototype, List<String> attributes) {
this.prototype = prototype;
this.attributes = attributes;
}

/**
* Constructs a RuntimeCode instance with the specified method object and code object.
*
* @param methodObject the method object representing the compiled subroutine
* @param codeObject the code object instance used during execution
*/
public RuntimeCode(Method methodObject, Object codeObject) {
this.methodObject = methodObject;
this.codeObject = codeObject;
}

/**
* Constructs a RuntimeCode instance with the specified method object, code object, and prototype.
*
* @param methodObject the method object representing the compiled subroutine
* @param codeObject the code object instance used during execution
* @param prototype the prototype of the subroutine
*/
public RuntimeCode(Method methodObject, Object codeObject, String prototype) {
this.methodObject = methodObject;
this.codeObject = codeObject;
this.prototype = prototype;
}

// Method to compile the text of eval string into a Class that
// represents an anonymous subroutine.
//
// After the Class returns to the caller, an instance of the Class
// will be populated with closure variables, and then
// makeCodeObject() will be called to transform the Class instance
// into a Perl CODE object
//
/**
* Compiles the text of an eval string into a Class that represents an anonymous subroutine.
* After the Class is returned to the caller, an instance of the Class will be populated
* with closure variables, and then makeCodeObject() will be called to transform the Class
* instance into a Perl CODE object.
*
* @param code the RuntimeScalar containing the eval string
* @param evalTag the tag used to retrieve the eval context
* @return the compiled Class representing the anonymous subroutine
* @throws Exception if an error occurs during compilation
*/
public static Class<?> evalStringHelper(RuntimeScalar code, String evalTag) throws Exception {

// retrieve the eval context that was saved at program compile-time
// Retrieve the eval context that was saved at program compile-time
EmitterContext ctx = RuntimeCode.evalContext.get(evalTag);
ScopedSymbolTable symbolTable = ctx.symbolTable.clone();

Expand Down Expand Up @@ -87,7 +117,7 @@ public static Class<?> evalStringHelper(RuntimeScalar code, String evalTag) thro
true // use try-catch
);
} catch (Exception e) {
// compilation error in eval-string
// Compilation error in eval-string

// Set the global error variable "$@" using GlobalContext.setGlobalVariable(key, value)
GlobalContext.getGlobalVariable("main::@").set(e.toString());
Expand All @@ -105,12 +135,15 @@ public static Class<?> evalStringHelper(RuntimeScalar code, String evalTag) thro
return generatedClass;
}

// Factory method to create a CODE object (anonymous subroutine)
//
// This is called right after a new Class is compiled.
//
// codeObject is an instance of the new Class, with the closure variables in place.
//
/**
* Factory method to create a CODE object (anonymous subroutine).
* This is called right after a new Class is compiled.
* The codeObject is an instance of the new Class, with the closure variables in place.
*
* @param codeObject the instance of the compiled Class
* @return a RuntimeScalar representing the CODE object
* @throws Exception if an error occurs during method retrieval
*/
public static RuntimeScalar makeCodeObject(Object codeObject) throws Exception {
// Retrieve the class of the provided code object
Class<?> clazz = codeObject.getClass();
Expand All @@ -125,30 +158,55 @@ public static RuntimeScalar makeCodeObject(Object codeObject) throws Exception {
return new RuntimeScalar(new RuntimeCode(mm, codeObject));
}

// Method to apply (execute) a subroutine reference
/**
* Method to apply (execute) a subroutine reference.
* Invokes the method associated with the code object, passing the RuntimeArray and RuntimeContextType as arguments.
*
* @param a the RuntimeArray containing the arguments for the subroutine
* @param callContext the context in which the subroutine is called
* @return the result of the subroutine execution as a RuntimeList
*/
public RuntimeList apply(RuntimeArray a, int callContext) {
// Invoke the method associated with the code object, passing the RuntimeArray and RuntimeContextType as arguments
// This executes the subroutine and returns the result, which is expected to be a RuntimeList
try {
return (RuntimeList) this.methodObject.invoke(this.codeObject, a, callContext);
} catch (Exception e) {
throw new RuntimeException(e);
}
}

/**
* Returns a string representation of the CODE reference.
*
* @return a string representing the CODE reference
*/
public String toStringRef() {
return "CODE(" + this.hashCode() + ")";
}

/**
* Returns an integer representation of the CODE reference.
*
* @return an integer representing the CODE reference
*/
public int getIntRef() {
return this.hashCode();
}

/**
* Returns a double representation of the CODE reference.
*
* @return a double representing the CODE reference
*/
public double getDoubleRef() {
return this.hashCode();
}

/**
* Returns a boolean representation of the CODE reference.
*
* @return true, indicating the presence of the CODE reference
*/
public boolean getBooleanRef() {
return true;
}
}
}
97 changes: 63 additions & 34 deletions src/main/java/org/perlonjava/runtime/RuntimeDataProvider.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,126 +3,155 @@
import java.util.Iterator;

/**
* RuntimeDataProvider interface defines methods for obtaining different types of runtime data.
* Classes implementing this interface should provide implementations for these methods.
* The RuntimeDataProvider interface defines methods for obtaining different types of runtime data.
* Classes implementing this interface should provide implementations for these methods to interact
* with various runtime data structures like arrays, lists, and scalars.
*/
public interface RuntimeDataProvider {

/**
* Retrieves a RuntimeArray of aliases instance.
* This is used to build the subroutine call parameter list `@_`
* This is used to build the subroutine call parameter list `@_`.
*
* @return a RuntimeArray object.
* @return a RuntimeArray object representing the array of aliases
*/
RuntimeArray getArrayOfAlias();

/**
* Push the data into a RuntimeArray of aliases instance.
* This provides data to getArrayOfAlias() and to iterator()
* Pushes the data into a RuntimeArray of aliases instance.
* This provides data to getArrayOfAlias() and to iterator().
*
* @return a RuntimeArray object.
* @param arr the RuntimeArray to be set as the array of aliases
* @return the updated RuntimeArray object
*/
RuntimeArray setArrayOfAlias(RuntimeArray arr);

/**
* Retrieves a RuntimeList instance.
* This is always called at the end of a subroutine to transform the return value to RuntimeList
* This is always called at the end of a subroutine to transform the return value to RuntimeList.
*
* @return a RuntimeList object.
* @return a RuntimeList object representing the list of elements
*/
RuntimeList getList();

/**
* Retrieves a RuntimeScalar instance.
*
* @return a RuntimeScalar object.
* @return a RuntimeScalar object representing the scalar value
*/
RuntimeScalar scalar();

/**
* Retrieves the boolean value of the object.
*
* @return a boolean representing the truthiness of the object
*/
boolean getBoolean();

/**
* Retrieves the defined boolean value of the object.
*
* @return a boolean indicating whether the object is defined
*/
boolean getDefinedBoolean();

/**
* Create a reference
* Creates a reference to the current object.
*
* @return a RuntimeScalar representing the reference
*/
RuntimeScalar createReference();

/**
* Add itself to a RuntimeArray.
* Adds itself to a RuntimeArray.
*
* @param array The RuntimeArray object
* @param array the RuntimeArray object to which this entity will be added
*/
void addToArray(RuntimeArray array);

/**
* Add itself to a RuntimeList.
* Adds itself to a RuntimeList.
*
* @param list The RuntimeList object
* @param list the RuntimeList object to which this entity will be added
*/
void addToList(RuntimeList list);

/**
* Count the number of RuntimeScalar elements.
* Counts the number of RuntimeScalar elements.
*
* @return the number of elements as an integer
*/
int countElements();

// Get the total number of elements in all elements of the list as a RuntimeScalar
/**
* Gets the total number of elements in all elements of the list as a RuntimeScalar.
*
* @return a RuntimeScalar representing the count of elements
*/
RuntimeScalar count();

/**
* Add itself to a RuntimeScalar.
* Adds itself to a RuntimeScalar.
*
* @param scalar The RuntimeScalar object
* @return scalar
* @param scalar the RuntimeScalar object to which this entity will be added
* @return the updated RuntimeScalar object
*/
RuntimeScalar addToScalar(RuntimeScalar scalar);

/**
* Set itself to a RuntimeList.
* Sets itself from a RuntimeList.
*
* @param list The RuntimeList object
* @return list
* @param list the RuntimeList object from which this entity will be set
* @return the updated RuntimeArray object
*/
RuntimeArray setFromList(RuntimeList list);

/**
* Retrives the result of keys() as a RuntimeArray instance.
* Retrieves the result of keys() as a RuntimeArray instance.
*
* @return a RuntimeList object.
* @return a RuntimeArray object representing the keys
*/
RuntimeArray keys();

/**
* Retrives the result of values() as a RuntimeArray instance.
* Retrieves the result of values() as a RuntimeArray instance.
*
* @return a RuntimeArray object.
* @return a RuntimeArray object representing the values
*/
RuntimeArray values();

/**
* Retrives the result of each() as a RuntimeList instance.
* Retrieves the result of each() as a RuntimeList instance.
*
* @return a RuntimeList object.
* @return a RuntimeList object representing the key-value pairs
*/
RuntimeList each();

/**
* Performs the chop operation on the object.
*
* @return a RuntimeScalar representing the result of the chop operation
*/
RuntimeScalar chop();

/**
* Performs the chomp operation on the object.
*
* @return a RuntimeScalar representing the result of the chomp operation
*/
RuntimeScalar chomp();

/**
* Method to return an iterator.
* Returns an iterator over the elements of type RuntimeScalar.
*
* @return a Iterator<Runtime>
* @return an Iterator<RuntimeScalar> for iterating over the elements
*/
Iterator<RuntimeScalar> iterator();

/**
* undefine the elements of the object
* Undefines the elements of the object.
*
* @return the object.
* @return the object after undefining its elements
*/
RuntimeDataProvider undefine();
}

Loading

0 comments on commit aa3ce8f

Please sign in to comment.