using KumiScript.Reader; namespace KumiScript.Interpreter { public class MathPrimitives { public static NumberExpression Plus(Expression args, Environment env) { List argl = args.EvalMembers(env); decimal acc = 0; for (int i = 0; i < argl.Count; i++) { acc += argl[i].GetValueAsFloat(); } return new NumberExpression(acc); } public static NumberExpression Minus(Expression args, Environment env) { List argl = args.EvalMembers(env); if (argl.Count == 0) throw new InterpreterInvalidApplicationException(); decimal acc = argl[0].GetValueAsFloat(); if (argl.Count == 1) return new NumberExpression(1 - acc); for (int i = 1; i < argl.Count; i++) { acc -= argl[i].GetValueAsFloat(); } return new NumberExpression(acc); } public static NumberExpression Times(Expression args, Environment env) { List argl = args.EvalMembers(env); if (argl.Count < 2) throw new InterpreterInvalidInvocationException(); decimal f = argl[0].GetValueAsFloat(); for (int i = 1; i < argl.Count; i++) { f *= argl[i].GetValueAsFloat(); } return new NumberExpression(f); } public static NumberExpression DividedBy(Expression args, Environment env) { List argl = args.EvalMembers(env); if (argl.Count != 2) throw new InterpreterInvalidApplicationException(); return new NumberExpression(argl[0].GetValueAsFloat() / argl[1].GetValueAsFloat()); } public static NumberExpression Modulus(Expression args, Environment env) { List argl = args.EvalMembers(env); if (argl.Count != 2) throw new InterpreterInvalidApplicationException(); return new NumberExpression(argl[0].GetValueAsFloat() % argl[1].GetValueAsFloat()); } public static Expression GreaterThan(Expression args, Environment env) { List argl = args.EvalMembers(env); if (argl.Count != 2) throw new InterpreterInvalidApplicationException(); return argl[0].GetValueAsFloat() > argl[1].GetValueAsFloat() ? TrueExpression.GetInstance() : NilExpression.GetInstance(); } public static Expression LessThan(Expression args, Environment env) { List argl = args.EvalMembers(env); if (argl.Count != 2) throw new InterpreterInvalidApplicationException(); return argl[0].GetValueAsFloat() < argl[1].GetValueAsFloat() ? TrueExpression.GetInstance() : NilExpression.GetInstance(); } public static Expression LessThanEquals(Expression args, Environment env) { List argl = args.EvalMembers(env); if (argl.Count != 2) throw new InterpreterInvalidApplicationException(); return argl[0].GetValueAsFloat() <= argl[1].GetValueAsFloat() ? TrueExpression.GetInstance() : NilExpression.GetInstance(); } public static Expression GreaterThanEquals(Expression args, Environment env) { List argl = args.EvalMembers(env); if (argl.Count != 2) throw new InterpreterInvalidApplicationException(); return argl[0].GetValueAsFloat() >= argl[1].GetValueAsFloat() ? TrueExpression.GetInstance() : NilExpression.GetInstance(); } public static Expression PlusPlus(Expression args, Environment env) { List argl = args.GetMembers(); if (argl.Count != 1) throw new InterpreterInvalidApplicationException(); Symbol name = argl[0].GetSymbol(); Expression val = env.Lookup(name); NumberExpression nump = new NumberExpression(val.GetValueAsFloat() + 1); env.RedefineSymbol(name, nump); return nump; } public static Expression MinusMinus(Expression args, Environment env) { List argl = args.GetMembers(); if (argl.Count != 1) throw new InterpreterInvalidApplicationException(); Symbol name = argl[0].GetSymbol(); Expression val = env.Lookup(name); NumberExpression nump = new NumberExpression(val.GetValueAsFloat() - 1); env.RedefineSymbol(name, nump); return nump; } public static Environment RegisterPrimitives(Environment outer) { Environment result = new Environment(outer); result.AddSymbol(SymbolTable.GetInstance().FromString("+"), new ProcedureExpression(new PrimitiveProcedure(Plus))); result.AddSymbol(SymbolTable.GetInstance().FromString("-"), new ProcedureExpression(new PrimitiveProcedure(Minus))); result.AddSymbol(SymbolTable.GetInstance().FromString("*"), new ProcedureExpression(new PrimitiveProcedure(Times))); result.AddSymbol(SymbolTable.GetInstance().FromString("/"), new ProcedureExpression(new PrimitiveProcedure(DividedBy))); result.AddSymbol(SymbolTable.GetInstance().FromString("%"), new ProcedureExpression(new PrimitiveProcedure(Modulus))); result.AddSymbol(SymbolTable.GetInstance().FromString(">"), new ProcedureExpression(new PrimitiveProcedure(GreaterThan))); result.AddSymbol(SymbolTable.GetInstance().FromString("<"), new ProcedureExpression(new PrimitiveProcedure(LessThan))); result.AddSymbol(SymbolTable.GetInstance().FromString("<="), new ProcedureExpression(new PrimitiveProcedure(LessThanEquals))); result.AddSymbol(SymbolTable.GetInstance().FromString(">="), new ProcedureExpression(new PrimitiveProcedure(GreaterThanEquals))); result.AddSymbol(SymbolTable.GetInstance().FromString("++!"), new ProcedureExpression(new PrimitiveProcedure(PlusPlus))); result.AddSymbol(SymbolTable.GetInstance().FromString("--!"), new ProcedureExpression(new PrimitiveProcedure(MinusMinus))); return result; } } }