Ejemplo n.º 1
0
        public async Task ArrayToTableString(byte[] output, int outputLenth = 0)
        {
            if (output.Length == 0)
            {
                throw new ArgumentException("File is empty");
            }

            if (OutputActionAsync.GetInvocationList() == null || OutputActionAsync.GetInvocationList().Length == 0)
            {
                isProgressAsync = false;
            }
            else
            {
                isProgressAsync = true;
            }

            var writingLenth = outputLenth != 0 ? outputLenth : output.Length;

            for (int i = 0; i < writingLenth; i++)
            {
                if (i % byteLineWidth == 0 && i != 0)
                {
                    if (isProgressAsync)
                    {
                        await OutputActionAsync?.Invoke("|\n");

                        await OutputActionAsync?.Invoke($"{RowLine}\n");
                    }
                    else
                    {
                        OutputAction?.Invoke("|\n");
                        OutputAction?.Invoke($"{RowLine}\n");
                    }
                }
                if (isProgressAsync)
                {
                    await OutputActionAsync?.Invoke(AlignCentre(output[i]));
                }
                else
                {
                    OutputAction?.Invoke(AlignCentre(output[i]));
                }

                WritingProgess = (double)(i + 1) / writingLenth;
            }

            Finalize?.Invoke();
        }
Ejemplo n.º 2
0
    /// <summary>
    /// Sets the raw output.
    /// Used internally.
    /// </summary>
    /// <param name="rawOutput">The raw output.</param>
    void ICanParseOutput.SetRawOutput(IEnumerable <string>?rawOutput)
    {
        string[] outputlines = Array.Empty <string>();
        T?       parsed      = default;

        if (rawOutput != null)
        {
            outputlines = rawOutput.ToArray();
            parsed      = OutputParser.Parse(outputlines);
        }

        RawOutputAction?.Invoke(outputlines);
        if (parsed != null)
        {
            OutputAction?.Invoke(parsed);
        }
    }
Ejemplo n.º 3
0
        public async Task ArrayToTableString(bool[] output, int outputLenth = 0)
        {
            if (output.Length == 0)
            {
                throw new ArgumentException("File is empty");
            }

            var writingLenth = outputLenth != 0 ? outputLenth : output.Length;

            for (int i = 0; i < writingLenth; i++)
            {
                if (i % binaryLineWidth == 0 && i != 0)
                {
                    if (isProgressAsync)
                    {
                        await OutputActionAsync?.Invoke("|\n");

                        await OutputActionAsync?.Invoke($"{RowLine}\n");
                    }
                    else
                    {
                        OutputAction?.Invoke("|\n");
                        OutputAction?.Invoke($"{RowLine}\n");
                    }
                }
                if (isProgressAsync)
                {
                    await OutputActionAsync?.Invoke($"| {Convert.ToInt16(output[i])} ");
                }
                else
                {
                    OutputAction?.Invoke($"| {Convert.ToInt16(output[i])} ");
                }

                WritingProgess = (double)(i + 1) / writingLenth;
            }

            Finalize?.Invoke();
        }
Ejemplo n.º 4
0
        public void Execute()
        {
            Random random = new Random();

            int maxX = Grid.GetLength(1);
            int maxY = Grid.GetLength(0);

            int        x          = 0;
            int        y          = 0;
            Directions direction  = 0;
            bool       stringMode = false;
            bool       skip       = false;

            while (true)
            {
                // cyclic boundaries
                if (x < 0 || y < 0 || x >= maxX || y >= maxY)
                {
                    switch (direction)
                    {
                    case Directions.Right:
                        x = 0;
                        break;

                    case Directions.Down:
                        y = 0;
                        break;

                    case Directions.Left:
                        x = maxX - 1;
                        break;

                    case Directions.Up:
                        y = maxY - 1;
                        break;
                    }
                }
                //
                char instruction = Grid[y, x];
                Debug.WriteLine($"Instruction at {x},{y} = {instruction}  string:{stringMode} skip:{skip}");

                // skip or not
                if (skip)
                {
                    skip = false; // skip instruction
                    Debug.WriteLine("BRIDGE OFF: skipping current instruction.");
                }
                // string mode or not
                else if (stringMode)
                {
                    // push instruction as string
                    if (instruction == '"')
                    {
                        Debug.WriteLine("STRING MODE OFF");
                        stringMode = false;
                    }
                    else
                    {
                        int operand = instruction;
                        Debug.WriteLine($"STRING MODE: PUSH {operand}");
                        Push(operand);
                    }
                }
                else
                {
                    switch (instruction)
                    {
                    //Push this number on the stack
                    case '0':
                    case '1':
                    case '2':
                    case '3':
                    case '4':
                    case '5':
                    case '6':
                    case '7':
                    case '8':
                    case '9':
                        int digit = instruction - 48;
                        Push(digit);
                        Debug.WriteLine($"PUSH DIGIT {digit}");
                        break;

                    //Addition: Pop a and b, then push a+b
                    case '+':
                    //Subtraction: Pop a and b, then push b-a
                    case '-':
                    //Multiplication: Pop a and b, then push a*b
                    case '*':
                    //Integer division: Pop a and b, then push b/a, rounded towards 0.
                    case '/':
                    //Modulo: Pop a and b, then push the remainder of the integer division of b/a.
                    case '%':
                        PerformMathOperation(instruction);
                        break;

                    //Logical NOT: Pop a value. If the value is zero, push 1; otherwise, push zero.
                    case '!':
                    {
                        int operand = Pop();
                        int result  = operand == 0 ? 1 : 0;
                        Debug.WriteLine($"NOT({operand})={result}");
                        Push(result);
                    }
                    break;

                    //Greater than: Pop a and b, then push 1 if b>a, otherwise zero.
                    case '`':
                    {
                        int operand2 = Pop();
                        int operand1 = Pop();
                        int result   = operand1 > operand2 ? 1 : 0;
                        Debug.WriteLine($"GREATER({operand1},{operand2})={result}");
                        Push(result);
                    }
                    break;

                    //Start moving right
                    case '>':
                        direction = Directions.Right;
                        Debug.WriteLine("MOVE RIGHT");
                        break;

                    //Start moving left
                    case '<':
                        direction = Directions.Left;
                        Debug.WriteLine("MOVE LEFT");
                        break;

                    //Start moving up
                    case '^':
                        direction = Directions.Up;
                        Debug.WriteLine("MOVE UP");
                        break;

                    //Start moving down
                    case 'v':
                        direction = Directions.Down;
                        Debug.WriteLine("MOVE DOWN");
                        break;

                    //Start moving in a random cardinal direction
                    case '?':
                        direction = (Directions)random.Next(4);
                        Debug.WriteLine($"MOVE RANDOM={direction}");
                        break;

                    //Pop a value; move right if value=0, left otherwise
                    case '_':
                    {
                        int operand = Pop();
                        direction = operand == 0
                                    ? Directions.Right
                                    : Directions.Left;
                        Debug.WriteLine($"CHANGE HORIZONTAL({operand})={direction}");
                    }
                    break;

                    //Pop a value; move down if value=0, up otherwise
                    case '|':
                    {
                        int operand = Pop();
                        direction = operand == 0
                                    ? Directions.Down
                                    : Directions.Up;
                        Debug.WriteLine($"CHANGE VERTICAL({operand})={direction}");
                    }
                    break;

                    //Start string mode: push each character's ASCII value all the way up to the next "
                    case '\"':
                        stringMode = true;
                        Debug.WriteLine("STRING MODE ON");
                        break;

                    //Duplicate value on top of the stack
                    case ':':
                    {
                        int operand = Pop();
                        Push(operand);
                        Push(operand);
                        Debug.WriteLine($"DUP({operand})");
                    }
                    break;

                    //Swap two values on top of the stack
                    case '\\':
                    {
                        int operand2 = Pop();
                        int operand1 = Pop();
                        Push(operand2);
                        Push(operand1);
                        Debug.WriteLine($"SWAP({operand1},{operand2})");
                    }
                    break;

                    //Pop value from the stack and discard it
                    case '$':
                    {
                        Pop();     // pop and discard
                        Debug.WriteLine("POP");
                    }
                    break;

                    //Pop value and output as an integer followed by a space
                    case '.':
                    {
                        int operand = Pop();
                        Debug.WriteLine($"OUT NUMBER({operand})");
                        OutputAction?.Invoke(operand.ToString());
                    }
                    break;

                    //Pop value and output as ASCII character
                    case ',':
                    {
                        int  outputAsInt = Pop();
                        char operand     = (char)(outputAsInt % 255);
                        OutputAction?.Invoke(operand.ToString());
                        Debug.WriteLine($"OUT CHAR({operand})");
                    }
                    break;

                    //Bridge: Skip next cell
                    case '#':
                        skip = true;
                        Debug.WriteLine("BRIDGE ON: skipping next instruction");
                        break;

                    //A "put" call (a way to store a value for later use). Pop y, x, and v, then change the character at (x,y) in the program to the character with ASCII value v
                    case 'p':
                    {
                        int putY     = Pop();
                        int putX     = Pop();
                        int putValue = Pop();
                        Grid[putY, putX] = (char)putValue;
                        Debug.WriteLine($"PUT({putX},{putY})={putValue}");
                    }
                    break;

                    //A "get" call (a way to retrieve data in storage). Pop y and x, then push ASCII value of the character at that position in the program
                    case 'g':
                    {
                        int getY     = Pop();
                        int getX     = Pop();
                        int getValue = Grid[getY, getX];
                        Push(getValue);
                        Debug.WriteLine($"GET({getX},{getY})={getValue}");
                    }
                    break;

                    //Ask user for a number and push it
                    case '&':
                    {
                        string inputAsString = InputFunc?.Invoke();
                        if (string.IsNullOrWhiteSpace(inputAsString))
                        {
                            Debug.WriteLine("IN NUMBER failed: null or empty input");
                        }
                        else
                        {
                            int operand;
                            if (!int.TryParse(inputAsString, out operand))
                            {
                                Debug.WriteLine($"IN NUMBER failed: invalid input {inputAsString}");
                            }
                            else
                            {
                                Push(operand);
                                Debug.WriteLine($"IN NUMBER({operand})");
                            }
                        }
                    }
                    break;

                    //Ask user for a character and push its ASCII value
                    case '~':
                    {
                        string inputAsString = InputFunc?.Invoke();
                        if (string.IsNullOrEmpty(inputAsString))
                        {
                            Debug.WriteLine("IN CHAR failed: null or empty input");
                        }
                        else
                        {
                            int inputChar = inputAsString[0] % 255;
                            Debug.WriteLine($"IN CHAR({inputChar})");
                            Push(inputChar);
                        }
                    }
                    break;

                    //End program
                    case '@':
                        Debug.WriteLine("END OF PROGRAM");
                        return;

                    //NOP
                    case ' ':
                        Debug.WriteLine("NOP");
                        break;

                    //Unknown instruction
                    default:
                        Debug.WriteLine($"Unknown instruction:{instruction}");
                        break;
                    }
                }
                // Move instruction pointers according to direction
                MoveDirectionUntilInstructionFound(direction, stringMode, ref x, ref y);
            }
        }
Ejemplo n.º 5
0
        /*
         *       Lightness
         * Hue   0         1           2
         * 0    /         push        pop
         * 1    add       sub         mul
         * 2    div       mod         not
         * 3    greater   pointer     switch
         * 4    dup       roll        in number
         * 5    in char   out number  out char
         */

        private void PerformInstruction(int fromColorIndex, int toColorIndex, int codelCount)
        {
            int hueDiff       = HueDiff(fromColorIndex, toColorIndex);
            int lightnessDiff = LightnessDiff(fromColorIndex, toColorIndex);

            Debug.WriteLine($"PerformInstruction: From{ColorIndexToString(fromColorIndex)} to {ColorIndexToString(toColorIndex)} => Hue:{hueDiff} Lightness:{lightnessDiff}");

            switch (hueDiff)
            {
            case 0:     // NOP, Push, Pop
                switch (lightnessDiff)
                {
                case 0:         // NOP
                    Debug.WriteLine("Action: NOP");
                    break;

                case 1:         // Push
                    Debug.WriteLine($"Action: PUSH {codelCount}");
                    Stack.Push(codelCount);
                    break;

                case 2:         // Pop
                    if (Stack.Count == 0)
                    {
                        Debug.WriteLine("Action: POP failed: stack underflow");
                    }
                    else
                    {
                        Debug.WriteLine("Action: POP");
                        Stack.Pop();         // Pop and discard
                    }
                    break;
                }
                break;

            case 1:     // Add, Sub, Mul
                switch (lightnessDiff)
                {
                case 0:         // Add
                    // Pop 2 values, add them and push back result
                    PerformMathOperation('+');
                    break;

                case 1:         // Sub
                    // Pop 2 values, sub (top from second top) them and push back result
                    PerformMathOperation('-');
                    break;

                case 2:         // Mul
                    // Pop 2 values, multiply them and push back result
                    PerformMathOperation('*');
                    break;
                }
                break;

            case 2:     // Div, Mod, Not
                switch (lightnessDiff)
                {
                case 0:         // Div
                    // Pop 2 values, divide (second top by top) them and push back result
                    PerformMathOperation('/');
                    break;

                case 1:         // Mod
                    // Pop 2 values, mod (second top modulo top) them and push back result
                    PerformMathOperation('%');
                    break;

                case 2:         // Not
                    // Pop 1 value, not (0->1, 0 otherwise) it and push back result
                    if (Stack.Count == 0)
                    {
                        Debug.WriteLine("Action: NOT failed: stack underflow");
                    }
                    else
                    {
                        int operand = Stack.Pop();
                        int result  = operand == 0
                                    ? 1
                                    : 0;
                        Debug.WriteLine($"Action: NOT({operand})={result}");
                        Stack.Push(result);
                    }
                    break;
                }
                break;

            case 3:     // greater, pointer, switch
                switch (lightnessDiff)
                {
                case 0:         // Greater
                    // Pop 2 values, if second top > top push 1, push 0 otherwise
                    if (Stack.Count < 2)
                    {
                        Debug.WriteLine("Action: GREATER failed: stack underflow");
                    }
                    else
                    {
                        int operand2 = Stack.Pop();
                        int operand1 = Stack.Pop();
                        int result   = operand1 > operand2
                                    ? 1
                                    : 0;
                        Debug.WriteLine($"Action: GREATER({operand1},{operand2})={result}");
                        Stack.Push(result);
                    }
                    break;

                case 1:         // Pointer
                    // Pop 1 value, turn DP clockwise if positive, counterclockwise otherwise
                    if (Stack.Count == 0)
                    {
                        Debug.WriteLine("Action: POINTER failed: stack underflow");
                    }
                    else
                    {
                        int operand    = Stack.Pop();
                        int absOperand = operand;
                        Func <PointerDirections, PointerDirections> func;
                        if (absOperand > 0)
                        {
                            func = TurnDirectionPointerClockwise;
                        }
                        else
                        {
                            absOperand = -absOperand;
                            func       = TurnDirectionPointerCounterClockwise;
                        }
                        for (int i = 0; i < absOperand % 4; i++)
                        {
                            DirectionPointer = func(DirectionPointer);
                        }
                        Debug.WriteLine($"Action: POINTER({operand})={DirectionPointer}");
                    }
                    break;

                case 2:         // Switch
                    // Pop 1 value, toggle CC that many times
                    if (Stack.Count == 0)
                    {
                        Debug.WriteLine("Action: SWITCH failed: stack underflow");
                    }
                    else
                    {
                        int operand = Stack.Pop();
                        for (int i = 0; i < operand % 4; i++)
                        {
                            CodelChooser = ToggleCodelChooser(CodelChooser);
                        }
                        Debug.WriteLine($"Action: SWITCH({operand})={CodelChooser}");
                    }
                    break;
                }
                break;

            case 4:     // dup, roll, in number
                switch (lightnessDiff)
                {
                case 0:         // Duplicate
                    // Push a copy of top value
                    if (Stack.Count == 0)
                    {
                        Debug.WriteLine("Action: DUPLICATE failed: stack underflow");
                    }
                    else
                    {
                        int operand = Stack.Peek();
                        Stack.Push(operand);
                        Debug.WriteLine($"Action: DUPLICATE({operand})");
                    }
                    break;

                case 1:         // Roll
                    // Pop 2 values, roll remaining stack entries to a depth equals to the second top by a number of rolls equal to top (see http://www.dangermouse.net/esoteric/piet.html)
                    //  roll of depth k: move top at position k in stack and move up every value above k'th position
                    if (Stack.Count < 2)
                    {
                        Debug.WriteLine("Action: ROLL failed: stack underflow");
                    }
                    else
                    {
                        int roll  = Stack.Pop();
                        int depth = Stack.Pop();
                        if (depth < 0)
                        {
                            Debug.WriteLine($"Action: ROLL failed: negative depth {depth}");
                        }
                        else if (Stack.Count < depth)
                        {
                            Debug.WriteLine($"Action: ROLL failed: stack underflow {depth}");
                        }
                        else
                        {
                            Stack.Roll(roll, depth);
                        }
                    }
                    break;

                case 2:         // In number
                    // Read a number from stdin and push it
                    string inputAsString = InputFunc?.Invoke();
                    int    inputNumber;
                    if (!int.TryParse(inputAsString, out inputNumber))
                    {
                        Debug.WriteLine($"Action: IN NUMBER failed: invalid input {inputAsString}");
                    }
                    else
                    {
                        Debug.WriteLine($"Action: IN NUMBER({inputNumber})");
                        Stack.Push(inputNumber);
                    }
                    break;
                }
                break;

            case 5:     // in char, out number, out char
                switch (lightnessDiff)
                {
                case 0:         // In char
                    // Read a char from stdin and push it
                    string inputAsString = InputFunc?.Invoke();
                    if (string.IsNullOrEmpty(inputAsString))
                    {
                        Debug.WriteLine("Action: IN CHAR failed: null or empty input");
                    }
                    else
                    {
                        int inputChar = inputAsString[0] % 255;
                        Debug.WriteLine($"Action: IN CHAR({inputChar})");
                        Stack.Push(inputChar);
                    }
                    break;

                case 1:         // Out number
                    // Pop 1 value, print it on stdout as number
                    if (Stack.Count == 0)
                    {
                        Debug.WriteLine("Action: OUT NUMBER failed: stack underflow");
                    }
                    else
                    {
                        int operand = Stack.Pop();
                        Debug.WriteLine($"Action: OUT NUMBER({operand})");
                        OutputAction?.Invoke(operand.ToString());
                    }
                    break;

                case 2:         // Out char
                    // Pop 1 value, print it on stdout as char
                    if (Stack.Count == 0)
                    {
                        Debug.WriteLine("Action: OUT CHAR failed: stack underflow");
                    }
                    else
                    {
                        int  outputAsInt = Stack.Pop();
                        char operand     = (char)(outputAsInt % 255);
                        Debug.WriteLine($"Action: OUT CHAR({operand})");
                        OutputAction?.Invoke(operand.ToString());
                    }
                    break;
                }
                break;
            }
        }
Ejemplo n.º 6
0
        public void Execute()
        {
            Debug.WriteLine("Execution start");
            // init registers
            int a = 0; // accumulator
            int c = 0; // code pointer
            int d = 0; // data pointer

            while (true)
            {
                int instruction = Memory[c];
                if (instruction > 32 && instruction < 127) // [33-126]
                {
                    int  opCodeEncrypted = (c + instruction - 33) % 94;
                    char opCode          = DecryptionTable[opCodeEncrypted];
                    Debug.WriteLine($"Opcode:{opCodeEncrypted} => {opCode}");

                    // Perform instruction
                    switch (opCode)
                    {
                    case 'j':     // 40: mov d,[d]
                        Debug.WriteLine("Instruction: MOV");
                        d = Memory[d];
                        break;

                    case 'i':     // 4: jmp[d]
                        Debug.WriteLine("Instruction: JMP");
                        c = Memory[d];
                        break;

                    case '*':     // 39: rotr [d] | mov a,d
                        Debug.WriteLine("Instruction: ROTR");
                        Memory[d] = Memory[d] / 3 + Memory[d] % 3 * 19683;
                        a         = Memory[d];
                        break;

                    case 'p':     // 62: crazy [d],a | mov a,[d]
                        Debug.WriteLine("Instruction: CRAZY");
                        Memory[d] = Crazy(a, Memory[d]);
                        a         = Memory[d];
                        break;

                    case '<':     // 5: stdout
                        Debug.WriteLine("Instruction: STDOUT");
                        OutputAction?.Invoke((char)(a & 0xFF));
                        break;

                    case '/':     // 23: stdin
                        Debug.WriteLine("Instruction: STDIN");
                        char?input = InputFunc?.Invoke();
                        if (input == null)
                        {
                            Debug.WriteLine("Null input");
                        }
                        else
                        {
                            if (input.Value == '\n')
                            {
                                a = 10;
                            }
                            //else if (input == EOF) // TODO
                            //  a = int.MaxValue;
                            else
                            {
                                a = input.Value;
                            }
                        }
                        break;

                    case 'v':     // 81: end
                        Debug.WriteLine("Instruction: END OF PROGRAM");
                        return;

                    case 'o':     // 68: nop
                        Debug.WriteLine("Instruction: NOP");
                        break;

                    default:
                        Debug.WriteLine("Instruction: INVALID");
                        break;
                    }

                    // Encrypt instruction
                    Memory[c] = EncryptionTable[Memory[c] - 33];
                    // Advance c and d
                    if (c == MaxValue)
                    {
                        c = 0;
                    }
                    else
                    {
                        c++;
                    }
                    if (d == MaxValue)
                    {
                        d = 0;
                    }
                    else
                    {
                        d++;
                    }
                }
                else
                {
                    Debug.WriteLine($"Skipping invalid instruction {instruction}");
                }
            }
        }