Esempio n. 1
0
        public KerbulatorGUI(IGlue glue, bool inEditor, bool drawMainButton, KerbulatorOptions options)
        {
            this.glue           = glue;
            this.inEditor       = inEditor;
            this.drawMainButton = drawMainButton;
            this.options        = options;
            ChangeState(false);

            // Use the game base directory + PluginData as base folder for plugin data
            functionDir = glue.GetFunctionDir();
            functionDir = functionDir.Replace("\\", "/");

            Debug.Log("Kerbulator function dir: " + functionDir);

            editFunctionContent = maneuverTemplate;

            if (!Directory.Exists(functionDir))
            {
                Directory.CreateDirectory(functionDir);
            }

            // Load icons
            kerbulatorIcon = glue.GetTexture("kerbulator");
            editIcon       = glue.GetTexture("edit");
            runIcon        = glue.GetTexture("run");
            repeatIcon     = glue.GetTexture("repeat");
            nodeIcon       = glue.GetTexture("node");
            alarmIcon      = glue.GetTexture("alarm");
            saveIcon       = glue.GetTexture("save");
            deleteIcon     = glue.GetTexture("delete");

            kalc = new Kerbulator(functionDir);
        }
Esempio n. 2
0
        // UNITY
        public static void AddOrbit(Kerbulator kalc, Orbit orbit, string prefix)
        {
            if (orbit == null)
            {
                return;
            }

            AddDouble(kalc, prefix + ".Ap", (double)orbit.ApA);
            AddDouble(kalc, prefix + ".Pe", (double)orbit.PeA);
            AddDouble(kalc, prefix + ".Inc", (double)orbit.inclination);
            AddDouble(kalc, prefix + ".Alt", (double)orbit.altitude);
            AddDouble(kalc, prefix + ".ArgPe", (double)orbit.argumentOfPeriapsis);
            AddDouble(kalc, prefix + ".ω", (double)orbit.argumentOfPeriapsis);
            AddDouble(kalc, prefix + ".LAN", (double)orbit.LAN);
            AddDouble(kalc, prefix + ".Ω", (double)orbit.LAN);
            AddDouble(kalc, prefix + ".TimeToAp", (double)orbit.timeToAp);
            AddDouble(kalc, prefix + ".TimeToPe", (double)orbit.timeToPe);
            AddDouble(kalc, prefix + ".Vel", (double)orbit.vel.magnitude);
            AddDouble(kalc, prefix + ".TrueAnomaly", (double)orbit.trueAnomaly);
            AddDouble(kalc, prefix + ".θ", (double)orbit.trueAnomaly);

            if (orbit.UTsoi > 0)
            {
                AddDouble(kalc, prefix + ".SOI.dt", (double)orbit.UTsoi - Planetarium.GetUniversalTime());
                AddDouble(kalc, prefix + ".SOI.Δt", (double)orbit.UTsoi - Planetarium.GetUniversalTime());
                AddDouble(kalc, prefix + ".SOI.TrueAnomaly", (double)orbit.TrueAnomalyAtUT(orbit.UTsoi));
                AddDouble(kalc, prefix + ".SOI.θ", (double)orbit.TrueAnomalyAtUT(orbit.UTsoi));
            }
        }
Esempio n. 3
0
        public static void AddCelestialBody(Kerbulator kalc, CelestialBody body, string prefix)
        {
            if (body == null)
            {
                return;
            }

            try {
                if (body.orbit != null)
                {
                    AddOrbit(kalc, body.orbit, prefix);
                }
            } catch (Exception) {
                // Somehow, testing body.orbit != null is not enough. I don't know why...
                // Leave a pull request or file an issue if you can help me figure this out!
            }

            AddDouble(kalc, prefix + ".R", (double)body.Radius);
            AddDouble(kalc, prefix + ".M", (double)body.Mass);
            AddDouble(kalc, prefix + ".mu", (double)body.gravParameter);
            AddDouble(kalc, prefix + ".μ", (double)body.gravParameter);
            AddDouble(kalc, prefix + ".µ", (double)body.gravParameter);
            AddDouble(kalc, prefix + ".day", (double)body.rotationPeriod);
            AddDouble(kalc, prefix + ".SOI", (double)body.sphereOfInfluence);
            AddDouble(kalc, prefix + ".AtmosHeight", (double)body.maxAtmosphereAltitude);
            AddDouble(kalc, prefix + ".AtmosPress", (double)body.atmosphereMultiplier * 101325.0);
        }
Esempio n. 4
0
        private void HandleToken(Token t)
        {
            switch (t.type)
            {
            case TokenType.EMPTY:
                return;

            // Some identifiers are special
            case TokenType.IDENTIFIER:
                // These are actually operators
                if (t.val == "and" || t.val == "or")
                {
                    t.type = TokenType.OPERATOR;
                }

                // These are actually conditionals
                else if (t.val == "if" || t.val == "otherwise")
                {
                    t.type = TokenType.CONDITIONAL;
                }
                break;
            }

            Kerbulator.Debug(" " + t.ToString());
            tokens.Enqueue(t);
        }
Esempio n. 5
0
        public JITExpression(string expression, Kerbulator kalc)
            : base("unnamed", expression, kalc)
        {
            Expression <Func <Object> > e = Expression.Lambda <Func <Object> >(ParseExpression());

            expressionFunction = e.Compile();
        }
Esempio n. 6
0
        private bool PossiblyValidExpression(Stack <Expression> expr, Stack <Operator> ops)
        {
            if (expr.Count == 0 && ops.Count == 0)
            {
                return(false);
            }

            int required = 0;
            int supplied = expr.Count;

            foreach (Operator op in ops)
            {
                Kerbulator.DebugLine(op.id);
                supplied++;
                if (op.arity == Arity.BINARY)
                {
                    required += 2;
                }
                else
                {
                    required += 1;
                }
            }

            Kerbulator.DebugLine("required: " + required + ", supplied: " + supplied);
            return(supplied == required + 1);
        }
Esempio n. 7
0
 private void PrintVertices(double[][] sim, double[] fsim)
 {
     Kerbulator.DebugLine("Verts:");
     for (int i = 0; i < sim.Length; i++)
     {
         Kerbulator.Debug("\t" + i + ": " + PrintVert(sim[i]) + " = " + fsim[i] + "\n");
     }
 }
Esempio n. 8
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);
        }
Esempio n. 9
0
 public static void AddDouble(Kerbulator kalc, string id, double v)
 {
     if (kalc.Globals.ContainsKey(id))
     {
         kalc.Globals[id] = (System.Object)v;
     }
     else
     {
         kalc.Globals.Add(id, (System.Object)v);
     }
 }
Esempio n. 10
0
        private void ParseNumber(Stack <Expression> expr)
        {
            Token t = tokens.Dequeue();

            Kerbulator.DebugLine("Pushing " + t.val);
            expr.Push(
                Expression.Convert(
                    Expression.Constant(Double.Parse(t.val, System.Globalization.CultureInfo.InvariantCulture)),
                    typeof(Object)
                    )
                );
        }
Esempio n. 11
0
        private void HandleToken(Token t)
        {
            switch (t.type)
            {
            case TokenType.EMPTY:
                break;

            default:
                Kerbulator.Debug(" " + t.ToString());
                tokens.Enqueue(t);
                break;
            }
        }
Esempio n. 12
0
        /// <summary>Provide a string representation of the output resulting from executing a function.</summary>
        public string FormatOutput(ExecutionEnvironment env)
        {
            if (env == null)
            {
                return("");
            }

            if (env.InError)
            {
                return("ERROR: " + env.ErrorString);
            }

            if (env.Output == null)
            {
                return("");
            }

            if (env.Output.Count == 0)
            {
                return("None.");
            }

            if (env.Output.Count != env.func.Outs.Count)
            {
                return("None.");
            }

            string desc = "";

            for (int i = 0; i < env.Output.Count; i++)
            {
                if (i < env.func.OutputTypes.Count)
                {
                    if (env.func.OutputTypes[i] == OutputType.Value)
                    {
                        desc += env.func.OutPrefixes[i] + Kerbulator.FormatVar(env.Output[i]) + env.func.OutPostfixes[i] + "\n";
                    }
                }
                else
                {
                    desc += env.func.OutPrefixes[i] + Kerbulator.FormatVar(env.Output[i]) + env.func.OutPostfixes[i] + "\n";
                }
            }


            return(desc);
        }
Esempio n. 13
0
        private void SortVertices(double[][] sim, double[] fsim)
        {
            int[] ind = Enumerable.Range(0, sim.Length).ToArray();
            Array.Sort(fsim, ind);
            Kerbulator.DebugLine("Sorted idx:" + PrintVert(ind));

            double[][] sim2 = new double[sim.Length][];
            for (int i = 0; i < sim.Length; i++)
            {
                sim2[i] = sim[ind[i]];
            }

            for (int i = 0; i < sim.Length; i++)
            {
                sim[i] = sim2[i];
            }
        }
Esempio n. 14
0
        private void ParseOperator(Stack <Expression> expr, Stack <Operator> ops)
        {
            Token t = tokens.Dequeue();

            if (!kalc.Operators.ContainsKey(t.val))
            {
                throw new Exception(t.pos + " unknown operator: " + t.val);
            }

            Operator op = kalc.Operators[t.val];

            // Handle ambiguous cases of arity
            if (op.arity == Arity.BOTH)
            {
                if (PossiblyValidExpression(expr, ops))
                {
                    op = new Operator(op.id, op.precidence, Arity.BINARY);
                    Kerbulator.DebugLine(op.id + " is binary.");
                }
                else
                {
                    op = new Operator(op.id, 3, Arity.UNARY);
                    Kerbulator.DebugLine(op.id + " is unary.");
                }
            }

            // Handle operators with higher precidence
            while (ops.Count > 0)
            {
                Operator prevOp = ops.Peek();

                if (op.arity != Arity.BINARY || prevOp.precidence < op.precidence)
                {
                    // Leave for later
                    break;
                }
                else
                {
                    expr.Push(ExecuteOperator(ops.Pop(), expr, ops, t.pos));
                }
            }

            // Push current operator on the stack
            Kerbulator.DebugLine("Pushing " + op.id);
            ops.Push(op);
        }
Esempio n. 15
0
        public static Object Any(Object a, string pos)
        {
            Kerbulator.DebugLine("Executing any()");
            if(a.GetType() != typeof(Object[]))
                throw new Exception(pos +"function any() can only be called with a list as argument");

            Object[] listA = (Object[]) a;

            double result = 0.0;
            for(int i=0; i<listA.Length; i++) {
                if(listA[i].GetType() != typeof(double))
                    throw new Exception(pos +"argument to function any() must be a list that contains only numbers");
                if(((double) listA[i]) != 0)
                    result = 1.0;
            }

            return (Object) result;
        }
Esempio n. 16
0
        public bool ParseList(Stack <Expression> expr)
        {
            if (tokens.Peek().val == "]")
            {
                return(true);
            }

            // Consume left brace
            Token t = Consume();

            List <Expression> elements = new List <Expression>();

            while (tokens.Peek().val != "]")
            {
                t = tokens.Peek();
                Kerbulator.DebugLine("Starting subexpression");
                Expression subexpr = ParseExpression();
                Kerbulator.DebugLine("End of subexpression");
                elements.Add(subexpr);

                if (tokens.Count == 0)
                {
                    throw new Exception(t.pos + "missing closing ']'");
                }

                if (tokens.Peek().val != "]")
                {
                    Consume(TokenType.COMMA);
                }
            }

            // Consume right brace
            Consume();

            if (elements.Count == 0)
            {
                throw new Exception(t.pos + "Empty lists are not allowed.");
            }

            expr.Push(Expression.NewArrayInit(typeof(Object), elements));
            return(false);
        }
Esempio n. 17
0
        public KerbulatorGUI(IGlue glue, bool inEditor, bool drawMainButton)
        {
            this.glue           = glue;
            this.inEditor       = inEditor;
            this.drawMainButton = drawMainButton;
            ChangeState(false);

            functionDir = Application.persistentDataPath + "/Kerbulator";

            // Sometimes, Application.persistentDataPath returns an empty string.
            // To not completely crash, create a KerbulatorFunctions directory in the users home dir
            if (functionDir == "/Kerbulator")
            {
                string homePath =
                    (Environment.OSVersion.Platform == PlatformID.Unix ||
                     Environment.OSVersion.Platform == PlatformID.MacOSX)
                                         ? Environment.GetEnvironmentVariable("HOME")
                                         : Environment.ExpandEnvironmentVariables("%HOMEDRIVE%%HOMEPATH%");
                functionDir = homePath + "/KerbulatorFunctions";
            }

            Debug.Log("Kerbulator function dir: " + functionDir);

            editFunctionContent = maneuverTemplate;

            if (!Directory.Exists(functionDir))
            {
                Directory.CreateDirectory(functionDir);
            }

            // Load icons
            kerbulatorIcon = glue.GetTexture("kerbulator");
            editIcon       = glue.GetTexture("edit");
            runIcon        = glue.GetTexture("run");
            repeatIcon     = glue.GetTexture("repeat");
            nodeIcon       = glue.GetTexture("node");
            saveIcon       = glue.GetTexture("save");
            deleteIcon     = glue.GetTexture("delete");

            kalc = new Kerbulator(functionDir);
        }
Esempio n. 18
0
        /// <summary>Provide a string representation of the output resulting from executing a function.</summary>
        /// <param name="f">The function that was executed</param>
        /// <param name="output">The variables resuting from the execution</param>
        public string FormatOutput(ExecutionEnvironment env)
        {
            if (env == null)
            {
                return("");
            }

            if (env.InError)
            {
                return("ERROR: " + env.ErrorString);
            }

            if (env.Output == null)
            {
                return("");
            }

            string desc = "";

            if (env.Output.Count == 0)
            {
                desc += "None.";
            }
            else
            {
                for (int i = 0; i < env.Output.Count - 1; i++)
                {
                    desc += env.func.Outs[i] + " = " + Kerbulator.FormatVar(env.Output[i]) + "\n";
                }
                if (env.Output.Count > 0)
                {
                    desc += env.func.Outs[env.func.Outs.Count - 1] + " = " + Kerbulator.FormatVar(env.Output[env.Output.Count - 1]);
                }
            }

            return(desc);
        }
Esempio n. 19
0
        public JITFunction(string id, string expression, Kerbulator kalc)
        {
            this.id = id;

            this.ins             = new List <string>();
            this.outs            = new List <string>();
            this.inDescriptions  = new List <string>();
            this.outDescriptions = new List <string>();

            this.locals         = new Dictionary <string, Object>();
            this.thisExpression = Expression.Constant(this);

            this.kalc = kalc;
            this.solv = new Solver(this);

            try {
                Tokenizer tok = new Tokenizer(id);
                tok.Tokenize(expression);
                tokens = tok.tokens;
            } catch (Exception e) {
                inError = true;
                error   = e;
            }
        }
Esempio n. 20
0
        public void Compile()
        {
            if (compiledFunction != null)
            {
                return;                 // Already compiled
            }
            try {
                // Skip leading whitespace
                while (tokens.Count > 0 && tokens.Peek().type == TokenType.END)
                {
                    Consume();
                }

                // Parse in: statements
                while (tokens.Count > 0 && tokens.Peek().type == TokenType.IN)
                {
                    Consume();
                    Token id = Consume(TokenType.IDENTIFIER);

                    if (tokens.Count > 0 && tokens.Peek().type == TokenType.TEXT)
                    {
                        inDescriptions.Add(tokens.Dequeue().val);
                    }

                    Consume(TokenType.END);
                    ins.Add(id.val);
                    Kerbulator.DebugLine("Found IN statement for " + id.val);
                }

                // Skip whitespace
                while (tokens.Count > 0 && tokens.Peek().type == TokenType.END)
                {
                    Consume();
                }

                // Parse out: statements
                while (tokens.Count > 0 && tokens.Peek().type == TokenType.OUT)
                {
                    Consume();
                    Token id = Consume(TokenType.IDENTIFIER);

                    if (tokens.Count > 0 && tokens.Peek().type == TokenType.TEXT)
                    {
                        outDescriptions.Add(tokens.Dequeue().val);
                    }
                    else
                    {
                        outDescriptions.Add("");
                    }

                    Consume(TokenType.END);
                    outs.Add(id.val);
                    Kerbulator.DebugLine("Found OUT statement for " + id.val);
                }

                Kerbulator.DebugLine("");

                // Parse all other statements
                List <Expression> statements = new List <Expression>();
                while (tokens.Count > 0)
                {
                    Expression statement = ParseStatement();
                    if (statement != null)
                    {
                        statements.Add(statement);
                    }
                    Consume(TokenType.END);
                }

                if (statements.Count == 0)
                {
                    throw new Exception("In function " + this.id + ": function does not contain any statements (it's empty)");
                }

                // If no outputs are given, take last assigned variables as output
                if (outs.Count == 0)
                {
                    outs            = lastAssigned;
                    outDescriptions = new List <string>(outs.Count);
                    for (int i = 0; i < outs.Count; i++)
                    {
                        outDescriptions.Add("");
                    }
                }

                // Create expression that will execute all the statements
                Expression functionExpression = Expression.Call(
                    thisExpression,
                    typeof(JITFunction).GetMethod("ExecuteBlock"),
                    Expression.NewArrayInit(typeof(Object), statements)
                    );

                compiledFunction = Expression.Lambda <Func <Object> >(functionExpression).Compile();
            } catch (Exception e) {
                compiledFunction = null;
                inError          = true;
                error            = e;
            }
        }
Esempio n. 21
0
        public static void AddVector3d(Kerbulator kalc, string id, Vector3d v)
        {
            Variable x = new Variable("x", VarType.NUMBER, v.x);
            Variable y = new Variable("y", VarType.NUMBER, v.y);
            Variable z = new Variable("z", VarType.NUMBER, v.z);

            List<Variable> elements = new List<Variable>(3);
            elements.Add(x);
            elements.Add(y);
            elements.Add(z);

            Variable g = new Variable(id, VarType.LIST, elements);
            kalc.AddGlobal(g);
        }
Esempio n. 22
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;
        }
Esempio n. 23
0
 public void AddGlobals(Kerbulator kalc)
 {
 }
Esempio n. 24
0
        public KerbulatorGUI(IGlue glue, bool inEditor, bool drawMainButton)
        {
            this.glue = glue;
            this.inEditor = inEditor;
            this.drawMainButton = drawMainButton;
            ChangeState(false);

            functionDir = Application.persistentDataPath + "/Kerbulator";

            // Sometimes, Application.persistentDataPath returns an empty string.
            // To not completely crash, create a KerbulatorFunctions directory in the users home dir
            if(functionDir == "/Kerbulator") {
                string homePath =
                    (Environment.OSVersion.Platform == PlatformID.Unix ||
                     Environment.OSVersion.Platform == PlatformID.MacOSX)
                     ? Environment.GetEnvironmentVariable("HOME")
                     : Environment.ExpandEnvironmentVariables("%HOMEDRIVE%%HOMEPATH%");
                functionDir = homePath +"/KerbulatorFunctions";
            }

            Debug.Log("Function dir: "+ functionDir);

            editFunctionContent = maneuverTemplate;

            if(!Directory.Exists(functionDir)) {
                Directory.CreateDirectory(functionDir);
            }

            // Load icons
            kerbulatorIcon = glue.GetTexture("kerbulator");
            editIcon = glue.GetTexture("edit");
            runIcon = glue.GetTexture("run");
            nodeIcon = glue.GetTexture("node");
            saveIcon = glue.GetTexture("save");
            deleteIcon = glue.GetTexture("delete");

            Scan();

            kalc = new Kerbulator(functionDir);
        }
Esempio n. 25
0
        private bool ParseBrace(Stack <Expression> expr, Stack <Operator> ops)
        {
            Token t = tokens.Peek();

            // Determine whether it's a left or right brace
            bool isLeft = false;

            switch (t.val)
            {
            case "(":
            case "{":
            case "⌊":
            case "⌈":
                isLeft = true;
                break;

            case "|":
                isLeft = !PossiblyValidExpression(expr, ops);

                if (isLeft)
                {
                    Kerbulator.DebugLine("| is left brace");
                }
                else
                {
                    Kerbulator.DebugLine("| is right brace");
                }
                break;
            }

            // If it's a left brace, start a sub-expression
            if (isLeft)
            {
                Consume();

                // Execute sub-expression
                Kerbulator.DebugLine("Starting subexpression");
                Expression subexpr = ParseExpression();
                Kerbulator.DebugLine("End of subexpression");
                expr.Push(subexpr);

                // Consume right brace. Execute operation if any
                switch (t.val)
                {
                case "(":
                    Consume(")");
                    break;

                case "{":
                    Consume("}");
                    break;

                case "⌊":
                    Consume("⌋");
                    ops.Push(kalc.Operators[t.val]);
                    break;

                case "⌈":
                    Consume("⌉");
                    ops.Push(kalc.Operators[t.val]);
                    break;

                case "|":
                    Consume("|");
                    ops.Push(kalc.Operators[t.val]);
                    break;
                }
                return(false);
            }
            else
            {
                return(true);
            }
        }
Esempio n. 26
0
        public static void Add(Kerbulator kalc)
        {
            // Planets
            foreach(CelestialBody b in FlightGlobals.Bodies) {
                if(b.name == "Sun")
                    Globals.AddCelestialBody(kalc, b, "Kerbol");
                else
                    Globals.AddCelestialBody(kalc, b, b.name);
            }

            Vessel v = FlightGlobals.ActiveVessel;
            Orbit orbit1 = v.orbit;
            if(v != null) {
                // Current orbit
                Globals.AddOrbit(kalc, orbit1, "Craft");

                // Navball (thank you MechJeb source)
                Vector3d CoM = v.findWorldCenterOfMass();
                Vector3d up = (CoM - v.mainBody.position).normalized;
                Vector3d north = Vector3d.Exclude(up, (v.mainBody.position + v.mainBody.transform.up * (float)v.mainBody.Radius) - CoM).normalized;
                Quaternion rotationSurface = Quaternion.LookRotation(north, up);
                Quaternion rotationVesselSurface = Quaternion.Inverse(Quaternion.Euler(90, 0, 0) * Quaternion.Inverse(v.GetTransform().rotation) * rotationSurface);
                Vector3d velocityVesselOrbit = v.orbit.GetVel();
                Vector3d velocityVesselSurface = velocityVesselOrbit - v.mainBody.getRFrmVel(CoM);

                Globals.AddDouble(kalc, "Navball.Heading", rotationVesselSurface.eulerAngles.y);
                Globals.AddDouble(kalc, "Navball.Pitch",  (rotationVesselSurface.eulerAngles.x > 180) ? (360.0 - rotationVesselSurface.eulerAngles.x) : -rotationVesselSurface.eulerAngles.x);
                Globals.AddDouble(kalc, "Navball.Roll", (rotationVesselSurface.eulerAngles.z > 180) ? (rotationVesselSurface.eulerAngles.z - 360.0) : rotationVesselSurface.eulerAngles.z);
                Globals.AddDouble(kalc, "Navball.OrbitalVelocity", velocityVesselOrbit.magnitude);
                Globals.AddDouble(kalc, "Navball.SurfaceVelocity", velocityVesselSurface.magnitude);
                Globals.AddDouble(kalc, "Navball.VerticalVelocity", Vector3d.Dot(velocityVesselSurface, up));

                // Current time
                double UT = (double)Planetarium.GetUniversalTime();
                Globals.AddDouble(kalc, "UT", UT);

                // Reference body
                Globals.AddCelestialBody(kalc, v.orbit.referenceBody, "Parent");

                // Target
                if(FlightGlobals.fetch.VesselTarget != null) {
                    ITargetable target = FlightGlobals.fetch.VesselTarget;
                    Orbit orbit2 = target.GetOrbit();

                    // Target Orbit
                    Globals.AddOrbit(kalc, orbit2, "Target");

                    // Intersection with target orbit
                    double CD = 0.0;
                    double CCD = 0.0;
                    double FFp = 0.0;
                    double FFs = 0.0;
                    double SFp = 0.0;
                    double SFs = 0.0;
                    int iterationCount = 0;
                    Orbit.FindClosestPoints(orbit1, orbit2, ref CD, ref CCD, ref FFp, ref FFs, ref SFp, ref SFs, 0.0, 100, ref iterationCount);
                    double T1 = orbit1.GetDTforTrueAnomaly(FFp, 0.0);
                    double T2 = orbit1.GetDTforTrueAnomaly(SFp, 0.0);
                    Globals.AddDouble(kalc, "Craft.Inter1.dt", T1);
                    Globals.AddDouble(kalc, "Craft.Inter1.Δt", T1);
                    Globals.AddDouble(kalc, "Craft.Inter1.Sep", (orbit1.getPositionAtUT(T1+UT) - orbit2.getPositionAtUT(T1+UT)).magnitude);
                    Globals.AddDouble(kalc, "Craft.Inter1.TrueAnomaly", orbit1.TrueAnomalyAtUT(T1+UT));
                    Globals.AddDouble(kalc, "Craft.Inter1.θ", orbit1.TrueAnomalyAtUT(T1+UT));
                    Globals.AddDouble(kalc, "Craft.Inter2.dt", T2);
                    Globals.AddDouble(kalc, "Craft.Inter2.Δt", T2);
                    Globals.AddDouble(kalc, "Craft.Inter2.Sep", (orbit1.getPositionAtUT(T2+UT) - orbit2.getPositionAtUT(T2+UT)).magnitude);
                    Globals.AddDouble(kalc, "Craft.Inter2.TrueAnomaly", orbit2.TrueAnomalyAtUT(T2+UT));
                    Globals.AddDouble(kalc, "Craft.Inter2.θ", orbit2.TrueAnomalyAtUT(T2+UT));
                }
            }
        }
 public ExecutionEnvironment(JITFunction func, Kerbulator kalc)
 {
     this.func        = func;
     this.kalc        = kalc;
     inputExpressions = new List <JITExpression>(func.Ins.Count);
 }
Esempio n. 28
0
 /// <summary>Add/Update some useful globals</summary>
 public void AddGlobals(Kerbulator kalc)
 {
     Globals.Add(kalc); // UNITY
 }
Esempio n. 29
0
        public static void Main(string[] args)
        {
            Kerbulator k = new Kerbulator("./tests");
            if(args[0].EndsWith(".test")) {
                Console.WriteLine("Running unit tests in "+ args[0]);
                StreamReader file = File.OpenText(args[0]);
                string line;
                while( (line = file.ReadLine()) != null ) {
                    string[] parts = line.Split('>');
                    string expression = parts[0].Trim();
                    string expectedResult = parts[1].Trim();

                    try {
                        string r = k.RunExpression(expression).ToString();
                        if(r.Equals(expectedResult))
                            Console.WriteLine(expression +" = "+ r +" [PASS]");
                        else
                            Console.WriteLine(expression +" = "+ r +" [FAIL] "+ expectedResult);
                    } catch(Exception e) {
                        if(expectedResult == "ERROR")
                            Console.WriteLine(expression +" = ERROR [PASS]");
                        else
                            Console.WriteLine(expression +" = ERROR [FAIL] "+ e.Message);
                    }
                }
                file.Close();
                return;
            } else {
                List<Variable> result;
                if(args[0] == "-v") {
                    Kerbulator.DEBUG = true;
                    result = k.Run(args[1]);
                } else {
                    Kerbulator.DEBUG = false;
                    result = k.Run(args[0]);
                }

                foreach(Variable v in result)
                    Console.Write(v.id +" = "+ v.ToString() +", ");
                Console.WriteLine("\n");
            }
        }
Esempio n. 30
0
 public static void AddCelestialBody(Kerbulator kalc, CelestialBody body)
 {
     AddCelestialBody(kalc, body, body.name);
 }
Esempio n. 31
0
        public static void Add(Kerbulator kalc)
        {
            // Planets
            foreach (CelestialBody b in FlightGlobals.Bodies)
            {
                if (b.name == "Sun")
                {
                    AddCelestialBody(kalc, b, "Kerbol");
                }
                else
                {
                    AddCelestialBody(kalc, b, b.name);
                }
            }

            Vessel v      = FlightGlobals.ActiveVessel;
            Orbit  orbit1 = v.orbit;

            if (v != null)
            {
                // Current orbit
                AddOrbit(kalc, orbit1, "Craft");

                // Current position in carthesian coordinates
                AddVector3d(kalc, "Craft.Pos", v.GetWorldPos3D());

                // Navball (thank you MechJeb source)
                Vector3d   CoM                   = v.findWorldCenterOfMass();
                Vector3d   up                    = (CoM - v.mainBody.position).normalized;
                Vector3d   north                 = Vector3d.Exclude(up, (v.mainBody.position + v.mainBody.transform.up * (float)v.mainBody.Radius) - CoM).normalized;
                Quaternion rotationSurface       = Quaternion.LookRotation(north, up);
                Quaternion rotationVesselSurface = Quaternion.Inverse(Quaternion.Euler(90, 0, 0) * Quaternion.Inverse(v.GetTransform().rotation) * rotationSurface);
                Vector3d   velocityVesselOrbit   = v.orbit.GetVel();
                Vector3d   velocityVesselSurface = velocityVesselOrbit - v.mainBody.getRFrmVel(CoM);

                AddDouble(kalc, "Navball.Heading", rotationVesselSurface.eulerAngles.y);
                AddDouble(kalc, "Navball.Pitch", (rotationVesselSurface.eulerAngles.x > 180) ? (360.0 - rotationVesselSurface.eulerAngles.x) : -rotationVesselSurface.eulerAngles.x);
                AddDouble(kalc, "Navball.Roll", (rotationVesselSurface.eulerAngles.z > 180) ? (rotationVesselSurface.eulerAngles.z - 360.0) : rotationVesselSurface.eulerAngles.z);
                AddDouble(kalc, "Navball.OrbitalVelocity", velocityVesselOrbit.magnitude);
                AddDouble(kalc, "Navball.SurfaceVelocity", velocityVesselSurface.magnitude);
                AddDouble(kalc, "Navball.VerticalVelocity", Vector3d.Dot(velocityVesselSurface, up));

                // Current time
                double UT = (double)Planetarium.GetUniversalTime();
                AddDouble(kalc, "UT", UT);

                // Reference body
                AddCelestialBody(kalc, v.orbit.referenceBody, "Parent");

                // Target
                if (FlightGlobals.fetch.VesselTarget != null)
                {
                    ITargetable target = FlightGlobals.fetch.VesselTarget;
                    Orbit       orbit2 = target.GetOrbit();

                    // Target Orbit
                    AddOrbit(kalc, orbit2, "Target");

                    // Intersection with target orbit
                    double CD             = 0.0;
                    double CCD            = 0.0;
                    double FFp            = 0.0;
                    double FFs            = 0.0;
                    double SFp            = 0.0;
                    double SFs            = 0.0;
                    int    iterationCount = 0;
                    Orbit.FindClosestPoints(orbit1, orbit2, ref CD, ref CCD, ref FFp, ref FFs, ref SFp, ref SFs, 0.0, 100, ref iterationCount);
                    double T1 = orbit1.GetDTforTrueAnomaly(FFp, 0.0);
                    double T2 = orbit1.GetDTforTrueAnomaly(SFp, 0.0);
                    AddDouble(kalc, "Craft.Inter1.dt", T1);
                    AddDouble(kalc, "Craft.Inter1.Δt", T1);
                    AddDouble(kalc, "Craft.Inter1.Sep", (orbit1.getPositionAtUT(T1 + UT) - orbit2.getPositionAtUT(T1 + UT)).magnitude);
                    AddDouble(kalc, "Craft.Inter1.TrueAnomaly", orbit1.TrueAnomalyAtUT(T1 + UT));
                    AddDouble(kalc, "Craft.Inter1.θ", orbit1.TrueAnomalyAtUT(T1 + UT));
                    AddDouble(kalc, "Craft.Inter2.dt", T2);
                    AddDouble(kalc, "Craft.Inter2.Δt", T2);
                    AddDouble(kalc, "Craft.Inter2.Sep", (orbit1.getPositionAtUT(T2 + UT) - orbit2.getPositionAtUT(T2 + UT)).magnitude);
                    AddDouble(kalc, "Craft.Inter2.TrueAnomaly", orbit2.TrueAnomalyAtUT(T2 + UT));
                    AddDouble(kalc, "Craft.Inter2.θ", orbit2.TrueAnomalyAtUT(T2 + UT));
                }
            }
        }
Esempio n. 32
0
        // UNITY
        public static void AddOrbit(Kerbulator kalc, Orbit orbit, string prefix)
        {
            if(orbit == null)
                return;

            kalc.AddGlobal(new Variable(prefix +".Ap", VarType.NUMBER, (double)orbit.ApA));
            kalc.AddGlobal(new Variable(prefix +".Pe", VarType.NUMBER, (double)orbit.PeA));
            kalc.AddGlobal(new Variable(prefix +".Inc", VarType.NUMBER, (double)orbit.inclination));
            kalc.AddGlobal(new Variable(prefix +".Alt", VarType.NUMBER, (double)orbit.altitude));
            kalc.AddGlobal(new Variable(prefix +".ArgPe", VarType.NUMBER, (double)orbit.argumentOfPeriapsis));
            kalc.AddGlobal(new Variable(prefix +".ω", VarType.NUMBER, (double)orbit.argumentOfPeriapsis));
            kalc.AddGlobal(new Variable(prefix +".LAN", VarType.NUMBER, (double)orbit.LAN));
            kalc.AddGlobal(new Variable(prefix +".Ω", VarType.NUMBER, (double)orbit.LAN));
            kalc.AddGlobal(new Variable(prefix +".TimeToAp", VarType.NUMBER, (double)orbit.timeToAp));
            kalc.AddGlobal(new Variable(prefix +".TimeToPe", VarType.NUMBER, (double)orbit.timeToPe));
            kalc.AddGlobal(new Variable(prefix +".Vel", VarType.NUMBER, (double)orbit.vel.magnitude));
            kalc.AddGlobal(new Variable(prefix +".TrueAnomaly", VarType.NUMBER, (double)orbit.trueAnomaly));
            kalc.AddGlobal(new Variable(prefix +".θ", VarType.NUMBER, (double)orbit.trueAnomaly));

            if(orbit.UTsoi > 0) {
                kalc.AddGlobal(new Variable(prefix +".SOI.dt", VarType.NUMBER, (double)orbit.UTsoi-Planetarium.GetUniversalTime()));
                kalc.AddGlobal(new Variable(prefix +".SOI.Δt", VarType.NUMBER, (double)orbit.UTsoi-Planetarium.GetUniversalTime()));
                kalc.AddGlobal(new Variable(prefix +".SOI.TrueAnomaly", VarType.NUMBER, (double)orbit.TrueAnomalyAtUT(orbit.UTsoi)));
                kalc.AddGlobal(new Variable(prefix +".SOI.θ", VarType.NUMBER, (double)orbit.TrueAnomalyAtUT(orbit.UTsoi)));
            }
        }
Esempio n. 33
0
        public void Tokenize(string line)
        {
            int   lineno = 1;
            int   col    = 1;
            Token tok    = new Token(functionName, lineno, col);

            for (int i = 0; i < line.Length; i++, col++)
            {
                char c = line[i];
                switch (c)
                {
                // Whitespace
                case ' ':
                case '\t':
                case '\r':
                    if (tok.type != TokenType.SKIP_NEWLINE)
                    {
                        HandleToken(tok);
                        tok = new Token(functionName, lineno, col + 1);
                    }
                    break;

                // End of statement
                case '\n':
                    if (tok.type != TokenType.SKIP_NEWLINE)
                    {
                        HandleToken(tok);
                        HandleToken(new Token(TokenType.END, "\\n", functionName, lineno, col));
                    }
                    lineno++;
                    col = 0;
                    tok = new Token(functionName, lineno, col + 1);
                    break;

                // Comments
                case '#':
                    HandleToken(tok);
                    // Skip to next newline
                    int newI = line.IndexOf('\n', i + 1) - 1;
                    if (newI < 0)
                    {
                        newI = line.Length - 1;
                    }
                    col += newI - i;
                    i    = newI;
                    tok  = new Token(functionName, lineno, col);
                    break;

                // Quoted strings
                case '"':
                    HandleToken(tok);
                    tok = new Token(TokenType.TEXT, "", functionName, lineno, col);

                    // Read until next unescaped "
                    bool terminated = false;
                    for (i = i + 1, col++; i < line.Length; i++, col++)
                    {
                        if (line[i] == '\\')
                        {
                            if (i >= line.Length - 1)
                            {
                                break;
                            }
                            tok.val += line[i + 1];
                            i       += 2; col += 2;
                        }
                        else if (line[i] == '"')
                        {
                            terminated = true;
                            break;
                        }
                        else
                        {
                            tok.val += line[i];
                        }
                    }

                    if (!terminated)
                    {
                        throw new Exception(tok.pos + "missing end quote (\") for string");
                    }

                    HandleToken(tok);
                    tok = new Token(functionName, lineno, col);
                    break;

                // Numbers
                case '0':
                case '1':
                case '2':
                case '3':
                case '4':
                case '5':
                case '6':
                case '7':
                case '8':
                case '9':
                    if (tok.type == TokenType.EMPTY)
                    {
                        tok.type = TokenType.NUMBER;
                        tok.val  = c.ToString();
                    }
                    else if (tok.type == TokenType.NUMBER || tok.type == TokenType.IDENTIFIER)
                    {
                        tok.val += c;
                    }
                    else
                    {
                        throw new Exception(tok.pos + c + " is invalid here");
                    }
                    break;

                case 'e':
                case 'E':
                    if (tok.type == TokenType.EMPTY)
                    {
                        tok.type = TokenType.IDENTIFIER;
                        tok.val  = c.ToString();
                    }
                    else if (tok.type == TokenType.NUMBER || tok.type == TokenType.IDENTIFIER)
                    {
                        tok.val += c;
                        if (i < line.Length - 1 && line[i + 1] == '-')
                        {
                            tok.val += line[i + 1].ToString();
                            i++; col++;
                        }
                    }
                    else
                    {
                        throw new Exception(tok.pos + c + " is invalid here");
                    }
                    break;

                case '.':
                    if (tok.type == TokenType.EMPTY)
                    {
                        tok.type = TokenType.NUMBER;
                        tok.val  = c.ToString();
                    }
                    else if (tok.type == TokenType.NUMBER)
                    {
                        if (tok.val.IndexOf(c) >= 0)
                        {
                            throw new Exception(tok.pos + "numbers can only have one decimal point (.) in them");
                        }
                        tok.val += c;
                    }
                    else if (tok.type == TokenType.IDENTIFIER)
                    {
                        tok.val += c;
                    }
                    else
                    {
                        throw new Exception(tok.pos + "variable/function names cannot start with a dot (.)");
                    }
                    break;

                // Operators
                case '-':
                case '+':
                case '/':
                case '÷':
                case '√':
                case '%':
                case '*':
                case '·':
                case '×':
                case '^':
                case '≤':
                case '≥':
                case '≠':
                case '¬':
                case '∧':
                case '∨':
                    HandleToken(tok);
                    HandleToken(new Token(TokenType.OPERATOR, c.ToString(), functionName, lineno, col));
                    tok = new Token(functionName, lineno, col + 1);
                    break;

                // Operators that can possibly expand to two characters (<=, =>, ==, !=)
                case '<':
                    HandleToken(tok);
                    if (i < line.Length - 1 && line[i + 1] == '=')
                    {
                        HandleToken(new Token(TokenType.OPERATOR, "<=", functionName, lineno, col));
                        col++; i++;
                    }
                    else
                    {
                        HandleToken(new Token(TokenType.OPERATOR, "<", functionName, lineno, col));
                    }
                    tok = new Token(functionName, lineno, col + 1);
                    break;

                case '>':
                    HandleToken(tok);
                    if (i < line.Length - 1 && line[i + 1] == '=')
                    {
                        HandleToken(new Token(TokenType.OPERATOR, ">=", functionName, lineno, col));
                        col++; i++;
                    }
                    else
                    {
                        HandleToken(new Token(TokenType.OPERATOR, ">", functionName, lineno, col));
                    }
                    tok = new Token(functionName, lineno, col + 1);
                    break;

                case '!':
                    HandleToken(tok);
                    if (i < line.Length - 1 && line[i + 1] == '=')
                    {
                        HandleToken(new Token(TokenType.OPERATOR, "!=", functionName, lineno, col));
                        col++; i++;
                    }
                    else
                    {
                        HandleToken(new Token(TokenType.OPERATOR, "!", functionName, lineno, col));
                    }
                    tok = new Token(functionName, lineno, col + 1);
                    break;

                // The =, ==, ={ case
                case '=':
                    HandleToken(tok);
                    if (i < line.Length - 1 && line[i + 1] == '=')
                    {
                        HandleToken(new Token(TokenType.OPERATOR, "==", functionName, lineno, col));
                        col++; i++;
                    }
                    else if (i < line.Length - 1 && line[i + 1] == '{')
                    {
                        HandleToken(new Token(TokenType.PIECEWISE, "={", functionName, lineno, col));
                        col++; i++;
                    }
                    else
                    {
                        HandleToken(new Token(TokenType.ASSIGN, "=", functionName, lineno, col));
                    }
                    tok = new Token(functionName, lineno, col + 1);
                    break;

                // Brackets
                case '[':
                case ']':
                    HandleToken(tok);
                    HandleToken(new Token(TokenType.LIST, c.ToString(), functionName, lineno, col));
                    tok = new Token(functionName, lineno, col + 1);
                    break;

                case '(':
                case ')':
                case '{':
                case '}':
                case '⌊':
                case '⌋':
                case '⌈':
                case '⌉':
                case '|':
                    HandleToken(tok);
                    HandleToken(new Token(TokenType.BRACE, c.ToString(), functionName, lineno, col));
                    tok = new Token(functionName, lineno, col + 1);
                    break;

                // In: and Out: statements
                case ':':
                    if (tok.val == "in")
                    {
                        HandleToken(new Token(TokenType.IN, tok.val, functionName, lineno, col));
                    }
                    else if (tok.val == "out")
                    {
                        HandleToken(new Token(TokenType.OUT, tok.val, functionName, lineno, col));
                    }
                    else
                    {
                        HandleToken(tok);
                        HandleToken(new Token(TokenType.COLON, tok.val, functionName, lineno, col));
                    }

                    tok = new Token(functionName, lineno, col + 1);
                    break;

                // Others
                case ',':
                    HandleToken(tok);
                    HandleToken(new Token(TokenType.COMMA, c.ToString(), functionName, lineno, col));
                    tok = new Token(functionName, lineno, col + 1);
                    break;

                case '\\':
                    HandleToken(tok);
                    tok = new Token(TokenType.SKIP_NEWLINE, c.ToString(), functionName, lineno, col);
                    break;

                default:
                    if (tok.type != TokenType.EMPTY && tok.type != TokenType.IDENTIFIER)
                    {
                        throw new Exception(tok.pos + "unexpected character: " + c);
                    }
                    tok.type = TokenType.IDENTIFIER;
                    tok.val += c;
                    break;
                }
            }

            HandleToken(tok);
            Kerbulator.Debug("\n");
        }
Esempio n. 34
0
        public Expression ParseExpression()
        {
            Stack <Expression> expr = new Stack <Expression>();
            Stack <Operator>   ops  = new Stack <Operator>();

            bool end = false;             // If ever set to true, this is the end of the expression

            if (tokens.Count == 0)
            {
                throw new Exception("empty expression");
            }

            Token t = tokens.Peek();

            while (!end && tokens.Count > 0 && tokens.Peek().type != TokenType.END)
            {
                t = tokens.Peek();
                Kerbulator.DebugLine("Token: " + Enum.GetName(typeof(TokenType), t.type) + ": " + t.val);

                switch (t.type)
                {
                case TokenType.NUMBER:
                    ParseNumber(expr);
                    break;

                case TokenType.OPERATOR:
                    ParseOperator(expr, ops);
                    break;

                case TokenType.BRACE:
                    end = ParseBrace(expr, ops);
                    break;

                case TokenType.LIST:
                    end = ParseList(expr);
                    break;

                case TokenType.IDENTIFIER:
                    ParseIdentifier(expr, ops);
                    break;

                case TokenType.COMMA:
                    end = true;
                    break;

                case TokenType.EQUALS:
                    end = true;
                    break;

                default:
                    Consume();
                    break;
                }
            }

            // Handle remaining ops
            while (ops.Count > 0)
            {
                Operator op = ops.Pop();
                expr.Push(ExecuteOperator(op, expr, ops, t.pos));
            }

            if (expr.Count > 1)
            {
                throw new Exception(t.pos + "malformed expression");
            }

            return(expr.Pop());
        }
Esempio n. 35
0
 public static void AddBool(Kerbulator kalc, string id, bool v)
 {
     double val = v ? 1.0 : 0.0;
     Variable g = new Variable(id, VarType.NUMBER, val);
     kalc.AddGlobal(g);
 }
Esempio n. 36
0
 public void AddGlobals(Kerbulator kalc)
 {
 }
Esempio n. 37
0
        public static void AddCelestialBody(Kerbulator kalc, CelestialBody body, string prefix)
        {
            if(body == null)
                return;

            try {
                if(body.orbit != null) {
                    AddOrbit(kalc, body.orbit, prefix);
                }
            } catch(Exception) {
                // Somehow, testing body.orbit != null is not enough. I don't know why...
                // Leave a pull request or file an issue if you can help me figure this out!
            }

            kalc.AddGlobal(new Variable(prefix +".R", VarType.NUMBER, (double)body.Radius));
            kalc.AddGlobal(new Variable(prefix +".M", VarType.NUMBER, (double)body.Mass));
            kalc.AddGlobal(new Variable(prefix +".mu", VarType.NUMBER, (double)body.gravParameter));
            kalc.AddGlobal(new Variable(prefix +".μ", VarType.NUMBER, (double)body.gravParameter));
            kalc.AddGlobal(new Variable(prefix +".day", VarType.NUMBER, (double)body.rotationPeriod));
            kalc.AddGlobal(new Variable(prefix +".SOI", VarType.NUMBER, (double)body.sphereOfInfluence));
            kalc.AddGlobal(new Variable(prefix +".AtmosHeight", VarType.NUMBER, (double)body.maxAtmosphereAltitude));
            kalc.AddGlobal(new Variable(prefix +".AtmosPress", VarType.NUMBER, (double)body.atmosphereMultiplier * 101325.0));
        }
Esempio n. 38
0
        private Expression ExecuteOperator(Operator op, Stack <Expression> expr, Stack <Operator> ops, string pos)
        {
            Kerbulator.DebugLine("Executing: " + op.id);
            if (op.arity == Arity.BINARY && expr.Count < 2)
            {
                throw new Exception(pos + "operator " + op.id + " expects both a left and a right hand side to operate on.");
            }
            else if (op.arity == Arity.UNARY && expr.Count < 1)
            {
                throw new Exception(pos + "operator " + op.id + " expects a right hand side to operate on.");
            }
            else if (op.arity == Arity.BOTH)
            {
                throw new Exception(pos + "arity of " + op.id + " still undefined.");
            }

            Expression a, b;
            Expression opExpression;

            switch (op.id)
            {
            case "+":
                b            = expr.Pop();
                a            = expr.Pop();
                opExpression = CallBinaryLambda(op.id, (x, y) => x + y, a, b, pos);
                break;

            case "-":
                b = expr.Pop();
                if (op.arity == Arity.UNARY)
                {
                    opExpression = CallUnaryLambda(op.id, x => - x, b, pos);
                }
                else
                {
                    a            = expr.Pop();
                    opExpression = CallBinaryLambda(op.id, (x, y) => x - y, a, b, pos);
                }
                break;

            case "*":
            case "·":
            case "×":
                b            = expr.Pop(); a = expr.Pop();
                opExpression = CallBinaryLambda(op.id, (x, y) => x * y, a, b, pos);
                break;

            case "/":
            case "÷":
                b            = expr.Pop(); a = expr.Pop();
                opExpression = CallBinaryLambda(op.id, (x, y) => x / y, a, b, pos);
                break;

            case "%":
                b            = expr.Pop(); a = expr.Pop();
                opExpression = CallBinaryLambda(op.id, (x, y) => x % y, a, b, pos);
                break;

            case "^":
                b            = expr.Pop(); a = expr.Pop();
                opExpression = CallBinaryMathFunction(op.id, "Pow", a, b, pos);
                break;

            case "√":
                b = expr.Pop();
                if (op.arity == Arity.UNARY)
                {
                    opExpression = CallUnaryMathFunction(op.id, "Sqrt", b, pos);
                }
                else
                {
                    a            = expr.Pop();
                    opExpression = CallBinaryMathFunction(op.id, "Pow",
                                                          b,
                                                          CallUnaryLambda(op.id, x => 1 / x, a, pos),
                                                          pos
                                                          );
                }
                break;

            case "⌊":
                b            = expr.Pop();
                opExpression = CallUnaryMathFunction(op.id, "Floor", b, pos);
                break;

            case "⌈":
                b            = expr.Pop();
                opExpression = CallUnaryMathFunction(op.id, "Ceiling", b, pos);
                break;

            case "|":
                b            = expr.Pop();
                opExpression = Expression.Condition(
                    Expression.TypeIs(b, typeof(double)),
                    CallUnaryMathFunction(op.id, "Abs", b, pos),
                    Expression.Call(
                        typeof(VectorMath).GetMethod("Mag"),
                        b,
                        Expression.Constant(pos)
                        )
                    );
                break;

            case "buildin-function":
                List <Expression> args = new List <Expression>();
                args.Add(expr.Pop());
                a            = expr.Pop();
                opExpression = ParseBuildInFunction(kalc.BuildInFunctions[(string)((ConstantExpression)a).Value], args, pos);
                break;

            case "user-function":
                List <Expression> args2 = new List <Expression>();
                args2.Add(expr.Pop());
                a = expr.Pop();
                return(ParseUserFunction(
                           (string)((ConstantExpression)a).Value,
                           args2,
                           pos
                           ));

            default:
                throw new Exception(pos + "unknown operator: " + op.id);
            }

            return(Expression.Convert(opExpression, typeof(Object)));
        }
Esempio n. 39
0
        public static void AddBool(Kerbulator kalc, string id, bool v)
        {
            double val = v ? 1.0 : 0.0;

            AddDouble(kalc, id, val);
        }
Esempio n. 40
0
 public static void AddVector3(Kerbulator kalc, string prefix, Vector3 v)
 {
     AddDouble(kalc, prefix + ".x", (double)v.x);
     AddDouble(kalc, prefix + ".y", (double)v.y);
     AddDouble(kalc, prefix + ".z", (double)v.z);
 }
Esempio n. 41
0
 public static void AddDouble(Kerbulator kalc, string id, double v)
 {
     Variable g = new Variable(id, VarType.NUMBER, v);
     kalc.AddGlobal(g);
 }