//When a library is defined. public override object VisitStat_library([NotNull] algoParser.Stat_libraryContext context) { //Check if a library with this name already exists. if (Scopes.LibraryExists(context.IDENTIFIER().GetText())) { Error.Warning(context, "A library with the name '" + context.IDENTIFIER().GetText() + "' has already been loaded, so loading was ignored."); } //Switch the current scope out for a new "library" scope. AlgoScopeCollection oldScope = Scopes; Scopes = new AlgoScopeCollection(); //Evaluate the contents of the library. foreach (var statement in context.statement()) { VisitStatement(statement); } //Save the new scope, and switch back to the old one. AlgoScopeCollection libScope = Scopes; Scopes = oldScope; //Add the library scope to the library list. Scopes.AddLibrary(context.IDENTIFIER().GetText(), libScope); return(null); }
//When a variable is deleted. public override object VisitStat_deletevar([NotNull] algoParser.Stat_deletevarContext context) { //Checking if the disregard wants to delete all variables or only one. if (context.IDENTIFIER() != null) { //Get variable name. string varname = Particles.StitchVariableName(context, context.IDENTIFIER().GetText(), context.particle()); //Check if variable exists. if (!Scopes.VariableExists(varname)) { //Maybe it's a library? if (Scopes.LibraryExists(varname)) { //Okay, just disregard the library. Scopes.RemoveLibrary(varname); return(null); } //Not a library, so doesn't exist. Error.Fatal(context, "Invalid variable name given to disregard."); return(null); } //Remove variable. Scopes.RemoveVariable(varname); } else { //Reset all scopes. Scopes.Reset(); } return(null); }
//When a function is called. public override object VisitStat_functionCall([NotNull] algoParser.Stat_functionCallContext context) { //If there are particles, get the last value. AlgoValue currentVal = null; bool isLibraryTopLevelCall = false; if (context.IDENTIFIER() != null) { //Is the identifier a library and has no particles? if (!Scopes.VariableExists(context.IDENTIFIER().GetText()) && Scopes.LibraryExists(context.IDENTIFIER().GetText()) && (context.particle() == null || context.particle().Length == 0)) { //Library top level call, so don't evaluate like normal particles. isLibraryTopLevelCall = true; //Just get the very last function like a normal variable, but from the library. string libName = context.IDENTIFIER().GetText(); string name = context.functionCall_particle().IDENTIFIER().GetText(); var lib = Scopes.GetLibrary(libName); if (!lib.VariableExists(name)) { Error.Fatal(context, "No variable named '" + name + "' exists in library '" + libName + "'."); return(null); } currentVal = lib.GetVariable(name); } else { //Not a library top level call, so execute like a normal particle block. currentVal = Particles.ParseParticleBlock(this, context, context.IDENTIFIER(), context.particle()); } } else { //No particles, just grab the value as an identifier. string name = context.functionCall_particle().IDENTIFIER().GetText(); if (!Scopes.VariableExists(name)) { Error.Fatal(context, "No function exists with name '" + name + "'."); return(null); } currentVal = Scopes.GetVariable(name); } //Attempt to execute the final function on the result. if (context.IDENTIFIER() == null || isLibraryTopLevelCall) { //Visit and execute THIS value, not a child value (this was a straight normal call). Particles.SetParticleInput(currentVal); return(VisitFunctionCall_particle(context.functionCall_particle())); } else { //There were particles, visit and execute CHILD value. if (currentVal.Type != AlgoValueType.Object) { Error.Fatal(context, "Cannot call a child function on a value with no children (given value was not an object)."); return(null); } //Get the child, see if it's a function. AlgoObject thisObj = currentVal.Value as AlgoObject; string funcName = context.IDENTIFIER().GetText(); AlgoValue childFunc = thisObj.ObjectScopes.GetVariable(funcName); if (childFunc == null || (childFunc.Type != AlgoValueType.Function && childFunc.Type != AlgoValueType.EmulatedFunction)) { Error.Fatal(context, "No child function exists with name '" + funcName + "'."); return(null); } //Set the particle result as the function value, call the function call particle. Particles.SetParticleInput(childFunc); return(VisitFunctionCall_particle(context.functionCall_particle())); } }