Пример #1
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);
        }
Пример #2
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));
        }
Пример #3
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}()"));
        }
Пример #4
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);
            }
        }