/// <summary> /// Ejecuta la declaración de una función: añade la función a la tabla de funciones del contexto /// </summary> private void ExecuteFunctionDeclare(SentenceFunction sentence) { if (string.IsNullOrWhiteSpace(sentence.Name)) { AddError("Cant find name for function declare"); } else { Context.Actual.FunctionsTable.Add(sentence.Name, sentence); } }
/// <summary> /// Transforma una definición de función /// </summary> /// <remarks> /// def my_function(fname): /// print(fname + " var") /// </remarks> private void TransformFunction(SentenceFunction sentence) { // Añade los argumentos a las variables del contexto foreach (SymbolModel argument in sentence.Arguments) { Context.Actual.VariablesTable.Add(argument.Name, ConvertSymbolType(argument.Type)); } // Añade la definición de función AddSentence(string.Empty); AddSentence("def " + sentence.Definition.Name + "(" + GetArguments(sentence.Arguments) + "):"); // Añade el cuerpo de la función AddIndent(); Transform(sentence.Sentences); RemoveIndent(); // Añade una línea vacía tras la definición de la función AddSentence(string.Empty); }
/// <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(); } } }