/// <summary> /// Ejecuta la sentencia de impresión /// </summary> private void ExecutePrint(SentencePrint sentence) { string text = new Compiler.Interpreter().EvaluateText(Context.Actual, sentence.Message, out string error); // Log AddDebug($"Print: {sentence.Message}"); // Añade el resultado de la sentencia if (!string.IsNullOrWhiteSpace(error)) { AddError($"Error when execute print: {error}"); } else { AddConsoleOutput(text); } }
/// <summary> /// Ejecuta un bucle while /// </summary> private void ExecuteWhile(SentenceWhile sentence) { if (string.IsNullOrWhiteSpace(sentence.Condition)) { AddError("Cant find condition for while loop"); } else { bool result = new Compiler.Interpreter().EvaluateCondition(Context, sentence.Condition, out string error); if (!string.IsNullOrEmpty(error)) { AddError(error); } else if (result) { ExecuteWithContext(sentence.Sentences); } } }
/// <summary> /// Ejecuta la sentencia para devolver el resultado de una función /// </summary> private void ExecuteFunctionReturn(SentenceReturn sentence) { if (string.IsNullOrWhiteSpace(Context.Actual.ScopeFuntionResultVariable)) { AddError("Cant execute a return because there is not function block"); } else { VariableModel result = new Compiler.Interpreter().EvaluateExpression(Context, sentence.Expression, out string error); // Si no hay error, añade el resultado al contexto if (!string.IsNullOrWhiteSpace(error)) { AddError(error); } else { Context.Actual.VariablesTable.Add(new VariableModel(Context.Actual.ScopeFuntionResultVariable, result.Value)); } } }
/// <summary> /// Ejecuta una sentencia de asignación /// </summary> private void ExecuteLet(SentenceLet sentence) { if (string.IsNullOrWhiteSpace(sentence.Variable)) { AddError("Cant find the variable name"); } else { VariableModel variable = Context.Actual.VariablesTable.Get(sentence.Variable); // Depuración AddDebug($"Let {sentence.Variable} = {sentence.Expression}"); // Declara la variable si no existía if (variable == null && sentence.Type != VariableModel.VariableType.Unknown) { // Añade una variable con el valor predeterminado Context.Actual.VariablesTable.Add(sentence.Variable, sentence.Type); // Obtiene la variable variable = Context.Actual.VariablesTable.Get(sentence.Variable); } // Ejecuta la sentencia if (variable == null) { AddError($"Variable {sentence.Variable} not declared"); } else { VariableModel result = new Compiler.Interpreter().EvaluateExpression(Context, sentence.Expression, out string error); if (!string.IsNullOrWhiteSpace(error)) { AddError($"Error when evaluate expression {sentence.Expression}. {error}"); } else { variable.Value = result.Value; } } } }
/// <summary> /// Ejecuta una sentencia condicional /// </summary> private void ExecuteIf(SentenceIf sentence) { if (string.IsNullOrWhiteSpace(sentence.Condition)) { AddError("Cant find condition for if sentence"); } else { bool result = new Compiler.Interpreter().EvaluateCondition(Context, sentence.Condition, out string error); if (!string.IsNullOrEmpty(error)) { AddError(error); } else if (result && sentence.SentencesThen.Count > 0) { ExecuteWithContext(sentence.SentencesThen); } else if (!result && sentence.SentencesElse.Count > 0) { ExecuteWithContext(sentence.SentencesElse); } } }
/// <summary> /// Ejecuta una llamada a una función /// </summary> private void ExecuteFunctionCall(SentenceCallFunction sentence) { if (string.IsNullOrWhiteSpace(sentence.Function)) { AddError("Cant find the name function for call"); } else { SentenceFunction function = Context.Actual.FunctionsTable.GetIfExists(sentence.Function); if (function == null) { AddError($"Cant find the function to call: {sentence.Function}"); } else { string error = string.Empty; // Crea un nuevo contexto Context.Add(); // Añade los argumentos al contexto foreach (VariableModel argument in function.Arguments) { if (string.IsNullOrWhiteSpace(error)) { int index = function.Arguments.IndexOf(argument); // Si el argumento corresponde a un parámetro, se añade al contexto esa variable con el valor // Si no, se añade la variable con su valor predeterminado if (sentence.ParameterExpressions.Count > index) { VariableModel result = new Compiler.Interpreter().EvaluateExpression(Context, sentence.ParameterExpressions[index], out error); if (string.IsNullOrWhiteSpace(error)) { Context.Actual.VariablesTable.Add(argument.Name, result.Value); } } else { Context.Actual.VariablesTable.Add(argument); } } } // Si no hay ningún error, ejecuta las sentencias de la función if (!string.IsNullOrWhiteSpace(error)) { AddError(error); } else { // Añade el nombre que tiene que tener el valor de retorno Context.Actual.ScopeFuntionResultVariable = "Return_" + Guid.NewGuid().ToString(); // Ejecuta las sentencias de la función Execute(function.Sentences); // Obtiene el resultado de la función if (!string.IsNullOrWhiteSpace(sentence.ResultVariable)) { VariableModel variable = Context.Actual.Parent.VariablesTable.GetIfExists(sentence.ResultVariable); if (variable == null) { AddError($"The variable {sentence.ResultVariable} is undefined"); } else { VariableModel result = Context.Actual.VariablesTable.GetIfExists(Context.Actual.ScopeFuntionResultVariable); if (result == null) { AddError($"Cant find result for function {sentence.Function}"); } else { variable.Value = result.Value; } } } } // Elimina el contexto Context.Pop(); } } }