/// <summary> /// Creates new instance of the type. /// </summary> /// <returns></returns> public object VisitNew(NewExpr expr) { object[] constructorArgs = null; var paramListExprs = expr.ParamListExpressions; if (paramListExprs != null && paramListExprs.Count > 0) { expr.ParamList = new List <object>(); ParamHelper.ResolveNonNamedParameters(paramListExprs, expr.ParamList, this); constructorArgs = expr.ParamList.ToArray(); } // CASE 1: Built in basic system types ( string, date, time, etc ) if (LTypesLookup.IsBasicTypeShortName(expr.TypeName)) { // TODO: Move this check to Semacts later var langType = LTypesLookup.GetLType(expr.TypeName); var methods = this.Ctx.Methods.Get(langType); var canCreate = methods.CanCreateFromArgs(constructorArgs); if (!canCreate) { throw ExceptionHelper.BuildRunTimeException(expr, "Can not create " + expr.TypeName + " from parameters"); } // Allow built in type methods to create it. var result = methods.CreateFromArgs(constructorArgs); return(result); } // CASE 2: Custom types e.g. custom classes. var hostLangArgs = LangTypeHelper.ConvertToArrayOfHostLangValues(constructorArgs); var instance = this.Ctx.Types.Create(expr.TypeName, hostLangArgs); var obj = LangTypeHelper.ConvertToLangClass(instance); return(obj); }
/// <summary> /// Execute /// </summary> public object VisitTryCatch(TryCatchExpr expr) { var tryScopePopped = false; var catchScopePopped = false; try { this.Ctx.Memory.Push(); LangHelper.Evaluate(expr.Statements, expr, this); this.Ctx.Memory.Pop(); tryScopePopped = true; } // Force the langlimit excpetion to propegate // do not allow to flow through to the catch all "Exception ex". catch (LangLimitException) { throw; } catch (LangFailException) { throw; } catch (Exception ex) { this.Ctx.Limits.CheckExceptions(expr); // Pop the try scope. if (!tryScopePopped) { this.Ctx.Memory.Pop(); } // Push the scope in the catch block this.Ctx.Memory.Push(); var lException = LangTypeHelper.ConvertToLangClass(LError.FromException(ex)); this.Ctx.Memory.SetValue(expr.ErrorName, lException); // Run statements in catch block. if (expr.Catch != null && expr.Catch.Statements.Count > 0) { LangHelper.Evaluate(expr.Catch.Statements, expr.Catch, this); } // Pop the catch scope. this.Ctx.Memory.Pop(); catchScopePopped = true; } finally { // Pop the catch scope in case there was an error. if (!catchScopePopped) { this.Ctx.Memory.Remove(expr.ErrorName); } } return(LObjects.Null); }
/// <summary> /// Execute each expression. /// </summary> /// <returns></returns> public object VisitForEach(ForEachExpr expr) { expr.DoContinueRunning = true; expr.DoBreakLoop = false; expr.DoContinueLoop = false; // for(user in users) // Push scope for var name var source = expr.SourceExpr.Evaluate(this) as LObject; // Check : 1. null object? if (source == LObjects.Null) { return(LObjects.Null); } IEnumerator enumerator = null; if (source.Type == LTypes.Array) { enumerator = ((IList)source.GetValue()).GetEnumerator(); } else if (source.Type == LTypes.Map) { enumerator = ((IDictionary)source.GetValue()).GetEnumerator(); } else if (source.Type == LTypes.Table) { enumerator = ((IList)source.GetValue()).GetEnumerator(); } expr.DoContinueRunning = enumerator.MoveNext(); while (expr.DoContinueRunning) { // Set the next value of "x" in for(x in y). var current = enumerator.Current is LObject ? enumerator.Current : LangTypeHelper.ConvertToLangClass(enumerator.Current); this.Ctx.Memory.SetValue(expr.VarName, current); if (expr.Statements != null && expr.Statements.Count > 0) { foreach (var stmt in expr.Statements) { stmt.Evaluate(this); this.Ctx.Limits.CheckLoop(expr); // If Break statment executed. if (expr.DoBreakLoop) { expr.DoContinueRunning = false; break; } // Continue statement. else if (expr.DoContinueLoop) { break; } } } else { break; } // Break loop here. if (expr.DoContinueRunning == false) { break; } // Increment. expr.DoContinueRunning = enumerator.MoveNext(); } return(LObjects.Null); }