/
e89.pasm
178 lines (173 loc) · 4.04 KB
/
e89.pasm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
.loadlib 'io_ops'
#ASCII values of important letters
.macro_const M 77
.macro_const D 68
.macro_const C 67
.macro_const L 76
.macro_const X 88
.macro_const V 86
.macro_const I 73
#Impromptu convention:
#arguments passed in I/S 1, returned in I/S 0
.pcc_sub :main main:
#'The Stack'
new P10,'ResizableIntegerArray'
getstdin P0
set I9, 0
MAINLOOP:
readline S1, P0
unless S1, FINAL
#get length of string
length I8, S1
#subtract 2 from length because windows newline
sub I8, I8, 2
inc I8
#cutoff one char of newline, as methods expect
#UNIX newlines
substr S1, S1, 0, I8
dec I8
#Now that that is done...
local_branch P10, GET_STRING_VALUE
local_branch P10, GET_CHAR_COUNT
sub I0, I8, I0
add I9, I9, I0
branch MAINLOOP
FINAL:
say I9
end
#Basically a switch statement
#input: I0
#output: I0
GET_CHAR_VALUE:
eq I0, .M, M
eq I0, .D, D
eq I0, .C, C
eq I0, .L, L
eq I0, .X, X
eq I0, .V, V
I:
set I0, 1
local_return P10
V:
set I0, 5
local_return P10
X:
set I0, 10
local_return P10
L:
set I0, 50
local_return P10
C:
set I0, 100
local_return P10
D:
set I0, 500
local_return P10
M:
set I0, 1000
local_return P10
#compute integer corresponding to Roman Numeral
#input: S1
#output: I0
#used: I2, I3, I4, I5, S2
GET_STRING_VALUE:
length I2, S1
dec I2
set I3, 0
set I4, 0
set I5, 0
LOOP:
ge I3, I2, ENDLOOP
substr S2, S1, I3, 1
ord I0, S2
local_branch P10, GET_CHAR_VALUE
set I4, I0
inc I3
substr S2, S1, I3, 1
ord I0, S2
local_branch P10, GET_CHAR_VALUE
lt I4, I0, _SUB
add I5, I5, I4
branch LOOP
_SUB:
sub I5, I5, I4
branch LOOP
ENDLOOP:
set I0, I5
local_return P10
#This could be written much more nicely
#If I could figure out how to do arrays
#input: I0
#used: I1, I6, I7
GET_CHAR_COUNT:
#Move input into I1
#And compute number of M's
set I1, I0
div I6, I1, 1000
mul I0, I6, 1000
sub I1, I1, I0
set I7, I6
#CM
div I6, I1, 900
mul I0, I6, 900
sub I1, I1, I0
mul I6, I6, 2
add I7, I7, I6
#D
div I6, I1, 500
mul I0, I6, 500
sub I1, I1, I0
add I7, I7, I6
#CD
div I6, I1, 400
mul I0, I6, 400
sub I1, I1, I0
mul I6, I6, 2
add I7, I7, I6
#C
div I6, I1, 100
mul I0, I6, 100
sub I1, I1, I0
add I7, I7, I6
#XC
div I6, I1, 90
mul I0, I6, 90
sub I1, I1, I0
mul I6, I6, 2
add I7, I7, I6
#L
div I6, I1, 50
mul I0, I6, 50
sub I1, I1, I0
add I7, I7, I6
#XL
div I6, I1, 40
mul I0, I6, 40
sub I1, I1, I0
mul I6, I6, 2
add I7, I7, I6
#X
div I6, I1, 10
mul I0, I6, 10
sub I1, I1, I0
add I7, I7, I6
#IX
div I6, I1, 9
mul I0, I6, 9
sub I1, I1, I0
mul I6, I6, 2
add I7, I7, I6
#V
div I6, I1, 5
mul I0, I6, 5
sub I1, I1, I0
add I7, I7, I6
#IV
div I6, I1, 4
mul I0, I6, 4
sub I1, I1, I0
mul I6, I6, 2
add I7, I7, I6
#I
add I0, I7, I1
local_return P10