Пример #1
0
        public override BasicNode Eval(BasicEnvironment env)
        {
            env.InstructionCount++;
            var node = boolExpr.Eval(env);

            if (node.IsAbort())
            {
                return(node);
            }
            var cnode = node as ConstantNode;

            if (cnode == null)
            {
                env.RuntimeError();
            }
            bool b = cnode.BoolValue;

            if (!b)
            {
                return(this);
            }

            b = env.Goto(thenLabel);
            if (!b)
            {
                return(env.RuntimeError(ERuntimeErrors.JumpToUndefinedLabel, thenLabel));
            }
            return(this);
        }
Пример #2
0
        public override BasicNode Eval(BasicEnvironment env)
        {
            env.InstructionCount++;
            if (For.own1 == null || For.own2 == null)
            {
                return(env.RuntimeError(ERuntimeErrors.JumpIntoForLoop));
            }
            env.InstructionCount++;
            var v = Var.GetValue(env) as NumericConstantNode;

            if (v == null)
            {
                return(env.RuntimeError());
            }
            var val = v.Value;

            val += For.own2.Value;
            var valNode = new NumericConstantNode(val);

            Var.SetValue(env, valNode);
            if (For.LoopStep(env, valNode))
            {
                env.GotoPc(For.Pc + 1);
            }

            return(this);
        }
Пример #3
0
        override public ShipCommand getNextCommand(BasicEnvironment env)
        {
            var toCenter = env.getShipStatus().getPosition().getAngleTo(center);

            var toward = toCenter - env.getShipStatus().getOrientation();

            while (toward > 180)
            {
                toward -= 360;
            }
            while (toward < -180)
            {
                toward += 360;
            }

            var flip       = Math.Abs(toward) > 90;
            var adjustment = flip ? toward + 180 : toward;

            while (adjustment > 180)
            {
                adjustment -= 360;
            }
            while (adjustment < -180)
            {
                adjustment += 360;
            }

            Console.WriteLine($"flip: {flip}, adjustment: {adjustment}");

            if (Math.Abs(adjustment) > 2)
            {
                return(new RotateCommand(adjustment));
            }

            var distance = env.getShipStatus().getPosition().getDistanceTo(center);
            var closing  = Math.Cos((toCenter - env.getShipStatus().getMovementDirection()) * Math.PI / 180) * env.getShipStatus().getSpeed();
            var drift    = Math.Sin((toCenter - env.getShipStatus().getMovementDirection()) * Math.PI / 180) * env.getShipStatus().getSpeed();
            var eta      = distance / closing;

            Console.WriteLine($"closing: {closing}, drift: {drift}, distance: {distance}, eta: {eta}");

            if (Math.Abs(drift) > 2 && r.Next() % 4 == 0)
            {
                return(new ThrustCommand(drift < 0 ^ flip ? 'L' : 'R', .1, 1, false));
            }

            if ((eta < 0 || eta > 3.1 || closing < 0) && env.getShipStatus().getEnergy() > 50)
            {
                return(new ThrustCommand(flip ? 'F' : 'B', .1, 1, false));
            }

            if (closing < 5 || eta > 2.9)
            {
                return(new IdleCommand(.1));
            }

            var brakes = Math.Max(.25, Math.Min(1, distance / 50));

            return(new ThrustCommand(flip ? 'B' : 'F', .1, brakes, false));
        }
Пример #4
0
        override public ShipCommand getNextCommand(BasicEnvironment env)
        {
            iteration++;

            if (env.getShipStatus().getSpeed() < 30)
            {
                return(new ThrustCommand('B', 1, 1.0, false));
            }
            else if (!sw.IsRunning || sw.Elapsed.TotalSeconds > 10)
            {
                sw.Restart();
                return(new RaiseShieldsCommand(10));
            }

            double adjust = env.getShipStatus().getOrientation()
                            - env.getShipStatus().getMovementDirection();

            while (adjust < -180)
            {
                adjust += 360;
            }
            while (adjust > 180)
            {
                adjust -= 360;
            }
            if (Math.Abs(adjust) > 5)
            {
                return(new RotateCommand(-(int)adjust));
            }

            return(new IdleCommand(.1));
        }
Пример #5
0
        public override BasicNode Eval(BasicEnvironment env)
        {
            env.InstructionCount++;
            ExpressionNode[] evaledArgs = new ExpressionNode[Arguments.Length];
            for (int i = 0; i < Arguments.Length; i++)
            {
                var evArg = Arguments[i].Eval(env);
                if (evArg.IsAbort())
                {
                    return(evArg);
                }
                evaledArgs[i] = evArg as ConstantNode;
            }
            BasicNode result;

            switch (Functor)
            {
            case "TAB":
                result = ControlNode.Make(EvalResultKind.Tab, evaledArgs[0]);
                break;

            default: result = env.RuntimeError(ERuntimeErrors.CallToUnknownFunction, Functor); break;
            }
            return(result);
        }
Пример #6
0
        public NumericConstantNode EvalAtIndex(int index, BasicEnvironment env)
        {
            var arg = sequence[index] as BasicNode;

            if (arg == null)
            {
                return(null);
            }
            arg = arg.Eval(env);
            var ncn = arg as NumericConstantNode;

            if (ncn != null)
            {
                return(ncn);
            }
            var cnode = arg as ConstantNode;

            if (cnode != null)
            {
                ncn = cnode.ToNumericConstant();
            }
            if (ncn == null)
            {
                env.RuntimeError(ERuntimeErrors.ConversionError);
            }
            return(ncn);
        }
Пример #7
0
        public override BasicNode Eval(BasicEnvironment env)
        {
            var arg = EvalAtIndex(0, env);

            if (arg == null)
            {
                return(env.RuntimeError());
            }
            double prod = arg.Value;

            for (int i = 1; i < sequence.Length; i++)
            {
                object item = sequence[i];
                arg = EvalAtIndex(i, env);
                if (arg == null)
                {
                    return(env.RuntimeError());
                }
                var num  = arg.Value;
                var iv   = arg.IntValue;
                var back = (double)iv;
                if (back == num)
                {
                    prod = IntPow(prod, iv, env);
                    continue;
                }
                //if (num < 0)
                //	return env.RuntimeError("negative exponent not supported");
                prod = Math.Pow(prod, num);
            }
            return(new NumericConstantNode(prod));
        }
Пример #8
0
        double IntPow(double x, int n, BasicEnvironment env)
        {
            bool invert = false;

            if (n < 0)
            {
                n      = -n;
                invert = true;
            }
            double res  = 1.0;
            double prod = x;

            while (n > 0)
            {
                if ((n & 1) != 0)
                {
                    env.InstructionCount += MulSequenceExpressionNode.MulComplexity;
                    res *= prod;
                }
                env.InstructionCount += MulSequenceExpressionNode.MulComplexity;
                prod = prod * prod;
                n  >>= 1;
            }
            if (invert)
            {
                return(1.0 / res);
            }
            return(res);
        }
Пример #9
0
        public override BasicNode Eval(BasicEnvironment env)
        {
            double prod  = 1;
            bool   opDiv = false;

            for (int i = 0; i < sequence.Length; i++)
            {
                object item = sequence[i];
                string op   = item as string;
                if (op != null)
                {
                    opDiv = op == "/";
                    continue;
                }
                var arg = EvalAtIndex(i, env);
                if (arg == null)
                {
                    return(env.RuntimeError());
                }
                var argVal = (arg).Value;
                env.InstructionCount += opDiv ? DivComplexity : MulComplexity;
                if (opDiv)
                {
                    prod /= argVal;
                }
                else
                {
                    prod *= argVal;
                }
            }
            return(new NumericConstantNode(prod));
        }
Пример #10
0
        public override BasicNode Eval(BasicEnvironment env)
        {
            var res = env.Host.InputOutput.QueryInput(prompt, varNames);

            if (res == null)
            {
                return(env.RuntimeError("User aborted program during input"));
            }
            if (res.Length < varNames.Length)
            {
                return(env.RuntimeError($"INPUT expected {varNames.Length} values but got only {res.Length}"));
            }
            for (int i = 0; i < refNames.Length; i++)
            {
                env.InstructionCount++;
                var          varNode  = refNames[i];
                ConstantNode consNode = Parser.ParseDatum(res[i]);
                if (varNode.IsStringName)
                {
                    consNode = consNode?.ToStringConstant();
                }
                else
                {
                    consNode = consNode?.ToNumericConstant();
                }
                if (consNode == null)
                {
                    return(env.RuntimeError($"INPUT variable ({refNames[i]}) conversion error from '{res[i]}'"));
                }
                varNode.SetValue(env, consNode);
            }
            return(this);
        }
Пример #11
0
 public override BasicNode Eval(BasicEnvironment env)
 {
     env.InstructionCount++;
     if (!env.PopPc())
     {
         return(env.RuntimeError(ERuntimeErrors.ReturnWithoutGosub));
     }
     return(this);
 }
Пример #12
0
 public override BasicNode Eval(BasicEnvironment env)
 {
     env.InstructionCount++;
     if (!env.Goto(Label, IsGosub))
     {
         return(env.RuntimeError(ERuntimeErrors.JumpToUndefinedLabel, Label));
     }
     return(this);
 }
Пример #13
0
        public async Task <EvalResult> RunEvalAsync(string code)
        {
            var sb     = new StringBuilder();
            var textWr = new ConsoleLikeStringWriter(sb);
            var env    = new BasicEnvironment();

            var sw   = Stopwatch.StartNew();
            var eval = CSharpScript.Create(code, Options, typeof(Globals));

            var compilation = eval.GetCompilation().WithAnalyzers(Analyzers);

            var compileResult = await compilation.GetAllDiagnosticsAsync();

            var compileErrors = compileResult.Where(a => a.Severity == DiagnosticSeverity.Error).ToImmutableArray();

            sw.Stop();

            var compileTime = sw.Elapsed;

            if (compileErrors.Length > 0)
            {
                return(EvalResult.CreateErrorResult(code, sb.ToString(), sw.Elapsed, compileErrors));
            }

            var globals = new Globals();

            Globals.Random      = random;
            Globals.Console     = textWr;
            Globals.Environment = env;

            sw.Restart();
            var result = await eval.RunAsync(globals, ex => true);

            sw.Stop();
            var evalResult = new EvalResult(result, sb.ToString(), sw.Elapsed, compileTime);

            //this hack is to test if we're about to send an object that can't be serialized back to the caller.
            //if the object can't be serialized, return a failure instead.
            try
            {
                JsonConvert.SerializeObject(evalResult, jsonSettings);
            }
            catch (Exception ex)
            {
                evalResult = new EvalResult
                {
                    Code           = code,
                    CompileTime    = compileTime,
                    ConsoleOut     = sb.ToString(),
                    ExecutionTime  = sw.Elapsed,
                    ReturnTypeName = result.ReturnValue.GetType().Name,
                    ReturnValue    = $"An exception occurred when serializing the response: {ex.GetType().Name}: {ex.Message}"
                };
            }
            return(evalResult);
        }
Пример #14
0
        public override BasicNode Eval(BasicEnvironment env)
        {
            env.InstructionCount++;
            var evaledRhs = Expression.Eval(env) as ConstantNode;

            if (evaledRhs == null)
            {
                return(env.RuntimeError());
            }
            return(Variable.SetValue(env, evaledRhs));
        }
Пример #15
0
        internal bool LoopStep(BasicEnvironment env, NumericConstantNode v)
        {
            var cmp = v.Value.CompareTo(own1.Value);

            if (cmp * Math.Sign(own2.Value) > 0)
            {
                env.GotoPc(nextNode.Pc + 1);                  // jump out of loop
                own1 = own2 = null;
                return(false);
            }
            return(true);
        }
Пример #16
0
 public override BasicNode Eval(BasicEnvironment env)
 {
     env.InstructionCount += vars.Length;
     for (int i = 0; i < vars.Length; i++)
     {
         var result = env.Read(vars[i]);
         if (result.IsError())
         {
             return(result);
         }
     }
     return(this);
 }
Пример #17
0
        public override BasicNode Eval(BasicEnvironment env)
        {
            BasicNode result = null;

            for (int i = 0; i < statements.Length; i++)
            {
                result = statements[i].Eval(env);
                if (result.IsError())
                {
                    return(result);
                }
            }
            return(result);
        }
Пример #18
0
        internal bool Link(BasicEnvironment env)
        {
            if (env.GetProperty(name) != null)
            {
                return(false);
            }
            var f = new FunctionProperty
            {
                argumentNames = parNames,
                FuncImpl      = Call,
                Name          = name
            };

            env.SetProperty(f);
            return(true);
        }
Пример #19
0
 internal BasicNode ApplyFunc(BasicEnvironment env, FunctionProperty func)
 {
     env.InstructionCount++;
     if (!env.SaveContext())
     {
         return(env.LastError);
     }
     try
     {
         // create the formal parameters with their values
         int            nArgs      = func.argumentNames.Length;
         ConstantNode[] evaledArgs = new ConstantNode[nArgs];
         for (int i = 0; i < nArgs; i++)
         {
             string    argName = func.argumentNames[i];
             BasicNode evArg   = null;
             if (i < Arguments.Length)
             {
                 evArg = Arguments[i].Eval(env);
             }
             else
             {
                 evArg = CheckStringName(argName) ? ConstantNode.EmptyString : ConstantNode.Zero;
             }
             if (evArg.IsAbort())
             {
                 return(evArg);
             }
             var econs = evArg as ConstantNode;
             if (econs == null)
             {
                 env.RuntimeError();
             }
             evaledArgs[i] = econs;
         }
         var result = func.Apply(env, evaledArgs);
         if (result == null)
         {
             result = env.RuntimeError(ERuntimeErrors.NotImplemented, Name);
         }
         return(result);
     }
     finally
     {
         env.RestoreContext();
     }
 }
Пример #20
0
 public BasicNode BuildArrayIndexes(BasicEnvironment env, out int[] indexes)
 {
     indexes = new int[Arguments.Length];
     for (int i = 0; i < indexes.Length; i++)
     {
         var val = Arguments[i].Eval(env);
         if (val.IsError())
         {
             return(val);
         }
         var cval = (val as ConstantNode)?.ToNumericConstant();
         if (cval == null)
         {
             return(env.RuntimeError("array index type mismatch"));
         }
         indexes[i] = cval.IntValue;
     }
     return(this);
 }
Пример #21
0
        public override BasicNode Eval(BasicEnvironment env)
        {
            env.InstructionCount++;
            var cons = expr.Eval(env) as NumericConstantNode;

            if (cons == null)
            {
                return(env.RuntimeError("Expression did not evaluate to a numeric constant"));
            }
            int index = cons.IntValue - 1;

            if (index < 0 || index >= labels.Length)
            {
                return(env.RuntimeError(ERuntimeErrors.OnGotoIndexInvalid, index + 1));
            }
            if (!env.Goto(labels[index], false))
            {
                return(env.RuntimeError(ERuntimeErrors.JumpToUndefinedLabel, labels[index]));
            }
            return(this);
        }
Пример #22
0
        public override BasicNode Eval(BasicEnvironment env)
        {
            env.InstructionCount++;
            own1 = to.Eval(env) as NumericConstantNode;
            own2 = step.Eval(env) as NumericConstantNode;
            if (own1 == null || own2 == null)
            {
                return(env.RuntimeError());
            }
            //if (own2.Value.IsZero)
            //	return env.RuntimeError(ERuntimeErrors.ZeroStep);
            var initVal = from.Eval(env);
            var setRes  = Var.SetValue(env, initVal);

            if (env.HasEnded)
            {
                return(this);
            }

            LoopStep(env, initVal as NumericConstantNode);
            return(this);
        }
Пример #23
0
        public override BasicNode Eval(BasicEnvironment env)
        {
            env.InstructionCount++;
            var prop = env.GetProperty(varName.Name);

            varName.Arguments = dimension;
            int[] indexes;
            var   result = varName.BuildArrayIndexes(env, out indexes);

            if (result.IsError())
            {
                return(result);
            }
            for (int i = 0; i < indexes.Length; i++)
            {
                indexes[i]++;
                if (indexes[i] <= 0)
                {
                    return(env.RuntimeError($"invalid array dimension {indexes[i]}"));
                }
            }
            // new array
            if (prop == null)
            {
                prop      = varName.IsStringName ? (Property) new ArrayProperty <StringConstantNode>(indexes) : new ArrayProperty <NumericConstantNode>(indexes);
                prop.Name = varName.Name;
                env.SetProperty(prop);
                return(this);
            }
            // change existing array
            var arrProp = prop as IArrayProperty;

            if (arrProp == null)
            {
                return(env.RuntimeError($"DIM of non array variable {varName}"));
            }
            return(arrProp.Redim(env, indexes));
        }
Пример #24
0
        public override BasicNode Eval(BasicEnvironment env)
        {
            double sum     = 0;
            bool   opMinus = false;

            for (int i = 0; i < sequence.Length; i++)
            {
                object item = sequence[i];
                string op   = item as string;
                if (op != null)
                {
                    opMinus = op == "-";
                    continue;
                }
                var arg = EvalAtIndex(i, env);
                if (arg == null)
                {
                    return(env.RuntimeError());
                }
                var argVal = (arg).Value;
                env.InstructionCount++;
                if (opMinus)
                {
                    argVal = -argVal;
                }
                if (sum != 0)
                {
                    sum += argVal;
                }
                else
                {
                    sum = argVal;
                }
            }
            return(new NumericConstantNode(sum));
        }
Пример #25
0
        BasicNode Call(BasicEnvironment env, ConstantNode[] args)
        {
            if (!env.SaveContext())
            {
                return(env.LastError);
            }
            if (argCount != args.Length)
            {
                return(env.RuntimeError("Argument count mismatch"));
            }
            for (int i = 0; i < args.Length; i++)
            {
                var prop = new ConstantProperty()
                {
                    Value = args[i],
                    Name  = parNames[i],
                };
                env.SetProperty(prop);
            }
            var result = expr.Eval(env);

            env.RestoreContext();
            return(result);
        }
Пример #26
0
        public BasicNode GetValue(BasicEnvironment env)
        {
            var prop = env.GetProperty(Name);

            if (prop == null && Arguments.Length == 0)
            {
                return(IsStringName ? ConstantNode.EmptyString : ConstantNode.Zero);
            }
            var consProp = prop as ConstantProperty;

            if (consProp != null)
            {
                if (Arguments.Length > 0)
                {
                    return(env.RuntimeError($"simple variable '{Name}' is not an array"));
                }
                return(consProp.Value);
            }
            var funcprop = prop as FunctionProperty;

            if (funcprop != null)
            {
                return(ApplyFunc(env, funcprop));
            }
            var arrProp = prop as IArrayProperty;

            if (arrProp != null)
            {
                if (arrProp.DimCount != Arguments.Length)
                {
                    return(env.RuntimeError(ERuntimeErrors.ArrayDimensionMismatch));
                }
                int[] indexes;
                var   result = BuildArrayIndexes(env, out indexes);
                if (result.IsError())
                {
                    return(result);
                }
                if (IsStringName)
                {
                    var sar = arrProp as ArrayProperty <StringConstantNode>;
                    StringConstantNode sval;
                    if (!sar.GetValue(indexes, out sval))
                    {
                        return(env.RuntimeError(ERuntimeErrors.ArrayIndexOutOfRange, Name));
                    }
                    return(sval ?? ConstantNode.EmptyString);
                }
                else
                {
                    var sar = arrProp as ArrayProperty <NumericConstantNode>;
                    NumericConstantNode sval;
                    if (!sar.GetValue(indexes, out sval))
                    {
                        return(env.RuntimeError(ERuntimeErrors.ArrayIndexOutOfRange, Name));
                    }
                    return(sval ?? ConstantNode.Zero);
                }
            }
            return(env.RuntimeError($"Call of undefined function {Name}()"));
        }
Пример #27
0
 public override BasicNode Eval(BasicEnvironment env)
 {
     env.InstructionCount++;
     return(GetValue(env));
 }
Пример #28
0
        public BasicNode SetValue(BasicEnvironment env, BasicNode value)
        {
            env.InstructionCount++;
            var prop = env.GetProperty(Name);

            if (prop == null)
            {
                if (Arguments.Length == 0)
                {
                    prop = new ConstantProperty();
                }
                else
                {
                    prop = IsStringName ? (Property) new ArrayProperty <StringConstantNode>(Arguments.Length)
                                                : new ArrayProperty <NumericConstantNode>(Arguments.Length);
                }
                prop.Name = Name;
                env.SetProperty(prop);
            }

            var consProp = prop as ConstantProperty;

            if (consProp != null)
            {
                if (Arguments.Length > 0)
                {
                    return(env.RuntimeError($"simple variable '{Name}' is not an array"));
                }
                var consValue = value as ConstantNode;
                if (consValue == null)
                {
                    return(env.RuntimeError());
                }
                consProp.Value = consValue;
                return(value);
            }
            var arrProp = prop as IArrayProperty;

            if (Arguments.Length == 0)
            {
                return(env.RuntimeError($"array '{Name}' should not be used like a simple variable"));
            }
            if (arrProp.DimCount != Arguments.Length)
            {
                return(env.RuntimeError(ERuntimeErrors.ArrayDimensionMismatch));
            }
            int[] indexes;
            var   result = BuildArrayIndexes(env, out indexes);

            if (result.IsError())
            {
                return(result);
            }
            if (IsStringName)
            {
                var sar  = arrProp as ArrayProperty <StringConstantNode>;
                var sval = value as StringConstantNode;
                if (sval == null)
                {
                    return(env.RuntimeError("type mismatch"));
                }
                if (!sar.SetValue(indexes, sval))
                {
                    return(env.RuntimeError(ERuntimeErrors.ArrayIndexOutOfRange, Name));
                }
                return(sval);
            }
            else
            {
                var sar  = arrProp as ArrayProperty <NumericConstantNode>;
                var sval = value as NumericConstantNode;
                if (sval == null)
                {
                    return(env.RuntimeError("type mismatch"));
                }
                if (!sar.SetValue(indexes, sval))
                {
                    return(env.RuntimeError(ERuntimeErrors.ArrayIndexOutOfRange, Name));
                }
                return(sval);
            }
        }
Пример #29
0
 public override BasicNode Eval(BasicEnvironment env)
 {
     return(Statement.Eval(env));
 }
Пример #30
0
 public virtual BasicNode Eval(BasicEnvironment env)
 {
     env.InstructionCount++;
     return(env.RuntimeError(ERuntimeErrors.NotImplemented, $"{this.GetType().Name}.Eval()"));
 }