<commit_before>#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <limits.h>

#include "slvm.h"

/* Built-in Constants
 *****************************************************************************/
/** The argument stack */
val_t ArgStack[ARG_STACK_SIZE];

/** Pointer to current position on the stack */
val_t* ArgStackPtr = ArgStack-1;

/** Pointer to current instruction being executed */
val_t* CodePtr = 0;

/** A state variable used to flag when the interpreter reads a line of input */
val_t Line_Read = 0;

/* Built-in Constants
 *****************************************************************************/
void docolon(val_t* code) {
    word_t* word;
    /* We may have previously been executing a word so we should save off our
     * previous position */
    val_t* prev_code = CodePtr;
    /* Set the next instruction to execute */
    CodePtr = code;
    /* And loop through until we get the bytecode instruction of 0 (NEXT) */
    while(CodePtr)
    {
        word = (word_t*)*CodePtr;
        /* Increment the instruction pointer */
        CodePtr++;
        /* Execute the byte code instruction */
        word->codeword(CodePtr);
    }
    /* Execution finished lets put things back the way they were */
    CodePtr = prev_code;
}

/* Built-in Constants
 *****************************************************************************/
defconst("VERSION", version, 0, NULL,     1);
defconst("EXECDEF", execdef, 0, &version, (val_t)&docolon);
defconst("WORDSZ",  wordsz,  0, &execdef, sizeof(val_t));

/* Built-in Variables
 *****************************************************************************/
defvar("state",  state,  0, &wordsz, 0);
defvar("latest", latest, 0, &state,  0);

/* Word Words
 *****************************************************************************/
defcode("wlink", wlink, 0, &latest){
    *(ArgStackPtr) = (val_t)(((word_t*)*(ArgStackPtr))->link);
}

defcode("wsize", wflags, 0, &wlink){
    *(ArgStackPtr) = (val_t)(((word_t*)*(ArgStackPtr))->flags.codesize);
}

defcode("wname", wname, 0, &wflags){
    *(ArgStackPtr) = (val_t)(((word_t*)*(ArgStackPtr))->name);
}

defcode("wfunc", wfunc, 0, &wname){
    *(ArgStackPtr) = (val_t)(((word_t*)*(ArgStackPtr))->codeword);
}

defcode("wcode", wcode, 0, &wfunc){
    *(ArgStackPtr) = (val_t)(((word_t*)*(ArgStackPtr))->code);
}

defcode("here", here, 0, &wcode){
    ArgStackPtr++;
    *(ArgStackPtr) = (val_t)((((word_t*)latest_val)->flags.codesize) - 1);
}

/* Input/Output Words
 *****************************************************************************/
defvar("stdin",  _stdin,  0, &here,    0);
defvar("stdout", _stdout, 0, &_stdin,  0);
defvar("stderr", _stderr, 0, &_stdout, 0);

defconst("F_R",  f_r,  0, &_stderr, (val_t)"r");
defconst("F_W",  f_w,  0, &f_r,     (val_t)"w");
defconst("F_A",  f_a,  0, &f_w,     (val_t)"a");
defconst("F_R+", f_ru, 0, &f_a,     (val_t)"r+");
defconst("F_W+", f_wu, 0, &f_ru,    (val_t)"w+");
defconst("F_A+", f_au, 0, &f_wu,    (val_t)"a+");

defcode("fopen",  _fopen,  0, &f_au){
    *(ArgStackPtr-1) = (val_t)fopen( (const char*)*(ArgStackPtr-1), (const char*)*(ArgStackPtr) );
    ArgStackPtr--;
}

defcode("fclose", _fclose, 0, &_fopen){
    fclose((FILE*)*(ArgStackPtr));
    ArgStackPtr--;
}

defcode("fflush", _fflush, 0, &_fclose){
    fflush((FILE*)*(ArgStackPtr));
}

defcode("fgetc",  _fgetc,  0, &_fflush){
    ArgStackPtr++;
    *(ArgStackPtr) = fgetc((FILE*)*(ArgStackPtr-1));
}

defcode("fputc",  _fputc,  0, &_fgetc){
    fputc((char)*(ArgStackPtr), (FILE*)*(ArgStackPtr-1));
    ArgStackPtr--;
}

defcode("fpeekc", _fpeekc, 0, &_fputc){
    ArgStackPtr++;
    *(ArgStackPtr) = fgetc((FILE*)*(ArgStackPtr-1));
    ungetc((char)*(ArgStackPtr), (FILE*)*(ArgStackPtr-1));
}

/* Input Words
 *****************************************************************************/
defcode("getc", get_char, 0, &_fpeekc){
    ArgStackPtr++;<commit_msg>Added wish list comment to track possible features<commit_after>#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <limits.h>
#include "slvm.h"

/*
    Wish List:

    * Rework Interpreter With Custom Syntax
    * Add Dictionary Typedef
    * Dynamic Loading and Unloading of Dictionaries (File, Object, or Dynamic Lib)
    * Rework w* words to allow gettign and setting attributes of a word
    * Add optional debugging words
    * Add optional floating point / fixed point words
    * Add optional runtime integrity checks
    * Add optional static heap replacement for malloc, realloc, free
    * Add optional support for embedded systems (No dependence on stdlib)
    * Run through profiler and optimize execution speed where possible.
    * Add optional support for temporaries
    * Add optional code optimizer for compiled words
    * Add ability to compile to simple object file
    * Add ability to compile to shared library
    * Add ability to compile to standalone executable
    * Add support for multi-tasking
    * Add support for multi-tasking with multiple cores/threads
*/

/* Built-in Constants
 *****************************************************************************/
/** The argument stack */
val_t ArgStack[ARG_STACK_SIZE];

/** Pointer to current position on the stack */
val_t* ArgStackPtr = ArgStack-1;

/** Pointer to current instruction being executed */
val_t* CodePtr = 0;

/** A state variable used to flag when the interpreter reads a line of input */
val_t Line_Read = 0;

/* Inner Interpreter
 *****************************************************************************/
void docolon(val_t* code) {
    word_t* word;
    /* We may have previously been executing a word so we should save off our
     * previous position */
    val_t* prev_code = CodePtr;
    /* Set the next instruction to execute */
    CodePtr = code;
    /* And loop through until we "ret" sets the code pointer to null */
    while(CodePtr)
    {
        word = (word_t*)*CodePtr;
        /* Increment the instruction pointer */
        CodePtr++;
        /* Execute the byte code instruction */
        word->codeword(CodePtr);
    }
    /* Execution finished lets put things back the way they were */
    CodePtr = prev_code;
}

/* Built-in Constants
 *****************************************************************************/
defconst("VERSION", version, 0, NULL,     1);
defconst("EXECDEF", execdef, 0, &version, (val_t)&docolon);
defconst("WORDSZ",  wordsz,  0, &execdef, sizeof(val_t));

/* Built-in Variables
 *****************************************************************************/
defvar("state",  state,  0, &wordsz, 0);
defvar("latest", latest, 0, &state,  0);

/* Word Words
 *****************************************************************************/
defcode("wlink", wlink, 0, &latest){
    *(ArgStackPtr) = (val_t)(((word_t*)*(ArgStackPtr))->link);
}

defcode("wsize", wflags, 0, &wlink){
    *(ArgStackPtr) = (val_t)(((word_t*)*(ArgStackPtr))->flags.codesize);
}

defcode("wname", wname, 0, &wflags){
    *(ArgStackPtr) = (val_t)(((word_t*)*(ArgStackPtr))->name);
}

defcode("wfunc", wfunc, 0, &wname){
    *(ArgStackPtr) = (val_t)(((word_t*)*(ArgStackPtr))->codeword);
}

defcode("wcode", wcode, 0, &wfunc){
    *(ArgStackPtr) = (val_t)(((word_t*)*(ArgStackPtr))->code);
}

defcode("here", here, 0, &wcode){
    ArgStackPtr++;
    *(ArgStackPtr) = (val_t)((((word_t*)latest_val)->flags.codesize) - 1);
}

/* Input/Output Words
 *****************************************************************************/
defvar("stdin",  _stdin,  0, &here,    0);
defvar("stdout", _stdout, 0, &_stdin,  0);
defvar("stderr", _stderr, 0, &_stdout, 0);

defconst("F_R",  f_r,  0, &_stderr, (val_t)"r");
defconst("F_W",  f_w,  0, &f_r,     (val_t)"w");
defconst("F_A",  f_a,  0, &f_w,     (val_t)"a");
defconst("F_R+", f_ru, 0, &f_a,     (val_t)"r+");
defconst("F_W+", f_wu, 0, &f_ru,    (val_t)"w+");
defconst("F_A+", f_au, 0, &f_wu,    (val_t)"a+");

defcode("fopen",  _fopen,  0, &f_au){
    *(ArgStackPtr-1) = (val_t)fopen( (const char*)*(ArgStackPtr-1), (const char*)*(ArgStackPtr) );
    ArgStackPtr--;
}

defcode("fclose", _fclose, 0, &_fopen){
    fclose((FILE*)*(ArgStackPtr));
    ArgStackPtr--;
}

defcode("fflush", _fflush, 0, &_fclose){
    fflush((FILE*)*(ArgStackPtr));
}

defcode("fgetc",  _fgetc,  0, &_fflush){
    ArgStackPtr++;
    *(ArgStackPtr) = fgetc((FILE*)*(ArgStackPtr-1));
}

defcode("fputc",  _fputc,  0, &_fgetc){
    fputc((char)*(ArgStackPtr), (FILE*)*(ArgStackPtr-1));
    ArgStackPtr--;
}

defcode("fpeekc", _fpeekc, 0, &_fputc){
    ArgStackPtr++;
    *(ArgStackPtr) = fgetc((FILE*)*(ArgStackPtr-1));
    ungetc((char)*(ArgStackPtr), (FILE*)*(ArgStackPtr-1));
}

/* Interpreter Words
 *****************************************************************************/
// defcode("fetch",  , 0, &){}
// defcode("parse",  , 0, &){}
// defcode("interp", , 0, &){}

/* Input Words
 *****************************************************************************/
defcode("getc", get_char, 0, &_fpeekc){
    ArgStackPtr++;
{'fraction_non_alphanumeric': 0.2873348017621145, 'fraction_numerical': 0.009911894273127754, 'mean_word_length': 4.619430693069307, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 29, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5587256', 'n_tokens_mistral': 3165, 'n_tokens_neox': 3019, 'n_words': 730}