From b8b65c17f7c4cfbe7f1d2f6b76580d40afe51526 Mon Sep 17 00:00:00 2001 From: Aaron Taylor Date: Wed, 17 Jul 2019 23:50:00 -0700 Subject: [PATCH] Added ASCII string capability to `vvc`. Moved VVS stdlib functions: 1000 -> 1000100 1001 -> 1000101 --- examples/hello-stdlib/hello.pvvs | 19 +++----------- stdlib/README.md | 2 ++ stdlib/stdio.pvvs | 20 +++++++-------- vv_compiler.c | 44 +++++++++++++++++++++++++++++++- 4 files changed, 58 insertions(+), 27 deletions(-) diff --git a/examples/hello-stdlib/hello.pvvs b/examples/hello-stdlib/hello.pvvs index 3b28850..a70ebff 100644 --- a/examples/hello-stdlib/hello.pvvs +++ b/examples/hello-stdlib/hello.pvvs @@ -1,21 +1,8 @@ @@ This program outputs "Hello, world!" -SSSSN | ST: Push +0 (ASCII '\0') -SSSTSTSN | ST: Push +10 (ASCII '\n') -SSSTSSSSTN | ST: Push +33 (ASCII !) -SSSTTSSTSSN | ST: Push +100 (ASCII d) -SSSTTSTTSSN | ST: Push +108 (ASCII l) -SSSTTTSSTSN | ST: Push +114 (ASCII r) -SSSTTSTTTTN | ST: Push +111 (ASCII o) -SSSTTTSTTTN | ST: Push +119 (ASCII w) -SSSTSSSSSN | ST: Push +32 (ASCII space) -SSSTSTTSSN | ST: Push +44 (ASCII ,) -SSSTTSTTTTN | ST: Push +111 (ASCII o) -SSSTTSTTSSN | ST: Push +108 (ASCII l) -SSSTTSTTSSN | ST: Push +108 (ASCII l) -SSSTTSSTSTN | ST: Push +101 (ASCII e) -SSSTSSTSSSN | ST: Push +72 (ASCII H) -NSTTSSSN | FC: JSR>1000 (print string from stack; see stdlib) +A"Hello, world!\n" +@TODO: Change this to printf call +NSTTSSSTSSN | FC: JSR>1000100 (print string from stack; see stdlib) NNN | FC: Terminate program #include "stdio.pvvs" diff --git a/stdlib/README.md b/stdlib/README.md index 00d0fb5..12a5ff6 100644 --- a/stdlib/README.md +++ b/stdlib/README.md @@ -60,6 +60,8 @@ header comment for each function to learn the call and return stack. 1000001 ----- spew registers (heap.pvvs) 1000010 ----- print sign of number (stdio.pvvs) 1000011 ----- print magnitude of number (stdio.pvvs) + 1000100 ----- print string from stack (stdio.pvvs) + 1000101 ----- print string from heap (stdio.pvvs) # Misc # diff --git a/stdlib/stdio.pvvs b/stdlib/stdio.pvvs index 49b8cfc..f2dfe82 100644 --- a/stdlib/stdio.pvvs +++ b/stdlib/stdio.pvvs @@ -3,7 +3,7 @@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ Name: -@ printstackstring (1000) +@ printstackstring (1000100) @ Description: @ Prints a null-terminated string from the stack. @ Call Stack: @@ -15,18 +15,18 @@ @ Return Stack: @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -NSSVTSSSN | Mark: 1000 (print string from stack) +NSSVTSSSTSSN | Mark: 1000100 (print string from stack) SNS | DUP -NTSSSSSTSSSSSSSSSSTN | BRZ > 00001000 00000001 +NTSSTSSSTSSSSSSSSSTN | BRZ > 01000100 00000001 TNSS | Print character -NSNTSSSN | JMP > 1000 -NSSVSSSSTSSSSSSSSSSTN | Mark: 00001000 00000001 +NSNTSSSTSSN | JMP > 1000100 +NSSVSTSSSTSSSSSSSSSTN | Mark: 01000100 00000001 SNN | DROP NTN | RTS @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ Name: -@ printheapstring (1001) +@ printheapstring (1000101) @ Description: @ Prints a null-terminated string from the heap. @ Call Stack: @@ -34,16 +34,16 @@ NTN | RTS @ Return Stack: @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -NSSVTSSTN | Mark: 1001 (print string from heap) +NSSVTSSSTSTN | Mark: 1000101 (print string from heap) SNS | DUP TTT | LOAD SNS | DUP -NTSSSSSTSSTSSSSSSSTN | BRZ > 00001001 00000001 +NTSSTSSSTSTSSSSSSSTN | BRZ > 01000101 00000001 TNSS | Print character SSSTN | Push +1 TSSS | ADD -NSNTSSTN | JMP > 1001 -NSSVSSSSTSSTSSSSSSSTN | Mark: 00001001 00000001 +NSNTSSSTSTN | JMP > 1000101 +NSSVSTSSSTSTSSSSSSSTN | Mark: 01000101 00000001 SNN | DROP SNN | DROP NTN | RTS diff --git a/vv_compiler.c b/vv_compiler.c index 7ab1e06..9944070 100644 --- a/vv_compiler.c +++ b/vv_compiler.c @@ -25,6 +25,44 @@ print_usage(char ** argv) ); } +/* Allows building an ASCII string on the stack. */ +/* This syntax: A"test" */ +/* Results in five PUSH_IMMEDIATE commands for the four letters and newline. */ +/* Expects 'input' to present a double-quoted ('"') ASCII string. */ +/* The 'A' has already been chomped. */ +void +parse_ascii_string(FILE * input, FILE * output) +{ + uint8_t temp_byte; + fread(&temp_byte, 1, 1, input); + if (temp_byte != '"') fprintf(stderr, "WARNING: Expected double-quote to begin string.\n"); + + /* Put the letters on the stack in reverse. Don't forget to put a null-terminator first. */ + for (fread(&temp_byte,1,1,input); temp_byte != '"'; fread(&temp_byte,1,1,input)) continue; + temp_byte = '\0'; + + while (temp_byte != '"') { + /* First, push three spaces to start a PUSH_IMMEDIATE command for a positive number. */ + uint8_t temp_output = ' '; + for(int i=0;i<3;i++) fwrite(&temp_output, 1, 1, output); + /* Second, push the ASCII character, 7 bits total, most signficant bit first. */ + /* Remember, [Tab]=1 and [Space]=0. */ + uint8_t index = 7; /* 7 bits needed per ASCII character. */ + while (index) { + ((temp_byte >> (index-1)) & 1) ? (temp_output = '\t') : (temp_output = ' '); + fwrite(&temp_output, 1, 1, output); + index--; + } + /* Third, close the number with a newline. */ + temp_output = '\n'; + fwrite(&temp_output, 1, 1, output); + + /* Read the next byte to prepare for the loop test. */ + fseek(input, -2, SEEK_CUR); + fread(&temp_byte, 1, 1, input); + } +} + int main(int argc, char ** argv) { @@ -90,11 +128,15 @@ main(int argc, char ** argv) temp_byte = '\v'; fwrite(&temp_byte, 1, 1, output); break; + case 'a': + case 'A': + parse_ascii_string(input, output); + break; case '\n': /* Intentionally empty */ break; default: - /* The first non-[tTsSnNvV] character begins a comment lasting until end of line. */ + /* The first non-[tTsSnNvVaA] character begins a comment lasting until end of line. */ while (fread(&temp_byte, 1, 1, input)) { if (temp_byte == '\n') break; } -- 2.20.1