equi

A self-descriptive stack-based PC platform
git clone git://git.luxferre.top/equi.git
Log | Files | Refs | README | LICENSE

commit abfc1125c7c4c81dbdc66c3990ce1812028248ac
parent c3faeff722ca1b93f3938488a5b940bfb854c121
Author: Luxferre <lux@ferre>
Date:   Thu, 11 Aug 2022 19:11:18 +0300

Implemented minification mode

Diffstat:
MREADME.md | 2++
Mequi.c | 33++++++++++++++++++++++-----------
Aexamples/fizzbuzz.min.equi | 1+
3 files changed, 25 insertions(+), 11 deletions(-)

diff --git a/README.md b/README.md @@ -138,6 +138,8 @@ Being a purely PC-oriented low-level runtime/programming environment, Equi has t - doesn't implement non-blocking key input (the `,` instruction is identical to blocking key input instruction `?`), - sandboxes the `{` and `}` operations using the file you supply in the command-line parameter. If you don't supply the file, these operations will effectively do nothing except putting 0x0000 (success status) onto the stack. +Additionally, this emulator implements `m` command line parameter that means that, instead of execution, the VM shall output the current command buffer contents upon reaching the `Q` instruction. This is particularly useful to save minified versions of `.equi` files to further reuse them in more space-restricted environments. Note that minified and non-minified files load and run fully identically, but the size difference can be significant. I.e. for the current FizzBuzz example version, the source is 1544 bytes long but its actual application snapshot in the command buffer (which can be dumped with the `m` parameter as a minified variant) is just [180 bytes long](examples/fizzbuz.min.equi). The rest is comments and whitespace characters that are skipped while loading the program into the command buffer. + The source code file should compile using any mainstream C compiler with C89 support, like GCC/DJGPP, Clang, TCC etc. However, it is also being developed to be compilable with CC65 compiler for targets like Apple II or Atari 800. All the machine/target specific configuration is done at compile time, using compiler command-line switches. Here are the instructions to build Equi using different known C compilers. The following constants can be adjusted at compile time: diff --git a/equi.c b/equi.c @@ -553,7 +553,9 @@ void equi_main_loop() { /* Equi VM entry point */ int main(int argc, char* argv[]) { - uchar instr, bc; + uchar instr, bc, mmode = 0; + if(argc > 1 && argv[1][0] == 'm') /* enter minification mode, don't run the programs */ + mmode = 1; /* CC65-specific terminal init */ #ifdef __CC65__ clrscr(); @@ -574,6 +576,7 @@ int main(int argc, char* argv[]) { /* Start both execution and input buffering from the start of command buffer (-1 because we use prefix increment) */ ram.pc = ram.ibp = 65535U; + if(!mmode) /* skip the greeting if in minification mode */ printf("\nWelcome to Equi v" EQUI_VER " by Luxferre, 2022\nCLT: 0x%04X (%d bytes)\nGPD: 0x%04X (%d bytes)\nCommand buffer: 0x%04X (%d bytes)\nEqui ready\n\n> ", (unsigned int) ((uchar *)&ram.clt - (uchar *)&ram.main_stack), (unsigned int) ((uchar *)&ram.gpd - (uchar *)&ram.clt), @@ -599,16 +602,24 @@ int main(int argc, char* argv[]) { cputc(instr); /* echo it */ #endif ram.II = 0; - } else if(!ram.II && (instr == 0xFFU || instr == INS_QUIT)) { /* if not in II mode, process EOF or Q instruction: trigger interpreter loop */ - cputc(CR); /* echo CR */ - cputc(LF); /* echo LF */ - ram.cmdbuf[++ram.ibp] = INS_QUIT; /* end program with INS_QUIT */ - ram.IM = 1; /* set the mandatory interpretation mode flag */ - equi_main_loop(); /* and run the interpreter loop */ - cputc(CR); /* echo CR */ - cputc(LF); /* echo LF */ - cputc('>'); - cputc(' '); + } else if(!ram.II && (instr == 0xFFU || instr == INS_QUIT)) { + if(mmode) { /* output command buffer contents to stdout and exit */ + ram.cmdbuf[++ram.ibp] = INS_QUIT; /* end program with INS_QUIT */ + ram.cmdbuf[++ram.ibp] = 0; /* and zero terminator */ + puts((const char *)&ram.cmdbuf[0]); /* output the command buffer */ + break; /* and exit the command mode immediately */ + } else { + /* if not in II or minification mode, process EOF or Q instruction: trigger interpreter loop */ + cputc(CR); /* echo CR */ + cputc(LF); /* echo LF */ + ram.cmdbuf[++ram.ibp] = INS_QUIT; /* end program with INS_QUIT */ + ram.IM = 1; /* set the mandatory interpretation mode flag */ + equi_main_loop(); /* and run the interpreter loop */ + cputc(CR); /* echo CR */ + cputc(LF); /* echo LF */ + cputc('>'); + cputc(' '); + } } else { /* append the instruction/character to the command buffer if and only if it doesn't match the above criteria and we're not in II mode */ if(!ram.II) ram.cmdbuf[++ram.ibp] = instr; diff --git a/examples/fizzbuzz.min.equi b/examples/fizzbuzz.min.equi @@ -0,0 +1 @@ +nl:000A#D..;d:0030+.;fizz:0046.izz"...;buzz:0042.uzz"...;pdb:0064/%$3I!5Jd'1GS000A/%$3I!7Jd'1GS8JGL2I2Jd'd';0001#0G2+S$3/%!AIfizz'1G2+S$5/%!AIbuzz'1G2+SG2+L5I$pdb'nl'0001+$65<42NIQ