From ae1f85a178241c826a0b6a72ace12049b9907561 Mon Sep 17 00:00:00 2001 From: Aaron Taylor Date: Wed, 17 Jul 2019 14:15:58 -0700 Subject: [PATCH] Added functions to stdlib: 10000 slurp 10001 spew 100000 strlen 111001 dumpstack Renamed functions in stdlib: 11110 -> 1000000 slurp registers 11111 -> 1000001 spew registers 1000000 -> 1000010 print sign of number 1000001 -> 1000011 print magnitude of number --- stdlib/README.md | 16 ++++-- stdlib/debug.pvvs | 39 ++++++++++++- stdlib/heap.pvvs | 135 +++++++++++++++++++++++++++++++++++++++------ stdlib/stdio.pvvs | 28 +++++----- stdlib/string.pvvs | 39 +++++++++++++ 5 files changed, 219 insertions(+), 38 deletions(-) create mode 100644 stdlib/string.pvvs diff --git a/stdlib/README.md b/stdlib/README.md index cef4cd4..c64be4b 100644 --- a/stdlib/README.md +++ b/stdlib/README.md @@ -45,14 +45,18 @@ header comment for each function to learn the call and return stack. 11101 ----- 11110 ----- slurp (heap.pvvs) 11111 ----- spew (heap.pvvs) - 100xxx - unassigned + 100xxx - string functions + 100000 ----- strlen (string.pvvs) 101xxx - unassigned 110xxx - conversion functions 111xxx - debug functions 111000 ----- dump heap (debug.pvvs) + 111001 ----- dump stack (debug.pvvs) 1xxxxxx - reserved for less common entry points - 1000000 ----- print sign of number (stdio.pvvs) - 1000001 ----- print magnitude of number (stdio.pvvs) + 1000000 ----- slurp registers (heap.pvvs) + 1000001 ----- spew registers (heap.pvvs) + 1000010 ----- print sign of number (stdio.pvvs) + 1000011 ----- print magnitude of number (stdio.pvvs) # Misc # @@ -67,8 +71,8 @@ private label space associated with it, formed as follows: The stdlib uses heap[1] to heap[15] as registers. -The `slurp` and `spew` functions facilitate this by `spew`ing the stack onto -the heap's pseudo-registers or `slurp`ing the pseudo-registers back to the +The `slurpreg` and `spewreg` functions facilitate this by `spew`ing the stack +onto the heap's pseudo-registers or `slurp`ing the pseudo-registers back to the stack. The functions preserve order in complementary fashion. -The `spew` function uses `heap[0]` for storage. +The `spewreg` function uses `heap[0]` for storage. diff --git a/stdlib/debug.pvvs b/stdlib/debug.pvvs index 5261984..6328cf8 100644 --- a/stdlib/debug.pvvs +++ b/stdlib/debug.pvvs @@ -22,7 +22,7 @@ TTT | LOAD SNT | SWAP @ Print output line for this memory location -NSTTSSSSSTN | JSR>1000001 (print absolute value of number) +NSTTSSSSTTN | JSR>1000011 (print absolute value of number) SSSTTTSTSN | PUSH ASCII ':' SSSTSSTN | PUSH ASCII '\t' TNSS | PUTC @@ -51,4 +51,41 @@ NSSVSSTTTSSSSSSSSSSSN | Mark: 00111000 00000000 SNN | DROP NTN | RTS +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@ Name: +@ dumpstack (111001) +@ Description: +@ Dumps 'count' entries from the stack. +@ Call Stack: +@ count <-- TOS +@ Return Stack: +@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +#include +NSSVTTTSSTN | Mark: 111001 (dump stack) + +@ Print output line for the current TOS. +SNS | DUP +NSTTSSSSTTN | JSR>1000011 (print absolute value of number) +SSSTTTSTSN | PUSH ASCII ':' +SSSTSSTN | PUSH ASCII '\t' +TNSS | PUTC +TNSS | PUTC +SNT | SWAP +NSTTSTSN | JSR>1010 (print number from stack) +SSSTSTSN | PUSH ASCII '\n' +TNSS | PUTC + +@ Figure out if the loop is complete. +SNS | DUP +NTSSSTTTSSTSSSSSSSSN | BRZ > 00111001 00000000 +SSSTN | PUSH 1 +TSST | SUBTRACT +NSNTTTSSTN | JMP>111001 (dump stack) + +@ Clean up and return +NSSVSSTTTSSTSSSSSSSSN | Mark: 00111001 00000000 +SNN | DROP +NTN | RTS + #endif diff --git a/stdlib/heap.pvvs b/stdlib/heap.pvvs index d753363..3fa352c 100644 --- a/stdlib/heap.pvvs +++ b/stdlib/heap.pvvs @@ -15,7 +15,7 @@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ NSSVTTSSSN | Mark: 11000 (memset) SSSTTN | PUSH 3 -NSTTTTTTN | JSR > 11111 (spew) +NSTTSSSSSTN | JSR > 1000001 (spewreg) @ Store 'pattern' into one memory location on each pass through this loop. NSSVSSSTTSSSSSSSSSSSN | Mark: 00011000 00000000 @@ -59,7 +59,7 @@ NTN | RTS @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ NSSVTTSSTN | Mark: 11001 (memcpy) SSSTTN | PUSH 3 -NSTTTTTTN | JSR > 11111 (spew) +NSTTSSSSSTN | JSR > 1000001 (spewreg) @ Copy one word on each pass through this loop. NSSVSSSTTSSTSSSSSSSSN | Mark: 00011001 00000000 @@ -107,7 +107,7 @@ NTN | RTS #include NSSVTTSTSN | Mark: 11010 (memrand) SSSTN | PUSH 1 -NSTTTTTTN | JSR > 11111 (spew) +NSTTSSSSSTN | JSR > 1000001 (spewreg) @ Store random word into one memory location on each pass through this loop. NSSVSSSTTSTSSSSSSSSSN | Mark: 00011010 00000000 @@ -148,7 +148,7 @@ NTN | RTS @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ NSSVTTSTTN | Mark: 11011 (memcmp) SSSTSN | PUSH 2 -NSTTTTTTN | JSR > 11111 (spew) +NSTTSSSSSTN | JSR > 1000001 (spewreg) @ Compare one word on each pass through this loop. NSSVSSSTTSTTSSSSSSSSN | Mark: 00011011 00000000 @@ -201,7 +201,7 @@ NTN | RTS @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ NSSVTTTSSN | Mark: 11100 (memsrch) SSSTTN | PUSH 3 -NSTTTTTTN | JSR > 11111 (spew) +NSTTSSSSSTN | JSR > 1000001 (spewreg) @ Compare one word on each pass through this loop. NSSVSSSTTTSSSSSSSSSSN | Mark: 00011100 00000000 @@ -238,9 +238,9 @@ NTN | RTS @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ Name: -@ slurp (11110) +@ slurpreg (1000000) @ Description: -@ Reads 'count' values from heap to stack in complementary order to 'spew'. +@ Reads 'count' values from heap to stack in complementary order to 'spewreg'. @ Call Stack: @ count @ Return Stack: @@ -249,10 +249,10 @@ NTN | RTS @ heap[2] @ heap[1] <-- TOS @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -NSSVTTTTSN | Mark: 11110 (slurp) +NSSVTSSSSSSN | Mark: 1000000 (slurpreg) @ Load one word from heap on each pass. -NSSVSSSTTTTSSSSSSSSSN | Mark: 00011110 00000000 +NSSVSTSSSSSSSSSSSSSSN | Mark: 01000000 00000000 SNS | DUP TTT | LOAD SNT | SWAP @@ -262,15 +262,15 @@ SNT | SWAP SSSTN | PUSH 1 TSST | SUBTRACT SNS | DUP -NTSSSSTTTTSSSSSSSSTN | BRZ > 00011110 00000001 -NSNSSSTTTTSSSSSSSSSN | JMP > 00011110 00000000 -NSSVSSSTTTTSSSSSSSSTN | Mark: 00011110 00000001 +NTSSTSSSSSSSSSSSSSTN | BRZ > 01000000 00000001 +NSNSTSSSSSSSSSSSSSSN | JMP > 01000000 00000000 +NSSVSTSSSSSSSSSSSSSTN | Mark: 01000000 00000001 SNN | DROP NTN | RTS @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ Name: -@ spew (11111) +@ spewreg (1000001) @ Description: @ Writes 'count' values from stack to heap in this order: @ TOS -> heap[1] @@ -286,7 +286,7 @@ NTN | RTS @ Return Stack: @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -NSSVTTTTTN | Mark: 11111 (spew) +NSSVTSSSSSTN | Mark: 1000001 (spewreg) @ Create a counter in heap[0] that doubles as a destination pointer generator. SSSSN | PUSH 0 (ptr) @@ -294,7 +294,7 @@ SSSTN | PUSH 1 TTS | STORE @ Store one word to heap on each pass. -NSSVSSSTTTTTSSSSSSSSN | Mark: 00011111 00000000 +NSSVSTSSSSSTSSSSSSSSN | Mark: 01000001 00000000 SNT | SWAP SSSSN | PUSH 0 (ptr) TTT | LOAD @@ -306,7 +306,7 @@ SNS | DUP SSSSN | PUSH 0 (ptr) TTT | LOAD TSST | SUBTRACT -NTSSSSTTTTTSSSSSSSTN | BRZ > 00011111 00000001 +NTSSTSSSSSTSSSSSSSTN | BRZ > 01000001 00000001 @ Increment heap[0] if continuing. SSSSN | PUSH 0 (ptr) @@ -315,11 +315,112 @@ TTT | LOAD SSSTN | PUSH 1 TSSS | ADD TTS | STORE +NSNSTSSSSSTSSSSSSSSN | JMP > 01000001 00000000 + +@ Clean up and return. +NSSVSTSSSSSTSSSSSSSTN | Mark: 01000001 00000001 +SNN | DROP +NTN | RTS + +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@ Name: +@ slurp (11110) +@ Description: +@ Reads values from heap to stack in complementary order to 'spew'. +@ Call Stack: +@ address +@ count <-- TOS +@ Return Stack: +@ heap[address+count] +@ ... +@ heap[address+1] +@ heap[address] <-- TOS +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +NSSVTTTTSN | Mark: 11110 (slurp) +SSSTSN | PUSH 2 +NSTTSSSSSTN | JSR > 1000001 (spewreg) + +@ Load one word from heap on each pass. +NSSVSSSTTTTSSSSSSSSSN | Mark: 00011110 00000000 +SSSTN | PUSH 1 (ptr) +TTT | LOAD +SSSTSN | PUSH 2 (ptr) +TTT | LOAD +TSSS | ADD +TTT | LOAD + +@ Check for loop completion. +@ As a side effect, prepare the next address. +SSSTN | PUSH 1 (ptr) +SNS | DUP +TTT | LOAD +SNS | DUP +NTSSSSTTTTSSSSSSSSTN | BRZ > 00011110 00000001 +SSSTN | PUSH 1 +TSST | SUBTRACT +TTS | STORE +NSNSSSTTTTSSSSSSSSSN | JMP > 00011110 00000000 +NSSVSSSTTTTSSSSSSSSTN | Mark: 00011110 00000001 +SNN | DROP +SNN | DROP +NTN | RTS + +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@ Name: +@ spew (11111) +@ Description: +@ Writes values from stack to heap in this order: +@ TOS -> heap[address] +@ TOS+1 -> heap[address+1] +@ ... +@ TOS+n -> heap[address+count] +@ Call Stack: +@ data-words +@ ... +@ data-words +@ address +@ count <-- TOS +@ Return Stack: +@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +NSSVTTTTTN | Mark: 11111 (spew) +SSSTSN | PUSH 2 +NSTTSSSSSTN | JSR > 1000001 (spewreg) + +@ Create a counter in heap[3] that doubles as a dest. pointer offset generator. +SSSTTN | PUSH 3 (ptr) +SSSSN | PUSH 0 +TTS | STORE + +@ Store one word to heap on each pass. +NSSVSSSTTTTTSSSSSSSSN | Mark: 00011111 00000000 +SSSTSN | PUSH 2 (ptr) +TTT | LOAD +SSSTTN | PUSH 3 (ptr) +TTT | LOAD +TSSS | ADD +SNT | SWAP +TTS | STORE + +@ Check for loop completion. +SSSTN | PUSH 1 (ptr) +TTT | LOAD +SSSTTN | PUSH 3 (ptr) +TTT | LOAD +TSST | SUBTRACT +NTSSSSTTTTTSSSSSSSTN | BRZ > 00011111 00000001 + +@ Increment heap[3] if continuing. +SSSTTN | PUSH 3 (ptr) +SNS | DUP +TTT | LOAD +SSSTN | PUSH 1 +TSSS | ADD +TTS | STORE NSNSSSTTTTTSSSSSSSSN | JMP > 00011111 00000000 @ Clean up and return. NSSVSSSTTTTTSSSSSSSTN | Mark: 00011111 00000001 -SNN | DROP NTN | RTS #endif diff --git a/stdlib/stdio.pvvs b/stdlib/stdio.pvvs index 12e0ed7..49b8cfc 100644 --- a/stdlib/stdio.pvvs +++ b/stdlib/stdio.pvvs @@ -61,13 +61,13 @@ NTN | RTS @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ NSSVTSTSN | Mark: 1010 (print number from stack) SNS | DUP -NSTTSSSSSSN | JSR > 1000000 -NSTTSSSSSTN | JSR > 1000001 +NSTTSSSSTSN | JSR > 1000010 +NSTTSSSSTTN | JSR > 1000011 NTN | RTS @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ Name: -@ printstacknumbersign (1000000) +@ printstacknumbersign (1000010) @ Description: @ Prints the sign of 'number' from the stack. @ Call Stack: @@ -75,19 +75,19 @@ NTN | RTS @ Return Stack: @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ -NSSVTSSSSSSN | Mark: 1000000 (print sign of number from stack) -NTTSTSSSSSSSSSSSSSTN | BMI > 010000000 00000001 +NSSVTSSSSTSN | Mark: 1000010 (print sign of number from stack) +NTTSTSSSSTSSSSSSSSTN | BMI > 01000010 00000001 SSSTSTSTTN | PUSH ASCII '+' -NSNSTSSSSSSSSSSSSTSN | JMP > 010000000 00000010 -NSSVSTSSSSSSSSSSSSSTN | Mark: 010000000 00000001 +NSNSTSSSSTSSSSSSSTSN | JMP > 01000010 00000010 +NSSVSTSSSSTSSSSSSSSTN | Mark: 01000010 00000001 SSSTSTTSTN | PUSH ASCII '-' -NSSVSTSSSSSSSSSSSSTSN | Mark: 010000000 00000010 +NSSVSTSSSSTSSSSSSSTSN | Mark: 01000010 00000010 TNSS | PUTC NTN | RTS @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ Name: -@ printstacknumbermagnitude (1000001) +@ printstacknumbermagnitude (1000011) @ Description: @ Prints the magnitude of 'number' from the stack. @ Call Stack: @@ -96,14 +96,14 @@ NTN | RTS @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ #include -NSSVTSSSSSTN | Mark: 1000001 (print magnitude of number from stack) +NSSVTSSSSTTN | Mark: 1000011 (print magnitude of number from stack) NSTTSSSTN | JSR > 10001 (absolute value) SSSSN | PUSH ASCII '\0' SNT | SWAP @ Pick off one digit on each pass through this loop. -NSSVSTSSSSSTSSSSSSSSN | Mark: 01000001 00000000 +NSSVSTSSSSTTSSSSSSSSN | Mark: 01000011 00000000 SNS | DUP @ Mod-off a digit, convert to ASCII, store on stack as part of the string. @@ -117,11 +117,11 @@ SNT | SWAP SSSTSTSN | PUSH +10 TSTS | DIVIDE SNS | DUP -NTSSTSSSSSTSSSSSSSTN | BRZ > 01000001 00000001 -NSNSTSSSSSTSSSSSSSSN | JMP > 01000001 00000000 +NTSSTSSSSTTSSSSSSSTN | BRZ > 01000011 00000001 +NSNSTSSSSTTSSSSSSSSN | JMP > 01000011 00000000 @ Print the string we have built on the stack. -NSSVSTSSSSSTSSSSSSSTN | Mark: 01000001 00000001 +NSSVSTSSSSTTSSSSSSSTN | Mark: 01000011 00000001 SNN | DROP NSTTSSSN | JSR > 1000 (print string from stack) NTN | RTS diff --git a/stdlib/string.pvvs b/stdlib/string.pvvs new file mode 100644 index 0000000..5571349 --- /dev/null +++ b/stdlib/string.pvvs @@ -0,0 +1,39 @@ +#ifndef VVS_STDLIB_STRING +#define VVS_STDLIB_STRING + +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@ Name: +@ strlen (100000) +@ Description: +@ Counts number of words in a null-terminated string. +@ Returned number does not include the null-terminator. +@ Call Stack: +@ pointer to first character <-- TOS +@ Return Stack: +@ number of words in string <-- TOS +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +NSSVTSSSSSN | Mark: 100000 (strlen) + +@ Create a length counter. +SSSSN | PUSH 0 +SNT | SWAP + +@ Increment the counter (and pointer) on each pass through the loop. +NSSVSSTSSSSSSSSSSSSSN | Mark: 00100000 00000000 +SNS | DUP +TTT | LOAD +NTSSSTSSSSSSSSSSSSTN | BRZ > 00100000 00000001 +SNT | SWAP +SSSTN | PUSH 1 +TSSS | ADD +SNT | SWAP +SSSTN | PUSH 1 +TSSS | ADD +NSNSSTSSSSSSSSSSSSSN | JMP > 00100000 00000000 + +@ Clean up and return. +NSSVSSTSSSSSSSSSSSSTN | Mark: 00100000 00000001 +SNN | DROP +NTN | RTS + +#endif -- 2.20.1