Ejemplo n.º 1
0
        private void _function()
        {
            byte id = Pop();

            BytecodeFunction function = _functions[id];

            if (function == null)
            {
                throw new Exception($"function_{id} not defined.");
            }

            Console.WriteLine($"Running function_{id}");

            byte[] results = _interpretFunction(function);

            if (results == null || results.Length == 0)
            {
                return;
            }

            //TODO: check that this is all happening in order
            for (int i = 0; i < results.Length; i++)
            {
                Push(results[0]);
            }
        }
Ejemplo n.º 2
0
        public byte[] Interpret(IList <byte> bytes) //TODO: should take a stack?
        {
            BytecodeFunction function = new BytecodeFunction(bytes);

            _interpretFunction(function);

            return(_interpretFunction(_functions[0]));
        }
Ejemplo n.º 3
0
        private void _defFunction(List <byte> bytes, ref int i)
        {
            byte id = Pop();

            BytecodeFunction function = new BytecodeFunction();

            byte functionCount = 1;

            bool shouldEscapeWhileLoop = false;

            while (i < bytes.Count)
            {
                // Read the next byte from the bytecode.
                byte             value       = bytes[++i];
                InstructionsEnum instruction = (InstructionsEnum)value;

                //skip all instructions until we hit end function (still shift i for literals though)
                switch (instruction)
                {
                case InstructionsEnum.DefFunction:
                    functionCount++;
                    //TODO: consider order and things
                    function.Instructions.Add(value);
                    break;

                case InstructionsEnum.EndDefFunction:
                    functionCount--;
                    if (functionCount == 0)
                    {
                        shouldEscapeWhileLoop = true;
                    }
                    else
                    {
                        function.Instructions.Add(value);
                    }
                    break;

                case InstructionsEnum.Literal:
                    //TODO: consider order and things
                    function.Instructions.Add(value);
                    function.Instructions.Add(bytes[++i]);
                    break;

                default:
                    //TODO: consider order and things
                    function.Instructions.Add(value);
                    break;
                }

                if (shouldEscapeWhileLoop)
                {
                    break;
                }
            }

            Console.WriteLine($"Defining function_{id}");
            _functions[id] = function;
        }
Ejemplo n.º 4
0
        private void _returnSignature(BytecodeFunction function)
        {
            function.ReturnType = Pop();

            function.ShouldReturnArray = (Pop() == 1);

            if (function.ShouldReturnArray)
            {
                Console.WriteLine($"Setting signature to return type_{function.ReturnType}[]");
            }
            else
            {
                Console.WriteLine($"Setting signature to return type_{function.ReturnType}");
            }
        }
Ejemplo n.º 5
0
        private byte[] _return(BytecodeFunction function)
        {
            if (function.ReturnType == 0)
            {
                Console.Write($"Returning null");
                return(null);
            }

            byte[] returnBytes;

            if (function.ShouldReturnArray)
            {
                byte arrayLength = Pop();
                byte numFields   = _types[function.ReturnType];

                Console.WriteLine($"Returning a type_{function.ReturnType}[]");

                returnBytes = new byte[arrayLength * numFields];

                for (int i = 0; i < arrayLength; i++)
                {
                    for (int j = 0; j < numFields; j++)
                    {
                        returnBytes[(i * numFields) + (numFields - 1 - j)] = Pop(); //(numFields-1-j) is to ensure that we reverse the order they would otherwise appear in in the stack
                    }
                }

                return(returnBytes);
            }

            Console.WriteLine($"Returning a type_{function.ReturnType}");

            returnBytes = new byte[function.ReturnType];

            for (byte i = 0; i < function.ReturnType; i++)
            {
                returnBytes[i] = Pop();
            }

            return(returnBytes);
        }
Ejemplo n.º 6
0
        private byte[] _interpretFunction(BytecodeFunction function)
        {
            Console.WriteLine(this);
            int size = function.Instructions.Count;

            for (int i = 0; i < size; i++)
            {
                InstructionsEnum instruction = (InstructionsEnum)function.Instructions[i];

                //if we're in an if and the status is false
                if (ifs.Count > 0 && ifs.Peek() == false)
                {
                    //skip all instructions until we hit end if (still shift i for literals though)
                    switch (instruction)
                    {
                    case InstructionsEnum.If:
                        ifs.Push(false);     //push a false so we can handle nested ifs
                        continue;

                    case InstructionsEnum.Literal:
                        i++;
                        continue;

                    case InstructionsEnum.EndIf:
                        break;

                    default:
                        continue;
                    }
                }

                switch (instruction)
                {
                case InstructionsEnum.Literal:
                    _literal(function.Instructions, ref i);
                    break;

                case InstructionsEnum.ReturnSignature:
                    _returnSignature(function);
                    break;

                case InstructionsEnum.Add:     //should be preceded by two values to add
                    _add();
                    break;

                case InstructionsEnum.Subtract:     //should be preceded by two values to subtract
                    _subtract();
                    break;

                case InstructionsEnum.Multiply:     //should be preceded by two values to multiply
                    _multiply();
                    break;

                case InstructionsEnum.Divide:     //should be preceded by two values to divide
                    _divide();
                    break;

                case InstructionsEnum.LessThan:
                    _lessThan();
                    break;

                case InstructionsEnum.GreaterThan:
                    _greaterThan();
                    break;

                case InstructionsEnum.EqualTo:
                    _equalTo();
                    break;

                case InstructionsEnum.GreaterThanOrEqualTo:
                    _greaterThanOrEqualTo();
                    break;

                case InstructionsEnum.LessThanOrEqualTo:
                    _lessThanOrEqualTo();
                    break;

                case InstructionsEnum.If:
                    _if();
                    break;

                case InstructionsEnum.EndIf:
                    _endIf();
                    break;

                case InstructionsEnum.For:
                    _for(i);
                    break;

                case InstructionsEnum.EndFor:
                    _endFor(ref i);
                    break;

                case InstructionsEnum.DefArray:
                    _defArray();
                    break;

                case InstructionsEnum.GetArray:
                    _getArray();
                    break;

                case InstructionsEnum.GetArrayLength:
                    _getArrayLength();
                    break;

                case InstructionsEnum.GetArrayValueAtIndex:
                    _getArrayValueAtIndex();
                    break;

                case InstructionsEnum.SetArrayValueAtIndex:
                    _setArrayValueAtIndex();
                    break;

                case InstructionsEnum.DefType:
                    _defType();
                    break;

                case InstructionsEnum.DefVar:
                    _defVar();
                    break;

                case InstructionsEnum.GetVar:
                    _getVar();
                    break;

                case InstructionsEnum.SetVar:
                    _setVar();
                    break;

                case InstructionsEnum.DefFunction:
                    _defFunction(function.Instructions, ref i);
                    break;

                case InstructionsEnum.Function:
                    _function();
                    break;

                case InstructionsEnum.CustomFunction:
                    _customFunction();
                    break;

                case InstructionsEnum.Return:
                    return(_return(function));
                }

                Console.WriteLine(this);
            }

            if (function.ReturnType > 0)
            {
                throw new Exception("Missing return statement.");
            }

            return(null);
        }