Added 'atoi' to stdlib.
[vvhitespace] / stdlib / convert.pvvs
CommitLineData
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>
25NSSVTTSSSSN | 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.
29SNS | DUP
30TTT | LOAD
31SSSSSTSTTSTN | PUSH 45 (ASCII '-')
32TSST | SUBTRACT
33NTSSSTTSSSSSSSSSSSSN | BRZ > 00110000 00000000 (found_minus_sign)
34SNS | DUP
35TTT | LOAD
36SSSSSTSTSTTN | PUSH 43 (ASCII '+')
37TSST | SUBTRACT
38NTSSSTTSSSSSSSSSSSTN | BRZ > 00110000 00000001 (found_plus_sign)
39NSNSSTTSSSSSSSSSSTSN | JMP > 00110000 00000010 (found_digit)
40NSSVSSTTSSSSSSSSSSSTN | Mark: 00110000 00000001 (found_plus_sign)
41SSSTN | PUSH +1
42TSSS | ADD
43NSSVSSTTSSSSSSSSSSTSN | Mark: 00110000 00000010 (found_digit)
44SSSTN | PUSH +1 (sign_flag)
45SNT | SWAP
46NSNSSTTSSSSSSSSSSTTN | JMP > 00110000 00000011 (done_with_sign_flag)
47NSSVSSTTSSSSSSSSSSSSN | Mark: 00110000 00000000 (found_minus_sign)
48SSSTN | PUSH +1
49TSSS | ADD
50SSTTN | PUSH -1 (sign_flag)
51SNT | SWAP
52NSSVSSTTSSSSSSSSSSTTN | Mark: 00110000 00000011 (done_with_sign_flag)
53
54@ Create an accumulator on the TOS.
55SSSSN | 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
59NSSVSSTTSSSSSSSSSTSSN | Mark: 00110000 00000100 (atoi:main_loop)
60SSSTSN | PUSH +2
61NSTTTSSN | JSR > 1100 (deepdup)
62TTT | LOAD
63SNS | DUP
64NSTTSSSSTN | JSR > 100001 (isdigit)
65NTSSSTTSSSSSSSSSTSTN | BRZ > 00110000 00000101 (found_end_of_number)
66SSSSSTTSSSSN | PUSH 48 (ASCII '0')
67TSST | SUBTRACT
68SNT | SWAP
69SSSTSTSN | PUSH 10
70TSSN | MULTIPLY
71TSSS | ADD
72SNT | SWAP
73SSSTN | PUSH 1
74TSSS | ADD
75SNT | SWAP
76NSNSSTTSSSSSSSSSTSSN | JMP > 00110000 00000100 (atoi:main_loop)
77
78@ Clean up and return
79@ TOS> character, accumulator, string_ptr, sign_flag
80NSSVSSTTSSSSSSSSSTSTN | Mark: 00110000 00000101 (found_end_of_number)
81SNN | DROP
82SSSTTN | PUSH 3
83NSTTSTTN | JSR > 1011 (stackrotatereverse)
84TSSN | MULTIPLY
85SNT | SWAP
86NTN | RTS
87
88#endif