Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/development' into development
Browse files Browse the repository at this point in the history
  • Loading branch information
mctaverna committed Sep 11, 2023
2 parents c215334 + 7cff835 commit 2ccb2dc
Show file tree
Hide file tree
Showing 25 changed files with 336 additions and 182 deletions.
6 changes: 3 additions & 3 deletions runtime/src/main/java/ortus/boxlang/runtime/BoxRuntime.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,12 @@
import org.slf4j.LoggerFactory;

import ortus.boxlang.runtime.context.IBoxContext;
import ortus.boxlang.runtime.context.TemplateBoxContext;
import ortus.boxlang.runtime.context.ScriptingBoxContext;
import ortus.boxlang.runtime.dynamic.BaseTemplate;
import ortus.boxlang.runtime.logging.LoggingConfigurator;
import ortus.boxlang.runtime.scopes.Key;
import ortus.boxlang.runtime.services.InterceptorService;
import ortus.boxlang.runtime.types.Struct;
import ortus.boxlang.runtime.scopes.Key;
import ortus.boxlang.runtime.util.Timer;

/**
Expand Down Expand Up @@ -242,7 +242,7 @@ public void executeTemplate( BaseTemplate template ) throws Throwable {
instance.logger.atDebug().log( "Executing template [{}]", template.path );

// Build out the execution context for this execution and bind it to the incoming template
IBoxContext context = new TemplateBoxContext( template );
IBoxContext context = new ScriptingBoxContext();

// Announcements
Struct data = new Struct();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@
package ortus.boxlang.runtime.context;

import java.util.Map;
import java.util.Stack;

import ortus.boxlang.runtime.dynamic.BaseTemplate;
import ortus.boxlang.runtime.scopes.IScope;
import ortus.boxlang.runtime.scopes.Key;
import ortus.boxlang.runtime.types.Function;
Expand All @@ -41,7 +43,9 @@ public class BaseBoxContext implements IBoxContext {
* Private Properties
* --------------------------------------------------------------------------
*/
protected IBoxContext parent;
protected IBoxContext parent;

protected Stack<BaseTemplate> templates = new Stack<BaseTemplate>();

/**
* Creates a new execution context with a bounded execution template and parent context
Expand All @@ -68,6 +72,56 @@ public BaseBoxContext() {
* --------------------------------------------------------------------------
*/

/**
* Push a template to the stack
*
* @param templatePath The template that this execution context is bound to
*
* @return IBoxContext
*/
public IBoxContext pushTemplate( BaseTemplate template ) {
this.templates.push( template );
return this;
}

/**
* Pop a template from the stack
*
* @return The template that this execution context is bound to
*/
public BaseTemplate popTemplate() {
return this.templates.pop();
}

/**
* Has the execution context been bound to a template?
*
* @return True if bound, else false
*/
public boolean hasTemplates() {
return !this.templates.empty();
}

/**
* Finds the closest template
*
* @return The template instance if found, null if this code is not called from a template
*/
public BaseTemplate findClosestTemplate() {
// If this context has templates, grab the first
if ( hasTemplates() ) {
return this.templates.peek();
}

// Otherwise, if we have a parent, as them
if ( hasParent() ) {
return getParent().findClosestTemplate();
}

// There is none to be found!
return null;
}

/**
* Returns the parent box context. Null if none.
*
Expand All @@ -92,18 +146,20 @@ public Boolean hasParent() {
* @return Return value of the function call
*/
public Object invokeFunction( Key name, Object[] positionalArguments ) {
Function function = getFunction( name );
FunctionBoxContext fContext = new FunctionBoxContext( this, function.createArgumentsScope( positionalArguments ) );
Function function = findFunction( name );
FunctionBoxContext fContext = new FunctionBoxContext( this, function,
function.createArgumentsScope( positionalArguments ) );
return function.invoke( fContext );
}

public Object invokeFunction( Key name, Map<Key, Object> namedArguments ) {
Function function = getFunction( name );
FunctionBoxContext fContext = new FunctionBoxContext( this, function.createArgumentsScope( namedArguments ) );
Function function = findFunction( name );
FunctionBoxContext fContext = new FunctionBoxContext( this, function,
function.createArgumentsScope( namedArguments ) );
return function.invoke( fContext );
}

public Function getFunction( Key name ) {
private Function findFunction( Key name ) {
// TODO: Check for registered BIF

ScopeSearchResult result = scopeFindNearby( name, null );
Expand Down Expand Up @@ -139,4 +195,21 @@ public void regsiterUDF( UDF udf ) {
throw new UnsupportedOperationException( "This context cannot register a function" );
}

/**
* Finds the closest function call
*
* @return The Function instance if found, null if this code is not called from a function
*/
public Function findClosestFunction() {
IBoxContext context = this;
// Climb the context tree until we find a function
while ( context != null ) {
if ( context instanceof FunctionBoxContext ) {
return ( ( FunctionBoxContext ) context ).getFunction();
}
context = context.getParent();
}
return null;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import ortus.boxlang.runtime.scopes.IScope;
import ortus.boxlang.runtime.scopes.Key;
import ortus.boxlang.runtime.scopes.LocalScope;
import ortus.boxlang.runtime.types.Function;
import ortus.boxlang.runtime.types.Struct;
import ortus.boxlang.runtime.types.exceptions.KeyNotFoundException;
import ortus.boxlang.runtime.types.exceptions.ScopeNotFoundException;
Expand All @@ -13,24 +14,43 @@ public class FunctionBoxContext extends BaseBoxContext {
/**
* The arguments scope
*/
private IScope argumentsScope;
private IScope argumentsScope;

/**
* The local scope
*/
private IScope localScope;
private IScope localScope;

public FunctionBoxContext( IBoxContext parent ) {
this( parent, new ArgumentsScope() );
/**
* The Function being invoked with this context
*/
private Function function;

/**
* Creates a new execution context with a bounded function instance and parent context
*
* @param parent The parent context
* @param function The function being invoked with this context
*/
public FunctionBoxContext( IBoxContext parent, Function function ) {
this( parent, function, new ArgumentsScope() );
}

public FunctionBoxContext( IBoxContext parent, ArgumentsScope argumentsScope ) {
public FunctionBoxContext( IBoxContext parent, Function function, ArgumentsScope argumentsScope ) {
super( parent );
if ( parent == null ) {
throw new IllegalArgumentException( "Parent context cannot be null for FunctionBoxContext" );
}
this.localScope = new LocalScope();
this.argumentsScope = argumentsScope;
this.function = function;
}

/**
* Returns the function being invoked with this context
*/
public Function getFunction() {
return function;
}

public ScopeSearchResult scopeFindNearby( Key key, IScope defaultScope ) {
Expand Down Expand Up @@ -118,4 +138,13 @@ public IScope getScopeNearby( Key name ) throws ScopeNotFoundException {

}

/**
* Finds the closest function call
*
* @return The Function instance
*/
public Function findClosestFunction() {
return function;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,10 @@

import java.util.Map;

import ortus.boxlang.runtime.dynamic.BaseTemplate;
import ortus.boxlang.runtime.scopes.IScope;
import ortus.boxlang.runtime.scopes.Key;
import ortus.boxlang.runtime.types.Function;
import ortus.boxlang.runtime.types.UDF;
import ortus.boxlang.runtime.types.exceptions.KeyNotFoundException;
import ortus.boxlang.runtime.types.exceptions.ScopeNotFoundException;
Expand Down Expand Up @@ -115,6 +117,43 @@ public interface IBoxContext {
*/
public IBoxContext getParent();

/**
* Finds the closest function call
*
* @return The Function instance
*/
public Function findClosestFunction();

/**
* Push a template to the stack
*
* @param templatePath The template that this execution context is bound to
*
* @return IBoxContext
*/
public IBoxContext pushTemplate( BaseTemplate template );

/**
* Pop a template from the stack
*
* @return The template that this execution context is bound to
*/
public BaseTemplate popTemplate();

/**
* Has the execution context been bound to a template?
*
* @return True if bound, else false
*/
public boolean hasTemplates();

/**
* Finds the closest template
*
* @return The template instance if found, null if this code is not called from a template
*/
public BaseTemplate findClosestTemplate();

/**
* Represents the results of a successful scope hunting expedition.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
*/
package ortus.boxlang.runtime.context;

import ortus.boxlang.runtime.dynamic.BaseTemplate;
import ortus.boxlang.runtime.scopes.IScope;
import ortus.boxlang.runtime.scopes.Key;
import ortus.boxlang.runtime.scopes.VariablesScope;
Expand All @@ -29,29 +28,18 @@
/**
* This context represents the context of a template execution in BoxLang
*/
public class TemplateBoxContext extends BaseBoxContext {

/**
* --------------------------------------------------------------------------
* Public Properties
* --------------------------------------------------------------------------
*/
public class ScriptingBoxContext extends BaseBoxContext {

/**
* --------------------------------------------------------------------------
* Private Properties
* --------------------------------------------------------------------------
*/

/**
* The template that this execution context is bound to
*/
private BaseTemplate template = null;

/**
* The variables scope
*/
protected IScope variablesScope = new VariablesScope();
protected IScope variablesScope = new VariablesScope();

/**
* --------------------------------------------------------------------------
Expand All @@ -65,25 +53,15 @@ public class TemplateBoxContext extends BaseBoxContext {
* @param template The template that this execution context is bound to
* @param parent The parent context
*/
public TemplateBoxContext( BaseTemplate template, IBoxContext parent ) {
public ScriptingBoxContext( IBoxContext parent ) {
super( parent );
this.template = template;
}

/**
* Creates a new execution context with a bounded execution template
*
* @param templatePath The template that this execution context is bound to
*/
public TemplateBoxContext( BaseTemplate template ) {
this( template, null );
}

/**
* Creates a new execution context
*/
public TemplateBoxContext() {
this( null, null );
public ScriptingBoxContext() {
this( null );
}

/**
Expand All @@ -92,36 +70,6 @@ public TemplateBoxContext() {
* --------------------------------------------------------------------------
*/

/**
* Set the template path of execution
*
* @param templatePath The template that this execution context is bound to
*
* @return IBoxContext
*/
public IBoxContext setTemplate( BaseTemplate template ) {
this.template = template;
return this;
}

/**
* Get the template path of execution
*
* @return The template that this execution context is bound to
*/
public BaseTemplate getTemplate() {
return this.template;
}

/**
* Has the execution context been bound to a template?
*
* @return True if bound, else false
*/
public boolean hasTemplate() {
return this.template != null;
}

/**
* Try to get the requested key from the unscoped scope
* Meaning it needs to search scopes in order according to it's context.
Expand Down Expand Up @@ -176,7 +124,7 @@ public ScopeSearchResult scopeFindNearby( Key key, IScope defaultScope ) {
*/
public ScopeSearchResult scopeFind( Key key, IScope defaultScope ) {

// The templateBoxContext has no "global" scopes, so just defer to parent
// The ScriptingBoxContext has no "global" scopes, so just defer to parent

if ( parent != null ) {
return parent.scopeFind( key, defaultScope );
Expand All @@ -200,7 +148,7 @@ public ScopeSearchResult scopeFind( Key key, IScope defaultScope ) {
*/
public IScope getScope( Key name ) throws ScopeNotFoundException {

// The templateBoxContext has no "global" scopes, so just defer to parent
// The ScriptingBoxContext has no "global" scopes, so just defer to parent
if ( parent != null ) {
return parent.getScope( name );
}
Expand Down
Loading

0 comments on commit 2ccb2dc

Please sign in to comment.