public MinceObject Factor() { if (new List <string>() { "NUMBER", "STRING", "BOOL", "CHAR" }.Contains(interpreter.currentToken.type)) { return((MinceObject)interpreter.Eat()); } else if (interpreter.currentToken.type == "L_BRACKET") { interpreter.Eat("L_BRACKET"); MinceObject result = Evaluate(); interpreter.Eat("R_BRACKET"); return(result); } else if (interpreter.currentToken.type == "IDENTIFIER") { string name = interpreter.Eat().ToString(); if (interpreter.variables.Exists(name)) { var result = interpreter.variables.Get(name).GetValue(); if (result.GetType() == typeof(MinceUserFunction)) { if (interpreter.currentToken.type == "L_BRACKET") { var func = result as MinceUserFunction; interpreter.Eat(); MinceObject[] args = interpreter.GetParameters(); interpreter.Eat("R_BRACKET"); return(func.call(args)); } else { return(result); } } else { return(result); } } else { throw new InterpreterException(interpreter.currentToken, "'" + name + "' does not exist in this context"); } } else if (interpreter.currentToken.type == "NEW") { interpreter.Eat(); var func = Interpreter.types[interpreter.Eat("IDENTIFIER").ToString()]; interpreter.Eat("L_BRACKET"); var p = interpreter.GetParameters(); interpreter.Eat("R_BRACKET"); return(func.Invoke(p)); } else if (interpreter.currentToken.type == "NOT") { interpreter.Eat(); return(new MinceBool(!(bool)(this.Evaluate() as MinceBool).value)); } else if (interpreter.currentToken.type == "NULL") { interpreter.Eat(); return(new MinceNull()); } else if (interpreter.currentToken.type == "FUNCTION") { int initialDepth = interpreter.depth; interpreter.Eat(); MinceUserFunction userFunc = new MinceUserFunction(); List <Token> tokens = new List <Token>(); List <string> paramNames = new List <string>(); if (interpreter.currentToken.type == "COLON") { interpreter.Eat(); while (interpreter.currentToken.type == "IDENTIFIER") { string name = interpreter.Eat().ToString(); if (interpreter.variables.Exists(name)) { throw new InterpreterException(interpreter.currentToken, "A variable called '" + name + "' already exists!"); } paramNames.Add(name); if (interpreter.currentToken.type == "L_CURLY_BRACE") { break; } else if (interpreter.currentToken.type == "COMMA") { interpreter.Eat(); } else { throw new InterpreterException(interpreter.currentToken, "Expected ',' or '{' after parameter name"); } } } interpreter.Eat("L_CURLY_BRACE"); interpreter.depth++; tokens.Add(new Token(0, 0, "L_CURLY_BRACE")); tokens = tokens.Concat(interpreter.SkipBlock()).ToList(); userFunc.value = tokens; userFunc.variableNames = paramNames; return(userFunc); } else if (interpreter.currentToken.type == "L_SQUARE_BRACKET") { MinceArray ar = new MinceArray(new MinceObject[0]); interpreter.Eat(); while (interpreter.currentToken.type != "R_SQUARE_BRACKET") { ar.add(Evaluate()); if (interpreter.currentToken.type != "R_SQUARE_BRACKET") { interpreter.Eat("COMMA"); } } interpreter.Eat(); return(ar); } else if (interpreter.currentToken.type == "L_CURLY_BRACE") { MinceDynamic d = new MinceDynamic(); interpreter.Eat(); while (interpreter.currentToken.type == "IDENTIFIER") { string name = interpreter.Eat().ToString(); interpreter.Eat("EQUALS"); MinceObject value = Evaluate(); Variable v = new Variable(name, value, true); d.members.Add(v); if (interpreter.currentToken.type != "COMMA") { break; } interpreter.Eat(); } interpreter.Eat("R_CURLY_BRACE"); return(d); } else if (interpreter.currentToken.type == "EOF") { return(new MinceNull()); } throw new InterpreterException(interpreter.currentToken, "Unexpected token " + interpreter.currentToken.ToString() + " found when looking for a factor at token #" + interpreter.pointer); }
public override MinceObject Evaluate(Interpreter interpreter) { int pos = interpreter.pointer; int initialDepth = interpreter.depth; interpreter.Eat(); string varName = interpreter.Eat("IDENTIFIER").ToString(); if (interpreter.variables.Exists(varName)) { throw new Exception("A variable named '" + varName + "' already exists in this scope"); } interpreter.Eat("COLON"); MinceArray array = (MinceArray)interpreter.evaluation.Evaluate(); interpreter.Eat("L_CURLY_BRACE"); interpreter.depth++; if (interpreter.loopPositions.Count <= 0 || interpreter.loopPositions[0].depth != initialDepth) { interpreter.loopPositions.Insert(0, new LoopPosition(pos, initialDepth) { index = 0 }); } if ((array.value as List <MinceObject>).Count == 0) { interpreter.SkipBlock(); interpreter.loopPositions.RemoveAt(0); return(new MinceNull()); } Variable indexVar = new Variable(varName, (array.value as List <MinceObject>)[interpreter.loopPositions[0].index], true, interpreter.depth); interpreter.variables.variables.Add(indexVar); interpreter.EvaluateBlock(); if (interpreter.loopPositions.Count < 1 || interpreter.loopPositions[0].depth != initialDepth) { interpreter.variables.variables.Remove(indexVar); return(new MinceNull()); } interpreter.loopPositions[0].index++; interpreter.variables.variables.Remove(indexVar); if (interpreter.loopPositions[0].index >= (array.value as List <MinceObject>).Count) { interpreter.loopPositions.RemoveAt(0); } else { interpreter.depth = interpreter.loopPositions[0].depth; interpreter.GoTo(interpreter.loopPositions[0].pointer); } return(new MinceNull()); }