예제 #1
0
        public void Execute(State state)
        {
            var tmpValues = new Stack <IValue>();

            for (int i = 0; i < _argumentCount; i++)
            {
                var val = state.Stack.Pop();
                tmpValues.Push(val);
            }

            var callingClass    = state.Stack.Pop().Get <Class>();
            var callingInstance = state.Stack.Pop().Get <Instance>();

            for (int i = 0; i < _argumentCount; i++)
            {
                state.Stack.Push(tmpValues.Pop());
            }

            if (callingClass.TryGetFunction(_functionName.As <StringValue>().Item, out var membFunc))
            {
                PushCall(state, _argumentCount, membFunc, callingInstance);
            }
            else if (state.Environment.ExtensionFunctions.TryGetValue(
                         $"{callingClass.FullName}->{_functionName.As<StringValue>().Item}", out var extensionFunc))
            {
                PushCall(state, _argumentCount, extensionFunc, callingInstance);
            }
            else
            {
                throw ThrowHelper.MemberFunctionNotFound(_functionName.As <StringValue>().Item, callingClass.FullName);
            }
        }
예제 #2
0
        public void Execute(State state)
        {
            var value = state.Scopes.Peek().GetVariable(_name.As <StringValue>().Item);

            if (value == null)
            {
                throw ThrowHelper.VariableNotFound(_name.As <StringValue>().Item);
            }
            state.Stack.Push(value);
        }
예제 #3
0
        public void Execute(State state)
        {
            var instance = state.Stack.Pop().Get <IScope>();
            var member   = instance.GetVariable(_memberName.As <StringValue>().Item);

            if (member == null)
            {
                throw ThrowHelper.VariableNotFound(_memberName.As <StringValue>().Item);
            }
            state.Stack.Push(member);
        }
예제 #4
0
        public void Execute(State state)
        {
            var argCount = state.Stack.Pop().Get <int>();

            if (!state.Environment.Classes.TryGetValue(_className.As <StringValue>().Item, out var clas))
            {
                throw ThrowHelper.ClassNotFound(_className.As <StringValue>().Item);
            }
            var instScope   = new Scope();
            var newInstance = new Instance(instScope, clas);
            // figure out which constructor to call (should probably do that in the parser though)
            var ctor = clas.Constructors.FirstOrDefault(c => c.Arguments.Count == argCount);

            if (ctor == null && argCount > 0)
            {
                throw ThrowHelper.ConstructorNotFound(argCount, _className.As <StringValue>().Item);
            }
            else if ((ctor == null && argCount == 0) || ctor?.Length == 1)
            {
                ctor = clas.CtorForMembersWithValues;
            }
            state.Frames.Push(new CallFrame(ctor));
            state.Scopes.Push(instScope);
            if (argCount == 0)
            {
                // push instance to return
                state.Stack.Push(state.ValueFactory.Instance(newInstance));
                // push new instance for constructor to be used for 'me' token to refer to self
                state.Stack.Push(state.ValueFactory.Instance(newInstance));
            }
            else
            {
                var args = new List <IValue>();
                // get args from stack
                for (int i = 0; i < argCount; i++)
                {
                    args.Add(state.Stack.Pop());
                }

                // push instance to return
                state.Stack.Push(state.ValueFactory.Instance(newInstance));

                // push args for constructor
                for (int i = 0; i < argCount; i++)
                {
                    state.Stack.Push(args[i]);
                }

                // push new instance for constructor to be used for 'me' token to refer to self
                state.Stack.Push(state.ValueFactory.Instance(newInstance));
            }
        }
예제 #5
0
        public void Execute(State state)
        {
            var funcName = _name?.As <StringValue>().Item ??
                           state.Stack.Pop().As <InternalStringValue>().Item;

            var callArgCount = state.Stack.Pop().Get <int>();

            if (state.Environment.Functions.TryGetValue($"{SpecialVariables.Global}::{funcName}", out var globalFunc))
            {
                VerifyArgumentCount(globalFunc, callArgCount); // not sure if it's worth making this check during the parsing stage
                state.Frames.Push(new CallFrame(globalFunc));
            }
            else if (state.Environment.Functions.TryGetValue(funcName, out var func))
            {
                VerifyArgumentCount(func, callArgCount);
                state.Frames.Push(new CallFrame(func));
            }
            else
            {
                throw ThrowHelper.FunctionNotFound(funcName);
            }

            var currentScope = state.Scopes.Peek();

            state.Scopes.Push(new Scope(currentScope));
        }
예제 #6
0
파일: MemberSet.cs 프로젝트: Szune/eilang
        public void Execute(State state)
        {
            var value = state.Stack.Pop();
            var scope = state.Stack.Pop().Get <IScope>();

            scope.SetVariable(_memberName.As <StringValue>().Item, value);
        }
예제 #7
0
        public void Execute(State state)
        {
            var argLength = state.Stack.Pop().Get <int>();
            var function  = _functionName.As <StringValue>().Item;

            if (argLength == 0)
            {
                var result =
                    state.Environment.ExportedFunctions[function](state,
                                                                  Arguments.Create(state.ValueFactory.Void(), function));
                state.PushIfNonVoidValue(result);
            }
            else if (argLength == 1)
            {
                var val    = state.Stack.Pop();
                var result = state.Environment.ExportedFunctions[function](state,
                                                                           Arguments.Create(val, function));
                state.PushIfNonVoidValue(result);
            }
            else
            {
                var values = new List <IValue>();
                for (int i = 0; i < argLength; i++)
                {
                    values.Add(state.Stack.Pop());
                }

                var list   = state.ValueFactory.List(values);
                var result = state.Environment.ExportedFunctions[function](state,
                                                                           Arguments.Create(list, function));
                state.PushIfNonVoidValue(result);
            }
        }
예제 #8
0
        private static object ConvertArgument(IValue value)
        {
            switch (value.Type)
            {
            case EilangType.String:
                return(value.As <StringValue>().Item);   // TODO: make this work

            case EilangType.Integer:
            case EilangType.Long:
            case EilangType.Double:
            case EilangType.Bool:
            case EilangType.IntPtr:
                return(value.Value);

            case EilangType.Instance:
                if (value is StructInstanceValue strut)
                {
                    return(ConvertStructArgument(strut));
                }
                break;

            case EilangType.Uninitialized:
                return(null);
            }
            throw ThrowHelper.InvalidArgumentType("interop::invoke_func", "...", value, ValidInteropTypes);
        }
예제 #9
0
        public void Execute(State state)
        {
            var jumpIfTrue = state.Stack.Pop().Get <bool>();

            if (jumpIfTrue == true)
            {
                state.Frames.Peek().Address = _address.As <IntegerValue>().Item - 1;
                // - 1 because we need to adjust for the address++ at the start of the next iteration of the loop
            }
        }
예제 #10
0
        public ArgumentList Build()
        {
            var list = _value.As <ListValue>()?.Item;

            if (list == null)
            {
                if (_arguments.Count == 0)
                {
                    return(new ArgumentList(new List <IArgument> {
                        new RequiredArgument(_value)
                    }, _function));
                }
                else
                {
                    throw BuildException(_function, _arguments);
                }
            }

            list.Reverse(); // fix the ordering

            if (list.Count < _arguments.Count)
            {
                throw BuildException(_function, _arguments);
            }

            var validatedArguments = new List <IArgument>();
            var paramsArguments    = new List <IValue>();

            // validate up to the given arguments, which should be at least the required amount
            for (var i = 0; i < list.Count; i++)
            {
                if (i > _arguments.Count - 1) // params arguments after all the required arguments
                {
                    paramsArguments.Add(list[i]);
                }
                else
                {
                    var validated = _arguments[i].Validate(list[i], _function);
                    validatedArguments.Add(validated);
                }
            }

            validatedArguments.Add(new ParamsArgument(paramsArguments));

            return(new ArgumentList(validatedArguments, _function));
        }
예제 #11
0
        public static ArgumentList Build(IValue value, string function, List <IArgumentValidator> arguments)
        {
            var list = value.As <ListValue>()?.Item;

            if (list == null)
            {
                throw BuildException(function, arguments);
            }

            list.Reverse(); // fix the ordering

            var(optionalCount, requiredCount) = CountArguments(arguments);
            if (list.Count < requiredCount || list.Count > optionalCount + requiredCount)
            {
                throw BuildException(function, arguments);
            }

            var validatedArguments = new List <IArgument>();

            // validate up to the given arguments, which should be at least the required amount
            for (var i = 0; i < arguments.Count; i++)
            {
                IArgument validated;
                if (i > list.Count - 1) // optionals that were not supplied
                {
                    validated = arguments[i].Validate(null, function);
                }
                else
                {
                    validated = arguments[i].Validate(list[i], function);
                }

                validatedArguments.Add(validated);
            }

            return(new ArgumentList(validatedArguments, function));
        }
예제 #12
0
        public void Execute(State state)
        {
            var value = state.Stack.Pop();

            state.Scopes.Peek().SetVariable(_name.As <StringValue>().Item, value);
        }
예제 #13
0
 public void Execute(State state)
 {
     state.Frames.Peek().Address = _address.As <IntegerValue>().Item - 1;
 }
예제 #14
0
 public void Execute(State state)
 {
     state.Stack.Push(state.TemporaryVariables.Peek().GetVariable(_variableName.As <StringValue>().Item));
 }
예제 #15
0
        public void Execute(State state)
        {
            var val = state.Stack.Pop();

            state.TemporaryVariables.Peek().SetVariable(_variableName.As <StringValue>().Item, val);
        }