Пример #1
0
        /// <summary>Delete the current function being edited.</summary>
        public void Delete()
        {
            if (editFunction != null)
            {
                string oldFunctionFile = functionDir + "/" + editFunction.Id + ".math";
                if (System.IO.File.Exists(oldFunctionFile))
                {
                    System.IO.File.Delete(oldFunctionFile);
                }

                if (selectedFunction != null && selectedFunction.Id == editFunction.Id)
                {
                    selectedFunction = null;
                }

                if (RunFunction != null && RunFunction.Id == editFunction.Id)
                {
                    RunFunction = null;
                }

                kalc.Functions.Remove(editFunction.Id);
            }

            editFunction        = null;
            editWindowEnabled   = false;
            editFunctionContent = "";
            editFunctionName    = "unnamed";
        }
Пример #2
0
 public Solver(JITFunction func, int maxiter, int maxfev, double xtol, double ftol)
 {
     this.func    = func;
     this.maxiter = maxiter;
     this.maxfev  = maxfev;
     this.xtol    = xtol;
     this.ftol    = ftol;
 }
Пример #3
0
 public Solver(JITFunction func)
 {
     this.func = func;
     maxiter   = 0;
     maxfev    = 0;
     xtol      = 1E-8;
     ftol      = 1E-8;
 }
Пример #4
0
        public static JITFunction FromFile(string filename, Kerbulator kalc)
        {
            StreamReader file     = File.OpenText(filename);
            string       contents = file.ReadToEnd() + "\n";

            file.Close();
            JITFunction f = new JITFunction(Path.GetFileNameWithoutExtension(filename), contents, kalc);

            return(f);
        }
Пример #5
0
        public static string FormatResult(JITFunction f, List <Object> result)
        {
            string str = "";

            for (int i = 0; i < result.Count - 1; i++)
            {
                str += f.Outs[i] + " = " + FormatVar(result[i]) + ", ";
            }
            str += f.Outs[result.Count - 1] + " = " + FormatVar(result[result.Count - 1]);
            return(str);
        }
Пример #6
0
        public List <Object> Run(JITFunction f)
        {
            if (f.InError)
            {
                throw new Exception(f.ErrorString);
            }

            List <Object> r = f.Execute(new List <Object>());

            if (f.InError)
            {
                throw new Exception(f.ErrorString);
            }

            return(r);
        }
Пример #7
0
        /// <summary>Obtain some info of a function.</summary>
        /// <param name="f">The function to obtain the info of</param>
        public string FunctionDescription(JITFunction f)
        {
            if (f.InError)
            {
                return("ERROR: " + f.ErrorString);
            }

            string desc = "";

            if (f.Ins.Count == 0)
            {
                desc += "Inputs:\nnone\n";
            }
            else
            {
                desc += "Inputs:\n";
                for (int i = 0; i < f.Ins.Count; i++)
                {
                    desc += f.Ins[i];
                    if (i < f.InDescriptions.Count && f.InDescriptions[i] != "")
                    {
                        desc += ": " + f.InDescriptions[i];
                    }
                    desc += "\n";
                }
            }

            if (f.Outs.Count == 0)
            {
                desc += "\nOutputs:\nnone\n";
            }
            else
            {
                desc += "\nOutputs:\n";
                for (int i = 0; i < f.Outs.Count; i++)
                {
                    desc += f.Outs[i];
                    if (i < f.OutDescriptions.Count && f.OutDescriptions[i] != "")
                    {
                        desc += ": " + f.OutDescriptions[i];
                    }
                    desc += "\n";
                }
            }

            return(desc);
        }
Пример #8
0
        public string Run(string functionId)
        {
            if (!functions.ContainsKey(functionId))
            {
                throw new Exception("Function not found: " + functionId);
            }

            JITFunction f = functions[functionId];

            if (f.InError)
            {
                throw new Exception(f.ErrorString);
            }

            List <Object> r = functions[functionId].Execute(new List <Object>());

            if (f.InError)
            {
                throw new Exception(f.ErrorString);
            }

            return(FormatResult(f, r));
        }
Пример #9
0
        /// <summary>Scan for available functions and update funtion references if needed.</summary>
        public void Scan()
        {
            try {
                JITFunction.Scan(functionDir, kalc);
                error = null;
            } catch (Exception e) {
                error     = "Cannot access function dir (" + functionDir + "): " + e.Message;
                functions = new Dictionary <string, JITFunction>();
                throw e;
            }

            if (selectedFunction != null)
            {
                if (functions.ContainsKey(selectedFunction.Id))
                {
                    selectedFunction    = functions[selectedFunction.Id];
                    functionDescription = FunctionDescription(selectedFunction);
                }
                else
                {
                    selectedFunction    = null;
                    functionDescription = "";
                }

                functionDescriptionHeight = GUI.skin.GetStyle("label").CalcHeight(new GUIContent(functionDescription), 225);
            }

            if (editFunction != null)
            {
                if (functions.ContainsKey(editFunction.Id))
                {
                    editFunction = functions[editFunction.Id];
                }
                else
                {
                    editFunction      = null;
                    editWindowEnabled = false;
                }
            }

            if (runFunction != null)
            {
                if (functions.ContainsKey(runFunction.Id))
                {
                    runFunction = functions[runFunction.Id];
                }
                else
                {
                    runFunction = null;
                }

                functionOutput = "";
            }

            List <int> envsToRemove = new List <int>();

            foreach (KeyValuePair <int, ExecutionEnvironment> pair in envs)
            {
                if (functions.ContainsKey(pair.Value.func.Id))
                {
                    pair.Value.func = functions[pair.Value.func.Id];
                }
                else
                {
                    envsToRemove.Add(pair.Key);
                }
            }
            foreach (int id in envsToRemove)
            {
                envs.Remove(id);
            }
        }
Пример #10
0
        /// <summary>Save the current function being edited.</summary>
        public void Save()
        {
            if (!IsValidName(editFunctionName))
            {
                editFunctionStyle = invalidFunctionName;
                return;
            }
            else
            {
                editFunctionStyle = validFunctionName;
            }

            int id;

            if (editFunction != null && editFunction.Id != editFunctionName)
            {
                // Changing function name, remove old function
                string oldFunctionFile = functionDir + "/" + editFunction.Id + ".math";
                if (System.IO.File.Exists(oldFunctionFile))
                {
                    try {
                        System.IO.File.Delete(oldFunctionFile);
                        error = null;
                    } catch (Exception e) {
                        error = "Cannot save function: " + e.Message;
                        return;
                    }
                }

                kalc.Functions.Remove(editFunction.Id);

                if (selectedFunction != null && selectedFunction.Id == editFunction.Id)
                {
                    selectedFunction = null;
                }

                if (RunFunction != null && RunFunction.Id == editFunction.Id)
                {
                    RunFunction = null;
                }

                id = WindowIdOfRepeatingFunction(editFunction.Id);
                if (id != -1)
                {
                    envs.Remove(id);
                }
            }

            // Save new function
            try {
                functionFile = functionDir + "/" + editFunctionName + ".math";
                System.IO.File.WriteAllText(functionFile, editFunctionContent);
                error = null;
            } catch (Exception e) {
                error = "Cannot save function: " + e.Message;
                return;
            }

            // Compile new function
            JITFunction f = JITFunction.FromFile(functionFile, kalc);

            f.Compile();
            if (RunFunction != null && RunFunction.Id == f.Id)
            {
                RunFunction = f;
            }

            id = WindowIdOfRepeatingFunction(f.Id);
            if (id != -1)
            {
                envs[id].func = f;
            }

            if (!kalc.Functions.ContainsKey(editFunctionName))
            {
                kalc.Functions.Add(editFunctionName, f);
            }
            else
            {
                kalc.Functions[editFunctionName] = f;
            }

            editFunction = f;
        }
Пример #11
0
        /// <summary>Draws the edit window that allows basic text editing.</summary>
        /// <param name="id">An unique number indentifying the window</param>
        public void DrawEditWindow(int id)
        {
            // Close button
            editWindowEnabled = !GUI.Toggle(new Rect(options.editWindowPos.width - 25, 0, 20, 20), !editWindowEnabled, "");

            GUILayout.BeginHorizontal();

            if (GUILayout.Button(deleteIcon, defaultButton, GUILayout.Width(25), GUILayout.Height(24)))
            {
                Delete();
            }

            editFunctionName = GUILayout.TextField(editFunctionName, editFunctionStyle, GUILayout.Height(24));

            if (GUILayout.Button(saveIcon, defaultButton, GUILayout.Width(24), GUILayout.Height(24)))
            {
                Save();

                if (editFunction == null)
                {
                    editFunction = kalc.Functions[editFunctionName];
                }
            }

            if (GUILayout.Button(runIcon, defaultButton, GUILayout.Width(24), GUILayout.Height(24)))
            {
                // Save it
                Save();

                // Load the function to be run
                RunFunction      = editFunction;
                runWindowEnabled = true;

                // Run it
                Run();
                functionOutput = FormatOutput(env);
            }

            GUILayout.EndHorizontal();

            if (functionNameError != null)
            {
                GUILayout.Label("Cannot save function:" + functionNameError, invalidFunctionName);
            }

            editorScrollPos     = GUILayout.BeginScrollView(editorScrollPos, false, true, GUILayout.Height(options.editWindowPos.height - 140));         //, GUILayout.Width(460));
            editFunctionContent = GUILayout.TextArea(editFunctionContent, GUILayout.ExpandWidth(true));
            TextEditor editor = (TextEditor)GUIUtility.GetStateObject(typeof(TextEditor), GUIUtility.keyboardControl);

            GUILayout.EndScrollView();

            GUILayout.BeginHorizontal();
            foreach (string s in greekLetters)
            {
                if (GUILayout.Button(s, keyboard, GUILayout.Width(15)))
                {
                    editFunctionContent = editFunctionContent.Insert(editor.cursorIndex, s);
                    editor.cursorIndex++;
                    editor.selectIndex++;
                    //editor.UpdateScrollOffsetIfNeeded();
                }
            }
            GUILayout.EndHorizontal();

            GUILayout.BeginHorizontal();
            foreach (string s in greekUCLetters)
            {
                if (GUILayout.Button(s, keyboard, GUILayout.Width(15)))
                {
                    editFunctionContent = editFunctionContent.Insert(editor.cursorIndex, s);
                    editor.cursorIndex++;
                    editor.selectIndex++;
                    //editor.UpdateScrollOffsetIfNeeded();
                }
            }
            GUILayout.EndHorizontal();

            GUILayout.BeginHorizontal();
            foreach (string s in symbols)
            {
                if (GUILayout.Button(s, keyboard, GUILayout.Width(15)))
                {
                    editFunctionContent = editFunctionContent.Insert(editor.cursorIndex, s);
                    editor.cursorIndex++;
                    editor.selectIndex++;
                    //editor.UpdateScrollOffsetIfNeeded();
                }
            }
            GUILayout.EndHorizontal();

            options.editWindowPos = ResizeWindow(id, options.editWindowPos, minEditWindowSize);
            GUI.DragWindow(titleBarRect);

            if (Event.current.type == EventType.Repaint)
            {
                tooltip = GUI.tooltip;
            }
        }
Пример #12
0
        public Kerbulator(string functionDir)
        {
            operators = new Dictionary <string, Operator>();
            operators.Add("=", new Operator("=", 1, Arity.BINARY));                               // Assignment
            operators.Add("-", new Operator("-", 4, Arity.BOTH));                                 // Substraction or negation
            operators.Add("+", new Operator("+", 4, Arity.BINARY));                               // Addition
            operators.Add("/", new Operator("/", 5, Arity.BINARY));                               // Division
            operators.Add("÷", new Operator("÷", 5, Arity.BINARY));                               // Division
            operators.Add("√", new Operator("√", 5, Arity.BOTH));                                 // Square Root or ^(1/n)
            operators.Add("%", new Operator("%", 5, Arity.BINARY));                               // Modulo
            operators.Add("*", new Operator("*", 5, Arity.BINARY));                               // Multiplication
            operators.Add("·", new Operator("·", 5, Arity.BINARY));                               // Multiplication
            operators.Add("×", new Operator("×", 5, Arity.BINARY));                               // Multiplication
            operators.Add("^", new Operator("^", 6, Arity.BINARY));                               // Multiplication
            operators.Add("|", new Operator("|", 6, Arity.UNARY));                                // Absolute
            operators.Add("⌊", new Operator("⌊", 6, Arity.UNARY));                                // Floor
            operators.Add("⌈", new Operator("⌈", 6, Arity.UNARY));                                // Ceiling
            operators.Add("<", new Operator("<", 3, Arity.BINARY));                               // Less than
            operators.Add(">", new Operator(">", 3, Arity.BINARY));                               // Greater than
            operators.Add("<=", new Operator("<=", 3, Arity.BINARY));                             // Less than or equal
            operators.Add("≤", new Operator("≤", 3, Arity.BINARY));                               // Less than or equal
            operators.Add(">=", new Operator(">=", 3, Arity.BINARY));                             // Greater than or equal
            operators.Add("≥", new Operator("≥", 3, Arity.BINARY));                               // Greater than or equal
            operators.Add("==", new Operator("==", 3, Arity.BINARY));                             // Equals
            operators.Add("!=", new Operator("!=", 3, Arity.BINARY));                             // Not equals
            operators.Add("≠", new Operator("≠", 3, Arity.BINARY));                               // Not equals
            operators.Add("!", new Operator("!", 6, Arity.UNARY));                                // Boolean not
            operators.Add("¬", new Operator("¬", 6, Arity.UNARY));                                // Boolean not
            operators.Add("and", new Operator("and", 2, Arity.BINARY));                           // AND
            operators.Add("∧", new Operator("∧", 2, Arity.BINARY));                               // AND
            operators.Add("or", new Operator("or", 2, Arity.BINARY));                             // OR
            operators.Add("∨", new Operator("∨", 2, Arity.BINARY));                               // OR
            operators.Add("buildin-function", new Operator("buildin-function", 5, Arity.BINARY)); // Execute buildin function as unary operator
            operators.Add("user-function", new Operator("user-function", 5, Arity.BINARY));       // Execute user function as unary operator

            buildInFunctions = new Dictionary <string, BuildInFunction>();
            buildInFunctions.Add("abs", new BuildInFunction("abs", 1));
            buildInFunctions.Add("acos", new BuildInFunction("acos", 1));
            buildInFunctions.Add("acos_rad", new BuildInFunction("acos_rad", 1));
            buildInFunctions.Add("asin", new BuildInFunction("asin", 1));
            buildInFunctions.Add("asin_rad", new BuildInFunction("asin_rad", 1));
            buildInFunctions.Add("atan", new BuildInFunction("atan", 1));
            buildInFunctions.Add("atan_rad", new BuildInFunction("atan_rad", 1));
            buildInFunctions.Add("atan2", new BuildInFunction("atan2", 2));
            buildInFunctions.Add("atan2_rad", new BuildInFunction("atan2_rad", 2));
            buildInFunctions.Add("ceil", new BuildInFunction("ceil", 1));
            buildInFunctions.Add("cos", new BuildInFunction("cos", 1));
            buildInFunctions.Add("cos_rad", new BuildInFunction("cos_rad", 1));
            buildInFunctions.Add("cosh", new BuildInFunction("cosh", 1));
            buildInFunctions.Add("cosh_rad", new BuildInFunction("cosh_rad", 1));
            buildInFunctions.Add("exp", new BuildInFunction("exp", 1));
            buildInFunctions.Add("floor", new BuildInFunction("floor", 1));
            buildInFunctions.Add("ln", new BuildInFunction("ln", 1));
            buildInFunctions.Add("log", new BuildInFunction("log", 1));
            buildInFunctions.Add("log10", new BuildInFunction("log10", 1));
            buildInFunctions.Add("max", new BuildInFunction("max", 2));
            buildInFunctions.Add("min", new BuildInFunction("min", 2));
            buildInFunctions.Add("pow", new BuildInFunction("pow", 2));
            buildInFunctions.Add("rand", new BuildInFunction("rand", 0));
            buildInFunctions.Add("round", new BuildInFunction("round", 2));
            buildInFunctions.Add("sign", new BuildInFunction("sign", 1));
            buildInFunctions.Add("sin", new BuildInFunction("sin", 1));
            buildInFunctions.Add("sin_rad", new BuildInFunction("sin_rad", 1));
            buildInFunctions.Add("sinh", new BuildInFunction("sinh", 1));
            buildInFunctions.Add("sinh_rad", new BuildInFunction("sinh_rad", 1));
            buildInFunctions.Add("sqrt", new BuildInFunction("sqrt", 1));
            buildInFunctions.Add("tan", new BuildInFunction("tan", 1));
            buildInFunctions.Add("tan_rad", new BuildInFunction("tan_rad", 1));
            buildInFunctions.Add("tanh", new BuildInFunction("tanh", 1));
            buildInFunctions.Add("tanh_rad", new BuildInFunction("tanh_rad", 1));
            buildInFunctions.Add("len", new BuildInFunction("len", 1));
            buildInFunctions.Add("mag", new BuildInFunction("mag", 1));
            buildInFunctions.Add("norm", new BuildInFunction("norm", 1));
            buildInFunctions.Add("dot", new BuildInFunction("dot", 2));
            buildInFunctions.Add("cross", new BuildInFunction("cross", 2));
            buildInFunctions.Add("all", new BuildInFunction("all", 1));
            buildInFunctions.Add("any", new BuildInFunction("any", 1));

            globals = new Dictionary <string, Object>();
            globals.Add("pi", Math.PI);
            globals.Add("π", Math.PI);
            globals.Add("e", Math.E);
            globals.Add("G", 6.67408E-11);
            globals.Add("Inf", double.PositiveInfinity);
            globals.Add("∞", double.PositiveInfinity);

            functions = new SortedDictionary <string, JITFunction>();
            JITFunction.Scan(functionDir, this);
        }
Пример #13
0
        public static void Scan(string dir, Kerbulator kalc)
        {
            // This function is called pretty often, so I went through some lengths to ensure that only new or updated functions are compiled.
            List <string> files             = new List <string>(Directory.GetFiles(dir, "*.math"));
            List <string> compiledFunctions = new List <string>(kalc.Functions.Keys);

            files.Sort();
            compiledFunctions.Sort();

            int i = 0;
            int j = 0;

            while (i < files.Count || j < compiledFunctions.Count)
            {
                if (i >= files.Count)
                {
                    // Deleted function
                    kalc.Functions.Remove(compiledFunctions[j]);
                    j++;
                }

                else if (j >= compiledFunctions.Count)
                {
                    // Added function
                    JITFunction f = FromFile(files[i], kalc);
                    kalc.Functions[f.Id] = f;
                    i++;
                }

                else if (string.Compare(Path.GetFileNameWithoutExtension(files[i]), compiledFunctions[j]) == 1)
                {
                    // Deleted function
                    kalc.Functions.Remove(compiledFunctions[j]);
                    i++;
                }

                else if (string.Compare(Path.GetFileNameWithoutExtension(files[i]), compiledFunctions[j]) == -1)
                {
                    // Added function
                    JITFunction f = FromFile(files[i], kalc);
                    kalc.Functions[f.Id] = f;
                    j++;
                }

                else
                {
                    // Function already exists
                    // Reload only if file is newer
                    DateTime dt = File.GetLastWriteTime(files[i]);
                    if (dt > lastScan)
                    {
                        JITFunction f = FromFile(files[i], kalc);
                        kalc.Functions[f.Id] = f;
                    }

                    i++; j++;
                }
            }

            foreach (JITFunction f in kalc.Functions.Values)
            {
                f.Compile();
            }

            lastScan = DateTime.Now;
        }
Пример #14
0
        public Kerbulator(string functionDir)
        {
            operators = new Dictionary <string, Operator>();
            operators.Add("=", new Operator("=", 1, Arity.BINARY));                               // Assignment
            operators.Add("-", new Operator("-", 1, Arity.BOTH));                                 // Substraction or negation
            operators.Add("+", new Operator("+", 1, Arity.BINARY));                               // Addition
            operators.Add("/", new Operator("/", 2, Arity.BINARY));                               // Division
            operators.Add("÷", new Operator("÷", 2, Arity.BINARY));                               // Division
            operators.Add("√", new Operator("√", 2, Arity.BOTH));                                 // Square Root or ^(1/n)
            operators.Add("%", new Operator("%", 2, Arity.BINARY));                               // Modulo
            operators.Add("*", new Operator("*", 2, Arity.BINARY));                               // Multiplication
            operators.Add("·", new Operator("·", 2, Arity.BINARY));                               // Multiplication
            operators.Add("×", new Operator("×", 2, Arity.BINARY));                               // Multiplication
            operators.Add("^", new Operator("^", 3, Arity.BINARY));                               // Multiplication
            operators.Add("|", new Operator("|", 3, Arity.UNARY));                                // Absolute
            operators.Add("⌊", new Operator("⌊", 3, Arity.UNARY));                                // Floor
            operators.Add("⌈", new Operator("⌈", 3, Arity.UNARY));                                // Ceiling
            operators.Add("func", new Operator("func", 2, Arity.BINARY));                         // Execute buildin function as unary operator
            operators.Add("buildin-function", new Operator("buildin-function", 2, Arity.BINARY)); // Execute buildin function as unary operator
            operators.Add("user-function", new Operator("user-function", 2, Arity.BINARY));       // Execute user function as unary operator

            buildInFunctions = new Dictionary <string, BuildInFunction>();
            buildInFunctions.Add("abs", new BuildInFunction("abs", 1));
            buildInFunctions.Add("acos", new BuildInFunction("acos", 1));
            buildInFunctions.Add("acos_rad", new BuildInFunction("acos_rad", 1));
            buildInFunctions.Add("asin", new BuildInFunction("asin", 1));
            buildInFunctions.Add("asin_rad", new BuildInFunction("asin_rad", 1));
            buildInFunctions.Add("atan", new BuildInFunction("atan", 1));
            buildInFunctions.Add("atan_rad", new BuildInFunction("atan_rad", 1));
            buildInFunctions.Add("ceil", new BuildInFunction("ceil", 1));
            buildInFunctions.Add("cos", new BuildInFunction("cos", 1));
            buildInFunctions.Add("cos_rad", new BuildInFunction("cos_rad", 1));
            buildInFunctions.Add("cosh", new BuildInFunction("cosh", 1));
            buildInFunctions.Add("cosh_rad", new BuildInFunction("cosh_rad", 1));
            buildInFunctions.Add("exp", new BuildInFunction("exp", 1));
            buildInFunctions.Add("floor", new BuildInFunction("floor", 1));
            buildInFunctions.Add("ln", new BuildInFunction("ln", 1));
            buildInFunctions.Add("log", new BuildInFunction("log", 1));
            buildInFunctions.Add("log10", new BuildInFunction("log10", 1));
            buildInFunctions.Add("max", new BuildInFunction("max", 2));
            buildInFunctions.Add("min", new BuildInFunction("min", 2));
            buildInFunctions.Add("pow", new BuildInFunction("pow", 2));
            buildInFunctions.Add("rand", new BuildInFunction("rand", 0));
            buildInFunctions.Add("round", new BuildInFunction("round", 2));
            buildInFunctions.Add("sign", new BuildInFunction("sign", 1));
            buildInFunctions.Add("sin", new BuildInFunction("sin", 1));
            buildInFunctions.Add("sin_rad", new BuildInFunction("sin_rad", 1));
            buildInFunctions.Add("sinh", new BuildInFunction("sinh", 1));
            buildInFunctions.Add("sinh_rad", new BuildInFunction("sinh_rad", 1));
            buildInFunctions.Add("sqrt", new BuildInFunction("sqrt", 1));
            buildInFunctions.Add("tan", new BuildInFunction("tan", 1));
            buildInFunctions.Add("tan_rad", new BuildInFunction("tan_rad", 1));
            buildInFunctions.Add("tanh", new BuildInFunction("tanh", 1));
            buildInFunctions.Add("tanh_rad", new BuildInFunction("tanh_rad", 1));
            buildInFunctions.Add("len", new BuildInFunction("len", 1));
            buildInFunctions.Add("mag", new BuildInFunction("mag", 1));
            buildInFunctions.Add("norm", new BuildInFunction("norm", 1));
            buildInFunctions.Add("dot", new BuildInFunction("dot", 2));
            buildInFunctions.Add("cross", new BuildInFunction("cross", 2));

            globals = new Dictionary <string, Object>();
            globals.Add("pi", Math.PI);
            globals.Add("π", Math.PI);
            globals.Add("e", Math.E);
            globals.Add("G", 6.67384E-11);

            functions = new SortedDictionary <string, JITFunction>();
            JITFunction.Scan(functionDir, this);
        }
Пример #15
0
 public ExecutionEnvironment(JITFunction func, Kerbulator kalc)
 {
     this.func        = func;
     this.kalc        = kalc;
     inputExpressions = new List <JITExpression>(func.Ins.Count);
 }
Пример #16
0
        private void ParseIdentifier(Stack <Expression> expr, Stack <Operator> ops)
        {
            Token t = tokens.Dequeue();

            if (kalc.Functions.ContainsKey(t.val))
            {
                // User function call
                JITFunction f = kalc.Functions[t.val];
                if (tokens.Count > 0 && tokens.Peek().val == "(")
                {
                    // Parameter list supplied, execute function now
                    List <Expression> args = ParseArgumentList();
                    expr.Push(ParseUserFunction(t.val, args, t.pos));
                }
                else if (f.Ins.Count == 0)
                {
                    // Function takes no arguments, execute now
                    expr.Push(ParseUserFunction(t.val, new List <Expression>(), t.pos));
                }
                else
                {
                    // Do function call later, when parameters are known
                    ops.Push(kalc.Operators["user-function"]);
                    expr.Push(Expression.Constant(t.val));
                }
            }
            else if (kalc.BuildInFunctions.ContainsKey(t.val))
            {
                BuildInFunction f = kalc.BuildInFunctions[t.val];

                if (tokens.Count > 0 && tokens.Peek().val == "(")
                {
                    // Parameter list supplied, execute function now
                    List <Expression> args = ParseArgumentList();
                    if (args.Count != f.numArgs)
                    {
                        throw new Exception(t.pos + "function " + f + " takes " + f.numArgs + " arguments, but " + args.Count + " were supplied");
                    }
                    expr.Push(ParseBuildInFunction(f, args, t.pos));
                }
                else if (f.numArgs == 0)
                {
                    // Function takes no arguments, execute now
                    expr.Push(ParseBuildInFunction(f, new List <Expression>(), t.pos));
                }
                else
                {
                    // Do function call later, when parameters are known
                    ops.Push(kalc.Operators["buildin-function"]);
                    expr.Push(Expression.Constant(t.val));
                }
            }
            else
            {
                // Variable identifier
                if (tokens.Count > 0 && tokens.Peek().val == "(")
                {
                    // Parameter list supplied, but function doesn't exist
                    throw new Exception(t.pos + "function " + t.val + " does not exist");
                }

                expr.Push(
                    Expression.Call(
                        thisExpression,
                        typeof(JITFunction).GetMethod("GetVar"),
                        Expression.Constant(t.val),
                        Expression.Constant(t.pos)
                        )
                    );
            }
        }
Пример #17
0
        /// <summary>Draws the GUI</summary>
        public void OnGUI()
        {
            // Initiate styles
            if (!stylesInitiated)
            {
                keyboard         = new GUIStyle(GUI.skin.GetStyle("button"));
                keyboard.padding = new RectOffset(0, 0, 2, 2);

                defaultButton         = new GUIStyle(GUI.skin.GetStyle("button"));
                defaultButton.padding = new RectOffset(4, 4, 4, 4);

                tooltipStyle = new GUIStyle(GUI.skin.GetStyle("label"));
                Texture2D texBack = new Texture2D(1, 1, TextureFormat.ARGB32, false);
                texBack.SetPixel(0, 0, new Color(0.0f, 0.0f, 0.0f, 1f));
                texBack.Apply();
                tooltipStyle.normal.background = texBack;

                validFunctionName   = new GUIStyle(GUI.skin.GetStyle("TextField"));
                editFunctionStyle   = validFunctionName;
                invalidFunctionName = new GUIStyle(GUI.skin.GetStyle("TextField"));
                invalidFunctionName.normal.textColor  = Color.red;
                invalidFunctionName.active.textColor  = Color.red;
                invalidFunctionName.hover.textColor   = Color.red;
                invalidFunctionName.focused.textColor = Color.red;

                stylesInitiated = true;
            }

            if (drawMainButton)
            {
                // Draw the main button
                if (GUI.Button(mainButtonPos, kerbulatorIcon, defaultButton))
                {
                    ChangeState(!mainWindowEnabled);
                }
            }

            if (reload)
            {
                reload = false;

                // Rebuild the list of functions. It could be that they were edited outside of KSP
                JITFunction.Scan(functionDir, kalc);

                // Reload the function being edited
                if (editFunction != null)
                {
                    editFunctionContent = System.IO.File.ReadAllText(functionFile);
                }
            }

            // Draw the windows (if enabled)
            if (mainWindowEnabled)
            {
                options.mainWindowPos = GUI.Window(windowId, options.mainWindowPos, DrawMainWindow, "Kerbulator");
                glue.PreventClickthrough(options.mainWindowPos, "KerbulatorMainWindow");
            }
            else
            {
                glue.EnsureLockReleased("KerbulatorMainWindow");
            }

            if (editWindowEnabled)
            {
                options.editWindowPos = GUI.Window(windowId + 1, options.editWindowPos, DrawEditWindow, "Function Editor");
                glue.PreventClickthrough(options.editWindowPos, "KerbulatorEditWindow");
            }
            else
            {
                glue.EnsureLockReleased("KerbulatorEditWindow");
            }

            if (runWindowEnabled)
            {
                options.runWindowPos = GUI.Window(windowId + 2, options.runWindowPos, DrawRunWindow, "Run " + RunFunction.Id);
                glue.PreventClickthrough(options.runWindowPos, "KerbulatorRunWindow");
            }
            else
            {
                glue.EnsureLockReleased("KerbulatorRunWindow");
            }

            if (running)
            {
                foreach (KeyValuePair <int, ExecutionEnvironment> pair in envs)
                {
                    pair.Value.windowPos = GUI.Window(pair.Key, pair.Value.windowPos, DrawRepeatedWindow, pair.Value.func.Id);
                    glue.PreventClickthrough(pair.Value.windowPos, "KerbulatorEnvironment" + pair.Value.func.Id);
                }
            }

            DrawToolTip();
        }
Пример #18
0
        /// <summary>Draws the main window that displays a list of available functions</summary>
        /// <param name="id">An unique number indentifying the window</param>
        public void DrawMainWindow(int id)
        {
            // Close button at the top right corner
            if (drawMainButton)
            {
                ChangeState(!GUI.Toggle(new Rect(options.mainWindowPos.width - 25, 0, 20, 20), !mainWindowEnabled, ""));
            }

            if (error != null)
            {
                GUILayout.Label(error);
            }

            GUILayout.Label("Available functions:");

            mainScrollPos = GUILayout.BeginScrollView(mainScrollPos, false, true, GUILayout.Height(options.mainWindowPos.height - 110));

            bool runSomething = false;

            foreach (KeyValuePair <string, JITFunction> f in kalc.Functions)
            {
                GUILayout.BeginHorizontal();

                if (GUILayout.Button(f.Key, GUILayout.Height(24)))
                {
                    selectedFunction          = f.Value;
                    functionDescription       = FunctionDescription(f.Value);
                    functionDescriptionHeight = GUI.skin.GetStyle("label").CalcHeight(new GUIContent(functionDescription), 225);
                }

                if (GUILayout.Button(editIcon, defaultButton, GUILayout.Width(24), GUILayout.Height(24)))
                {
                    // Load the function to be edited
                    editFunction        = f.Value;
                    functionFile        = functionDir + "/" + f.Key + ".math";
                    editFunctionName    = f.Key;
                    editFunctionContent = System.IO.File.ReadAllText(functionFile);
                    editWindowEnabled   = true;
                }

                if (GUILayout.Button(runIcon, defaultButton, GUILayout.Width(24), GUILayout.Height(24)))
                {
                    // Load the function to be run
                    RunFunction      = f.Value;
                    runWindowEnabled = true;

                    // Run it, but only after this loop finishes.
                    // Run() calls Scan(), which updates the dictionary we're currently
                    // enumerating over, which is not allowed.
                    runSomething = true;
                }

                GUILayout.EndHorizontal();

                // When a function is selected, display some info
                if (selectedFunction == f.Value)
                {
                    GUILayout.Label("Function info:");
                    GUILayout.Label(functionDescription, GUILayout.Width(225), GUILayout.Height(functionDescriptionHeight));
                }
            }

            GUILayout.EndScrollView();

            GUILayout.Space(20);

            GUILayout.BeginHorizontal();
            if (GUILayout.Button("New function"))
            {
                editFunction = null;

                // Load template for an empty function
                functionFile        = functionDir + "/unnamed.math";
                editFunctionName    = "unnamed";
                editFunctionContent = "";
                editWindowEnabled   = true;
            }

            if (GUILayout.Button("New maneuver"))
            {
                editFunction = null;

                // Load template for a function controlling a maneuver node
                functionFile        = functionDir + "/maneuver.math";
                editFunctionName    = "maneuver";
                editFunctionContent = maneuverTemplate;
                editWindowEnabled   = true;
            }

            GUILayout.EndHorizontal();

            options.mainWindowPos = ResizeWindow(id, options.mainWindowPos, minMainWindowSize);
            GUI.DragWindow(titleBarRect);

            if (Event.current.type == EventType.Repaint)
            {
                tooltip = GUI.tooltip;
            }

            // Run button was pressed, run the function
            if (runSomething)
            {
                Run();
                functionOutput = FormatOutput(env);
                GUI.FocusWindow(windowId + 2);
                runSomething = false;
            }
        }
Пример #19
0
        /// <summary>Draws the GUI</summary>
        public void OnGUI()
        {
            // Initiate styles
            if (!stylesInitiated)
            {
                keyboard         = new GUIStyle(GUI.skin.GetStyle("button"));
                keyboard.padding = new RectOffset(0, 0, 2, 2);

                defaultButton         = new GUIStyle(GUI.skin.GetStyle("button"));
                defaultButton.padding = new RectOffset(4, 4, 4, 4);

                tooltipStyle = new GUIStyle(GUI.skin.GetStyle("label"));
                Texture2D texBack = new Texture2D(1, 1, TextureFormat.ARGB32, false);
                texBack.SetPixel(0, 0, new Color(0.0f, 0.0f, 0.0f, 1f));
                texBack.Apply();
                tooltipStyle.normal.background = texBack;

                stylesInitiated = true;
            }

            if (drawMainButton)
            {
                // Draw the main button
                if (GUI.Button(mainButtonPos, kerbulatorIcon, defaultButton))
                {
                    ChangeState(!mainWindowEnabled);
                }
            }

            if (reload)
            {
                reload = false;

                // Rebuild the list of functions. It could be that they were edited outside of KSP
                JITFunction.Scan(functionDir, kalc);

                // Reload the function being edited
                if (editFunction != null)
                {
                    editFunctionContent = System.IO.File.ReadAllText(functionFile);
                }
            }


            // Draw the windows (if enabled)
            if (mainWindowEnabled)
            {
                mainWindowPos = GUILayout.Window(windowId, mainWindowPos, DrawMainWindow, "Kerbulator", GUILayout.ExpandHeight(false));
            }

            if (editWindowEnabled)
            {
                editWindowPos = GUILayout.Window(windowId + 1, editWindowPos, DrawEditWindow, "Function Editor", GUILayout.ExpandHeight(false));
            }

            if (runWindowEnabled)
            {
                runWindowPos = GUILayout.Window(windowId + 2, runWindowPos, DrawRunWindow, "Run " + RunFunction.Id, GUILayout.ExpandHeight(false));
            }

            if (running)
            {
                foreach (KeyValuePair <int, ExecutionEnvironment> pair in envs)
                {
                    pair.Value.windowPos = GUILayout.Window(pair.Key, pair.Value.windowPos, DrawRepeatedWindow, pair.Value.func.Id, GUILayout.ExpandHeight(false));
                }
            }

            DrawToolTip();
        }