/// <summary> /// Set the value of the specified variable currently in memory based on its unique ID. /// </summary> /// <param name="variableRef">The reference to the variable to set.</param> /// <param name="value">The value to give to the variable</param> internal void SetVariable(VariableReferenceExpression variableRef, object value) { var variable = GetVariable(variableRef.VariableDeclarationID, variableRef.Name.Identifier, true); if (IsAborted) { return; } var valueInfo = ValueInfo.GetValueInfo(value); if (!valueInfo.IsNull) { if (variable.IsArray && !valueInfo.IsArray) { BaZicInterpreter.ChangeState(this, new NotAssignableException(L.BaZic.Runtime.Interpreters.Interpreter.FormattedArrayExpected(variableRef.Name)), variableRef); return; } else if (!variable.IsArray && valueInfo.IsArray) { BaZicInterpreter.ChangeState(this, new NotAssignableException(L.BaZic.Runtime.Interpreters.Interpreter.FormattedNotArrayExpected(variableRef.Name)), variableRef); return; } } variable.SetValue(value, valueInfo); if (BaZicInterpreter.Verbose) { VerboseLog(L.BaZic.Runtime.Interpreters.Interpreter.FormattedVariableSetted(variable.Name, variable)); } }
public void ValueInfoPrimitive7() { var info = ValueInfo.GetValueInfo(new int[1]); Assert.IsFalse(info.IsNull); Assert.IsTrue(info.IsArray); Assert.IsTrue(info.IsPrimitive); Assert.AreEqual(1, info.Length); Assert.AreEqual(typeof(int[]), info.Type); }
public void ValueInfoPrimitive6() { var info = ValueInfo.GetValueInfo(new Exception("hello")); Assert.IsFalse(info.IsNull); Assert.IsFalse(info.IsArray); Assert.IsFalse(info.IsPrimitive); Assert.AreEqual(0, info.Length); Assert.AreEqual(typeof(Exception), info.Type); }
public void ValueInfoPrimitive4() { var info = ValueInfo.GetValueInfo('c'); Assert.IsFalse(info.IsNull); Assert.IsFalse(info.IsArray); Assert.IsTrue(info.IsPrimitive); Assert.AreEqual(0, info.Length); Assert.AreEqual(typeof(char), info.Type); }
public void ValueInfoPrimitive5() { var info = ValueInfo.GetValueInfo("Hello"); Assert.IsFalse(info.IsNull); Assert.IsFalse(info.IsArray); Assert.IsTrue(info.IsPrimitive); Assert.AreEqual(5, info.Length); Assert.AreEqual(typeof(string), info.Type); }
public void ValueInfoNull() { var info = ValueInfo.GetValueInfo(null); Assert.IsTrue(info.IsNull); Assert.IsFalse(info.IsArray); Assert.IsFalse(info.IsPrimitive); Assert.AreEqual(0, info.Length); Assert.IsNull(info.Type); }
public void ValueInfoPrimitive2() { var info = ValueInfo.GetValueInfo(1.234); Assert.IsFalse(info.IsNull); Assert.IsFalse(info.IsArray); Assert.IsTrue(info.IsPrimitive); Assert.AreEqual(0, info.Length); Assert.AreEqual(typeof(double), info.Type); }
public void ValueInfoArray1() { var info = ValueInfo.GetValueInfo(new object[] { 1, 2, "hello" }); Assert.IsFalse(info.IsNull); Assert.IsTrue(info.IsArray); Assert.IsFalse(info.IsPrimitive); Assert.AreEqual(3, info.Length); Assert.AreEqual(typeof(object[]), info.Type); }
public void ValueInfoArray4() { var info = ValueInfo.GetValueInfo(new List <string> { "1", "2", "hello" }); Assert.IsFalse(info.IsNull); Assert.IsTrue(info.IsArray); Assert.IsFalse(info.IsPrimitive); Assert.AreEqual(3, info.Length); Assert.AreEqual(typeof(List <string>), info.Type); }
public void ValueInfoArray3() { var info = ValueInfo.GetValueInfo(new Exception[3] { null, null, null }); Assert.IsFalse(info.IsNull); Assert.IsTrue(info.IsArray); Assert.IsFalse(info.IsPrimitive); Assert.AreEqual(3, info.Length); Assert.AreEqual(typeof(Exception[]), info.Type); }
public void ValueInfoArray2() { var info = ValueInfo.GetValueInfo(new int[3] { 1, 2, 3 }); Assert.IsFalse(info.IsNull); Assert.IsTrue(info.IsArray); Assert.IsTrue(info.IsPrimitive); Assert.AreEqual(3, info.Length); Assert.AreEqual(typeof(int[]), info.Type); }
/// <summary> /// Creates a new variable in memory. /// </summary> /// <param name="variableDeclaration">The variable declaration to use.</param> /// <param name="searchInParents">Defines whether finding a variable can be performed in the parent interpreters.</param> internal void AddVariable(VariableDeclaration variableDeclaration, bool searchInParents = true) { var existingVariable = GetVariable(variableDeclaration.Id, variableDeclaration.Name.Identifier, false, searchInParents); if (existingVariable != null) { if (!BaZicInterpreter.ProgramIsOptimized) { BaZicInterpreter.ChangeState(this, new InternalException(L.BaZic.Runtime.Interpreters.Interpreter.FormattedDuplicatedVariableId(variableDeclaration.Id)), variableDeclaration); return; } else { var variableRef = new VariableReferenceExpression(existingVariable.Name) { Line = variableDeclaration.Line, Column = variableDeclaration.Column, StartOffset = variableDeclaration.StartOffset, NodeLength = variableDeclaration.NodeLength, VariableDeclarationID = existingVariable.Id }; SetVariable(variableRef, RunExpression(variableDeclaration.DefaultValue)); return; } } if (IsAborted) { return; } var defaultValue = RunExpression(variableDeclaration.DefaultValue); var defaultValueInfo = ValueInfo.GetValueInfo(defaultValue); var variable = new Variable(variableDeclaration); AddVariable(variableDeclaration, variable, defaultValue, defaultValueInfo, true); }
/// <summary> /// Creates a new control accessor in memory. /// </summary> /// <param name="controlAccessorDeclaration">The control accessor declaration to use.</param> internal void AddVariable(ControlAccessorDeclaration controlAccessorDeclaration) { if (GetType() != typeof(ProgramInterpreter)) { BaZicInterpreter.ChangeState(this, new IncoherentStatementException(L.BaZic.Runtime.Interpreters.Interpreter.ForbiddenBinding), controlAccessorDeclaration); return; } var existingVariable = GetVariable(controlAccessorDeclaration.Id, controlAccessorDeclaration.Variable.Name.Identifier, false, true); if (existingVariable != null) { BaZicInterpreter.ChangeState(this, new InternalException(L.BaZic.Runtime.Interpreters.Interpreter.FormattedDuplicatedVariableId(controlAccessorDeclaration.Id)), controlAccessorDeclaration); return; } var defaultValue = RunExpression(controlAccessorDeclaration.Variable.DefaultValue); var defaultValueInfo = ValueInfo.GetValueInfo(defaultValue); if (IsAborted) { return; } var targetControl = ((ProgramInterpreter)this).UserInterface.FindName(controlAccessorDeclaration.ControlName); if (targetControl == null) { BaZicInterpreter.ChangeState(this, new UiException(L.BaZic.Runtime.Interpreters.Interpreter.FormattedUiControlNotFound(controlAccessorDeclaration.ControlName))); return; } var binding = new ControlAccessor(controlAccessorDeclaration, targetControl, BaZicInterpreter); AddVariable(controlAccessorDeclaration.Variable, binding, defaultValue, defaultValueInfo, false); }
/// <inheritdoc/> internal override void Run() { var methodInterpreter = ParentInterpreter.GetParentMethodInterpreter(); if (ParentInterpreter.IsAborted) { return; } var returnValue = ParentInterpreter.RunExpression(Statement.Expression); if (ParentInterpreter.IsAborted) { return; } methodInterpreter.ReturnedValue = returnValue; ParentInterpreter.State.ExitMethod = true; if (BaZicInterpreter.Verbose && !ParentInterpreter.IsAborted) { var valueString = methodInterpreter.ReturnedValue == null ? L.BaZic.Runtime.Debugger.ValueInfo.Null : $"{returnValue} ({ValueInfo.GetValueInfo(returnValue)})"; ParentInterpreter.VerboseLog(L.BaZic.Runtime.Interpreters.Statements.ReturnInterpreter.FormattedReturn(valueString)); } }
private void RunSync(IReadOnlyList <object> argumentValues) { // Defines arguments. for (var i = 0; i < _methodDeclaration.Arguments.Count; i++) { var argumentDeclaration = _methodDeclaration.Arguments[i]; var variableDeclaration = new VariableDeclaration(argumentDeclaration.Name.Identifier, argumentDeclaration.IsArray) { Id = argumentDeclaration.Id, Line = argumentDeclaration.Line, Column = argumentDeclaration.Column, StartOffset = argumentDeclaration.StartOffset, NodeLength = argumentDeclaration.NodeLength }; var variableRef = new VariableReferenceExpression(variableDeclaration) { VariableDeclarationID = argumentDeclaration.Id, Line = argumentDeclaration.Line, Column = argumentDeclaration.Column, StartOffset = argumentDeclaration.StartOffset, NodeLength = argumentDeclaration.NodeLength }; AddVariable(variableDeclaration, searchInParents: false); SetVariable(variableRef, argumentValues[i]); } if (IsAborted) { return; } // Execute statements var block = new BlockInterpreter(BaZicInterpreter, this, ExecutionFlowId, false, null, _methodDeclaration.Statements); block.Run(); if (BaZicInterpreter.Verbose && !IsAborted) { VerboseLog(L.BaZic.Runtime.Interpreters.MethodInterpreter.FormattedEndExecution(_invokeMethod.MethodName, ReturnedValue, ValueInfo.GetValueInfo(ReturnedValue))); } foreach (var variable in Variables) { if (DebugCallInfo.Variables.Remove(variable)) { variable.Dispose(); } } DebugCallInfo = null; if (!_invokeMethod.Await && _methodDeclaration.IsAsync) { GC.Collect(); GC.WaitForPendingFinalizers(); } }
/// <inheritdoc/> internal override object Run() { var expressionValue = ParentInterpreter.RunExpression(Expression.TargetObject); if (ParentInterpreter.IsAborted) { return(null); } if (expressionValue == null) { BaZicInterpreter.ChangeState(this, new NullValueException(L.BaZic.Runtime.Interpreters.Expressions.ArrayIndexerInterpreter.NullValue), Expression); return(null); } var valueInfo = ValueInfo.GetValueInfo(expressionValue); if (!valueInfo.IsArray) { BaZicInterpreter.ChangeState(this, new BadTypeException(L.BaZic.Runtime.Interpreters.Expressions.ArrayIndexerInterpreter.FormattedIndexerForbidden(valueInfo.Type.Name)), Expression); return(null); } if (Expression.Indexes.Length != 1) { BaZicInterpreter.ChangeState(this, new OutOfRangeException(L.BaZic.Runtime.Interpreters.Expressions.ArrayIndexerInterpreter.OneIndexerAllowed), Expression); return(null); } var index = ParentInterpreter.RunExpression(Expression.Indexes[0]); if (ParentInterpreter.IsAborted) { return(null); } if (index == null) { BaZicInterpreter.ChangeState(this, new OutOfRangeException(L.BaZic.Runtime.Interpreters.Expressions.ArrayIndexerInterpreter.IndexMustNotBeNull), Expression); return(null); } if (valueInfo.Type == typeof(ObservableDictionary)) { var dictionary = (ObservableDictionary)expressionValue; object val = null; if (dictionary.TryGetValue(index, out val)) { return(val); } BaZicInterpreter.ChangeState(this, new OutOfRangeException(L.BaZic.Runtime.Interpreters.Expressions.ArrayIndexerInterpreter.FormattedKeyDoesNotExist(index?.ToString())), Expression); return(null); } else if (typeof(IDictionary).IsAssignableFrom(valueInfo.Type)) { return(((IDictionary)expressionValue)[index]); } else { var indexValue = index as int?; if (indexValue == null) { BaZicInterpreter.ChangeState(this, new BadArgumentException(L.BaZic.Runtime.Interpreters.Expressions.ArrayIndexerInterpreter.CastToNumber), Expression); return(null); } if (indexValue < 0 || indexValue >= valueInfo.Length) { BaZicInterpreter.ChangeState(this, new OutOfRangeException(L.BaZic.Runtime.Interpreters.Expressions.ArrayIndexerInterpreter.FormattedOutOfRange(indexValue.ToString(), (valueInfo.Length - 1).ToString())), Expression); return(null); } if (valueInfo.Type.IsArray || valueInfo.Type == typeof(Array)) { return(((Array)expressionValue).GetValue(indexValue.Value)); } else if (typeof(IList).IsAssignableFrom(valueInfo.Type)) { return(((IList)expressionValue)[indexValue.Value]); } } BaZicInterpreter.ChangeState(this, new InternalException(L.BaZic.Runtime.Interpreters.Expressions.ArrayIndexerInterpreter.FormattedUnsupportedArray(valueInfo.Type.FullName)), Expression); return(null); }
/// <summary> /// Assigns the specified value to an array. /// </summary> /// <param name="arrayIndexer">The reference to the position in the array to set.</param> /// <param name="value">The value to assign.</param> private void AssignArrayValue(ArrayIndexerExpression arrayIndexer, object value) { var expressionValue = ParentInterpreter.RunExpression(arrayIndexer.TargetObject); if (ParentInterpreter.IsAborted) { return; } if (expressionValue == null) { BaZicInterpreter.ChangeState(this, new NullValueException(L.BaZic.Runtime.Interpreters.Statements.AssignInterpreter.TargetObjectNull), arrayIndexer); return; } var valueInfo = ValueInfo.GetValueInfo(expressionValue); if (!valueInfo.IsArray) { BaZicInterpreter.ChangeState(this, new BadTypeException(L.BaZic.Runtime.Interpreters.Expressions.ArrayIndexerInterpreter.FormattedIndexerForbidden(valueInfo.Type.Name)), arrayIndexer); return; } if (arrayIndexer.Indexes.Length != 1) { BaZicInterpreter.ChangeState(this, new OutOfRangeException(L.BaZic.Runtime.Interpreters.Expressions.ArrayIndexerInterpreter.OneIndexerAllowed), arrayIndexer); return; } var index = ParentInterpreter.RunExpression(arrayIndexer.Indexes[0]); if (ParentInterpreter.IsAborted) { return; } if (index == null) { BaZicInterpreter.ChangeState(this, new OutOfRangeException(L.BaZic.Runtime.Interpreters.Expressions.ArrayIndexerInterpreter.IndexMustNotBeNull), arrayIndexer.Indexes[0]); return; } if (valueInfo.Type == typeof(ObservableDictionary)) { ((ObservableDictionary)expressionValue)[index] = value; return; } else if (typeof(IDictionary).IsAssignableFrom(valueInfo.Type)) { ((IDictionary)expressionValue)[index] = value; return; } else { var indexValue = index as int?; if (indexValue == null) { BaZicInterpreter.ChangeState(this, new BadArgumentException(L.BaZic.Runtime.Interpreters.Expressions.ArrayIndexerInterpreter.CastToNumber), arrayIndexer); return; } if (indexValue < 0 || indexValue >= valueInfo.Length) { BaZicInterpreter.ChangeState(this, new OutOfRangeException(L.BaZic.Runtime.Interpreters.Statements.AssignInterpreter.FormattedOutOfRange(indexValue, valueInfo.Length - 1)), arrayIndexer); return; } if (valueInfo.Type.IsArray || valueInfo.Type == typeof(Array)) { ((Array)expressionValue).SetValue(value, indexValue.Value); return; } else if (typeof(IList).IsAssignableFrom(valueInfo.Type)) { ((IList)expressionValue)[indexValue.Value] = value; return; } } BaZicInterpreter.ChangeState(this, new InternalException(L.BaZic.Runtime.Interpreters.Statements.AssignInterpreter.FormattedUnsupportedArray(valueInfo.Type.FullName)), arrayIndexer); }
internal void SetValue(object value) { SetValue(value, ValueInfo.GetValueInfo(value)); }
/// <summary> /// Execute an expression /// </summary> /// <param name="expression">The expression to interpret</param> /// <returns>Returns the returned value of the expression</returns> internal object RunExpression(Code.AbstractSyntaxTree.Expression expression) { if (expression == null) { return(null); } if (BaZicInterpreter.Verbose) { VerboseLog(L.BaZic.Runtime.Interpreters.Interpreter.FormattedExecutingExpression(expression.GetType().Name)); } object expressionResult = null; switch (expression) { case ArrayCreationExpression arrayCreation: expressionResult = new ArrayCreationInterpreter(BaZicInterpreter, this, arrayCreation).Run(); break; case ArrayIndexerExpression arrayIndexer: expressionResult = new ArrayIndexerInterpreter(BaZicInterpreter, this, arrayIndexer).Run(); break; case BinaryOperatorExpression binaryOperator: expressionResult = new BinaryOperatorInterpreter(BaZicInterpreter, this, binaryOperator).Run(); break; case ClassReferenceExpression classReference: expressionResult = new ClassReferenceInterpreter(BaZicInterpreter, this, classReference).Run(); break; case ExceptionReferenceExpression exceptionReference: expressionResult = new ExceptionInterpreter(BaZicInterpreter, this, exceptionReference).Run(); break; case InstantiateExpression instantiate: expressionResult = new InstantiateInterpreter(BaZicInterpreter, this, instantiate).Run(); break; case InvokeCoreMethodExpression invokeCoreMethod: expressionResult = new InvokeCoreMethodInterpreter(BaZicInterpreter, this, invokeCoreMethod, ExecutionFlowId).Run(); break; case InvokeMethodExpression invokeMethod: expressionResult = new InvokeMethodInterpreter(BaZicInterpreter, this, invokeMethod, ExecutionFlowId).Run(); break; case NotOperatorExpression notOperator: expressionResult = new NotOperatorInterpreter(BaZicInterpreter, this, notOperator).Run(); break; case PrimitiveExpression primitive: expressionResult = new PrimitiveInterpreter(BaZicInterpreter, this, primitive).Run(); break; case PropertyReferenceExpression propertyReference: expressionResult = new PropertyReferenceInterpreter(BaZicInterpreter, this, propertyReference).Run(); break; case VariableReferenceExpression variableReference: expressionResult = new VariableReferenceInterpreter(BaZicInterpreter, this, variableReference).Run(); break; default: BaZicInterpreter.ChangeState(this, new InternalException(L.BaZic.Runtime.Interpreters.Interpreter.FormattedInterpreterNotFound(expression.GetType().Name)), expression); break; } if (IsAborted) { return(null); } if (BaZicInterpreter.Verbose) { VerboseLog(L.BaZic.Runtime.Interpreters.Interpreter.FormattedExpressionReturnedValue(expressionResult, ValueInfo.GetValueInfo(expressionResult))); } return(expressionResult); }