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