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