public override MinceObject Evaluate(Interpreter interpreter) { int initialDepth = interpreter.depth; interpreter.Eat(); MinceUserFunction userFunc = new MinceUserFunction(); List <Token> tokens = new List <Token>(); string funcName = interpreter.Eat().ToString(); 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.previousToken, "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; Variable v = new Variable(funcName, userFunc, false, initialDepth); interpreter.variables.variables.Add(v); return(new MinceNull()); }
public Variable GetProperty(Interpreter interpreter, bool isPrivate) { interpreter.Eat(); string varName = interpreter.Eat("IDENTIFIER").ToString(); interpreter.Eat("L_CURLY_BRACE"); bool got = false; bool setted = false; Property p = new Property(); p.name = varName; while (interpreter.currentToken.type == "GET" || interpreter.currentToken.type == "SET") { bool isGet = interpreter.currentToken.type == "GET"; if (isGet && got) { throw new InterpreterException(interpreter.currentToken, varName + " already has a get statement!"); } else if (!isGet && setted) { throw new InterpreterException(interpreter.currentToken, varName + " already has a set statement!"); } interpreter.Eat(); List <Token> tokens = new List <Token>(); MinceUserFunction func = new MinceUserFunction(); if (!isGet) { interpreter.Eat("COLON"); string vName = interpreter.Eat("IDENTIFIER").ToString(); func.variableNames.Add(vName); } interpreter.Eat("L_CURLY_BRACE"); interpreter.depth++; tokens.Add(new Token(0, 0, "L_CURLY_BRACE")); tokens = tokens.Concat(interpreter.SkipBlock()).ToList(); func.value = tokens; if (isGet) { p.getFunc = func; got = true; } else { p.setFunc = func; setted = true; } } interpreter.Eat("R_CURLY_BRACE"); p.isReadOnly = setted; p.isPrivate = isPrivate; return(p); }
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); }