BlueBear icon

nameless_interpreter.c

BlueBear | PRO | 02/17/17 01:22:37 PM UTC | 0 ⭐ | 528 👁️ | Never ⏰ | []
C |

8.02 KB

|

None

|

0 👍

/

0 👎

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <assert.h>
 
/*
Opcodes for the Nameless Language VM
*/
enum Opcode
{
    OP_MOVR = 0,    //(0000)   Move the pointer to the right    
    OP_MOVL = 1,    //(0001)   Move the pointer to the left
    OP_INC = 2,     //(0010)   Increment the memory cell under the pointer
    OP_DEC = 3,     //(0011)   Decrement the memory cell under the pointer
    OP_POP = 4,     //(0100)   Output the character signified by the cell at the pointer
    OP_PUSH = 5,    //(0101)   Input a character and store it in the cell at the pointer
    OP_JEZ = 6,     //(0110)   Jump past the matching 0111 if the cell under the pointer is 0
    OP_JNZ = 7,     //(0111)   Jump back to the matching 0110 if the cell under the pointer is nonzero
    OP_ADD = 8,     //(1000)   Add the next command's base 10 equivalent to the current cell
    OP_SUB = 9,     //(1001)   Subtract the next command's base 10 equivalent to the current cell
    OP_NOP = 10,    //(1010)   No Operation
    OP_CLC = 11,    //(1011)   Reset the current cell's value to 0
    OP_CLPTR = 12   //(1100)   Reset the pointer to point at cell 0
};
 
typedef struct VM
{
    unsigned int tapeSize;      //tape size in elements
    unsigned int *program;      //program to run in VM
    unsigned int programLength; //total program length
    unsigned int SP;            //pointer to tape memory (stack pointer)
    unsigned int PC;            //pointer to program memory
    char *tape;                 //growable memory
} VirtualMachine;
 
unsigned int ConvertBinaryStringToUInt(const char *bstring);
size_t __cdecl strlen_ojeb(const char* text);
void PrecompileSource(const char *source, unsigned int **program, unsigned int *programLength);
 
VirtualMachine *VM_Initialize(unsigned int *source, unsigned int programLength, unsigned int tapesize);
void VM_Run(VirtualMachine *vm);
 
int main(void)
{
    /* hello world program [currently not working due to lack of the jump commands] */
    const char *hello = "   00100010001000100010001000100010\
                            0110\
                            00000010001000100010\
                            0110\
                            000000100010\
                            0000001000100010\
                            0000001000100010\
                            00000010\
                            00010001000100010011\
                            0111\
                            00000010\
                            00000010\
                            00000011\
                            000000000010\
                            011000010111\
                            00010011\
                            0111\
                            000000000100\
                            00000011001100110100\
                            0010001000100010001000100010010001000010001000100100\
                            000000000100\
                            000100110100\
                            00010100\
                            0010001000100100\
                            0011001100110011001100110100\
                            001100110011001100110011001100110100\
                            0000000000100100";
 
    /* reads 5 chars from the input, and outputs them and increments them before outputting [works] */
    const char *cat = "010100100000\
                            010100100000\
                            010100100000\
                            010100100000\
                            01010010\
                            1100\
                            01000000\
                            01000000\
                            01000000\
                            01000000\
                            01000000";
 
    /* reads and prints out one char [works] */
    const char *pushpop = "010100100100";
 
    unsigned int *compiledProgram = NULL;
    unsigned int programLength = 0;
    
    PrecompileSource(pushpop, &compiledProgram, &programLength);
 
    VirtualMachine *environment = NULL;
    environment = VM_Initialize(compiledProgram, programLength, 100);
    assert(environment != NULL);
 
    VM_Run(environment);
    
    getchar();
    getchar();
 
 
    return 0;
}
 
/*
@procedure(VM_Run)
 
This function is responsible for decoding the opcode and executing the operation over the Virtual Machine
@param(vm): The Virtual Machine environment over which the Nameless program runs
@param(opcode): The 4bit buffer containing one opcode
*/
void VM_Run(VirtualMachine *vm)
{
    int loopcnt = 0;
    while (vm->PC != vm->programLength)
    {
        
        int op = vm->program[vm->PC];
        switch (op)
        {
        case OP_MOVR: //(0000)   Move the pointer to the right
        {
            if (vm->SP == vm->tapeSize - 1)
            {
                vm->SP = 0;
            }
            else
            {
                vm->SP++;
            }
            break;
        }
        case OP_MOVL: //(0001)   Move the pointer to the left
        {
            if (vm->SP == 0)
            {
                vm->SP = vm->tapeSize - 1;
            }
            else
            {
                vm->SP--;
            }
            break;
        }
        case OP_INC: //(0010)   Increment the memory cell under the pointer
        {
            vm->tape[vm->SP]++;
            break;
        }
        case OP_DEC: //(0011)   Decrement the memory cell under the pointer
        {
            vm->tape[vm->SP]--;
            break;
        }
        case OP_POP: //(0100)   Output the character signified by the cell at the pointer
        {
            char c = vm->tape[vm->SP];
            printf("%c", c);
            break;
        }
        case OP_PUSH: //(0101)   Input a character and store it in the cell at the pointer
        {
            scanf(" %c", &vm->tape[vm->SP]);
            break;
        }
        case OP_JEZ: //(0110)   Jump past the matching 0111 if the cell under the pointer is 0
        {
            break;
        }
        case OP_JNZ: //(0111)   Jump back to the matching 0110 if the cell under the pointer is nonzero
        {
            break;
        }
        case OP_ADD: //(1000)   Add the next command's base 10 equivalent to the current cell
        {
            vm->tape[vm->SP] += vm->program[vm->PC + 1];
            break;
        }
        case OP_SUB: //(1001)   Subtract the next command's base 10 equivalent to the current cell
        {
            vm->tape[vm->SP] -= vm->program[vm->PC + 1];
            break;
        }
        case OP_NOP: //(1010)   No Operation
        {
            //No Operation
            break;
        }
        case OP_CLC: //(1011)   Reset the current cell's value to 0
        {
            vm->tape[vm->SP] = 0;
            break;
        }
        case OP_CLPTR: //(1100)   Reset the pointer to point at cell 0
        {
            vm->SP = 0;
            break;
        }
        }
        
        vm->PC++;
    }
}
 
/*
@function(VM_Initialize)
 
Initializes the Virtual Machine with a program and creates a tape with [tapesize] number of cells
@param(source): The Nameless Language program source
@param(tapesize): The size of the tape memory to be created
@return(vm): The pre-created and allocated virtual machine ready to use
*/
VirtualMachine *VM_Initialize(unsigned int *source, unsigned int programLength, unsigned int tapesize)
{
    VirtualMachine *vm = (VirtualMachine *)malloc(sizeof(VirtualMachine));
 
    vm->tape = (char *)calloc(tapesize, sizeof(char));
    vm->tapeSize = tapesize;
    vm->program = source;
    vm->programLength = programLength;
    vm->SP = 0;
    vm->PC = 0;
 
    return vm;
}
 
/*
@function(PrecompileSource)
 
"Precompiles" the source to base10 ordinal array (unsigned int []) and removes bad input and/or comments
@param(source): The Nameless Language program source
@param(program): The program to be precompiled
@param(programLength): The precompiled program length
*/
void PrecompileSource(const char *source, unsigned int **program, unsigned int *programLength)
{
    unsigned int compiled[10000];
    register unsigned int len = strlen_ojeb(source);
    register unsigned int srclen = 0;
    char op[5];
    op[4] = '\0';
 
    for (register int i = 0; i < len; i++)
    {
        if (source[i] == '0' || source[i] == '1')
        {
            register int cnt = srclen % 4;
            op[cnt] = source[i];
            srclen++;
            if (cnt == 3)
            {
                compiled[(*programLength)] = ConvertBinaryStringToUInt(op);
                (*programLength)++;
            }
        }
    }
    *program = compiled;
}
 
/*
@function(ConvertBinaryStringToUInt)
 
Converts the binary string into a decimal number
@param(bstring): The binary number as string
@return(total): The base10 value of the binary string
*/
unsigned int ConvertBinaryStringToUInt(const char *bstring)
{
    const char* start = &bstring[0];
    unsigned int total = 0;
    while (*start)
    {
        total <<= 1;
        if (*start++ == '1')
        {
            total ^= 1;
        }
    }
    return total;
}
 
/*
@function(strlen_ojeb)
 
This string length function is here only because it is a bit faster code than in the standard library, feel free to use your own
@param(text): The text which length we want to know
@return(): The string length
*/
size_t __cdecl strlen_ojeb(const char* text)
{
    const char *s;
    const uint32_t* pdwText;
    register uint32_t dwText;
 
    pdwText = (uint32_t*)text;
    while (1)
    {
        dwText = *pdwText;
 
        if ((dwText - 0x01010101UL) & ~dwText & 0x80808080UL)
        {
            s = (const char*)pdwText;
            while (*s)
            {
                s++;
            }
            return s - text;
        }
        pdwText++;
    }
}

Comments

  •  icon
    01/01/70 12:00:00 AM UTC
    Plain Text |

    0 B

    |

    👍

    /

    👎

    
        
  • Suikzau icon
    03/31/26 10:09:55 PM UTC
    text |

    0 B

    |

    0 👍

    /

    0 👎

    Best t33n active cpx link daily updates!
     Copy and paste the link in a new browser tab and then hit enter!
     https://crazyporn.@xxx/members/157354/?asgtbndr=1&play=true&spon=adworld&zone=400
     Remove the @ 
  • Zyubi icon
    04/05/26 02:29:15 AM UTC
    text |

    0 B

    |

    0 👍

    /

    0 👎

    Best t33n active cpx link daily updates!
     Copy and paste the link in a new browser tab and then hit enter!
     https://crazyporn.xxx/members/157354/?asgtbndr=1&play=true&spon=adworld&zone=400