Commit | Line | Data |
---|---|---|
48f88489 AT |
1 | @ (c) 2020 Aaron Taylor <ataylor at subgeniuskitty dot com> |
2 | @ See LICENSE.txt file for copyright and license details. | |
3 | ||
b6bea2cf AT |
4 | #ifndef VVS_STDLIB_CONVERT |
5 | #define VVS_STDLIB_CONVERT | |
6 | ||
7 | @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ | |
8 | @ Name: | |
9 | @ atoi (110000) | |
10 | @ Description: | |
11 | @ Convert null-terminated ASCII string to integer. | |
12 | @ Result is negative if leading character is a hyphen ('-'). | |
13 | @ Result is positive if leading character is a plus sign ('+') or number. | |
14 | @ Excluding the sign, parsing halts on the first non-numeric ASCII character. | |
15 | @ Since all possible return values are valid, this subroutine simply returns | |
16 | @ zero if no parseable number was found. Any stronger validity checks are the | |
17 | @ responsibility of the caller. Similarly, no overflow checks are performed. | |
18 | @ In addition to returning the parsed integer, also returns a pointer to the | |
19 | @ first character after the parsed integer. | |
20 | @ Call Stack: | |
21 | @ pointer to first character <-- TOS | |
22 | @ Return Stack: | |
23 | @ integer | |
24 | @ pointer to last parsed character <-- TOS | |
25 | @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ | |
26 | #include <stack.pvvs> | |
27 | #include <string.pvvs> | |
28 | NSSVTTSSSSN | Mark: 110000 (atoi) | |
29 | ||
30 | @ Check the first character and create a 'sign' flag on the stack. | |
31 | @ Update the pointer to point to the first numeric character. | |
32 | SNS | DUP | |
33 | TTT | LOAD | |
34 | SSSSSTSTTSTN | PUSH 45 (ASCII '-') | |
35 | TSST | SUBTRACT | |
36 | NTSSSTTSSSSSSSSSSSSN | BRZ > 00110000 00000000 (found_minus_sign) | |
37 | SNS | DUP | |
38 | TTT | LOAD | |
39 | SSSSSTSTSTTN | PUSH 43 (ASCII '+') | |
40 | TSST | SUBTRACT | |
41 | NTSSSTTSSSSSSSSSSSTN | BRZ > 00110000 00000001 (found_plus_sign) | |
42 | NSNSSTTSSSSSSSSSSTSN | JMP > 00110000 00000010 (found_digit) | |
43 | NSSVSSTTSSSSSSSSSSSTN | Mark: 00110000 00000001 (found_plus_sign) | |
44 | SSSTN | PUSH +1 | |
45 | TSSS | ADD | |
46 | NSSVSSTTSSSSSSSSSSTSN | Mark: 00110000 00000010 (found_digit) | |
47 | SSSTN | PUSH +1 (sign_flag) | |
48 | SNT | SWAP | |
49 | NSNSSTTSSSSSSSSSSTTN | JMP > 00110000 00000011 (done_with_sign_flag) | |
50 | NSSVSSTTSSSSSSSSSSSSN | Mark: 00110000 00000000 (found_minus_sign) | |
51 | SSSTN | PUSH +1 | |
52 | TSSS | ADD | |
53 | SSTTN | PUSH -1 (sign_flag) | |
54 | SNT | SWAP | |
55 | NSSVSSTTSSSSSSSSSSTTN | Mark: 00110000 00000011 (done_with_sign_flag) | |
56 | ||
57 | @ Create an accumulator on the TOS. | |
58 | SSSSN | PUSH 0 (accumulator) | |
59 | ||
60 | @ Main loop examines string one character at a time, building result in accumulator. | |
61 | @ TOS> accumulator, string_ptr, sign_flag | |
62 | NSSVSSTTSSSSSSSSSTSSN | Mark: 00110000 00000100 (atoi:main_loop) | |
63 | SSSTSN | PUSH +2 | |
64 | NSTTTSSN | JSR > 1100 (deepdup) | |
65 | TTT | LOAD | |
66 | SNS | DUP | |
67 | NSTTSSSSTN | JSR > 100001 (isdigit) | |
68 | NTSSSTTSSSSSSSSSTSTN | BRZ > 00110000 00000101 (found_end_of_number) | |
69 | SSSSSTTSSSSN | PUSH 48 (ASCII '0') | |
70 | TSST | SUBTRACT | |
71 | SNT | SWAP | |
72 | SSSTSTSN | PUSH 10 | |
73 | TSSN | MULTIPLY | |
74 | TSSS | ADD | |
75 | SNT | SWAP | |
76 | SSSTN | PUSH 1 | |
77 | TSSS | ADD | |
78 | SNT | SWAP | |
79 | NSNSSTTSSSSSSSSSTSSN | JMP > 00110000 00000100 (atoi:main_loop) | |
80 | ||
81 | @ Clean up and return | |
82 | @ TOS> character, accumulator, string_ptr, sign_flag | |
83 | NSSVSSTTSSSSSSSSSTSTN | Mark: 00110000 00000101 (found_end_of_number) | |
84 | SNN | DROP | |
85 | SSSTTN | PUSH 3 | |
86 | NSTTSTTN | JSR > 1011 (stackrotatereverse) | |
87 | TSSN | MULTIPLY | |
88 | SNT | SWAP | |
89 | NTN | RTS | |
90 | ||
91 | #endif |