-
Notifications
You must be signed in to change notification settings - Fork 0
/
RPN_converter.s
135 lines (112 loc) · 2.85 KB
/
RPN_converter.s
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
.text
.p2align 2
.global convert_to_RPN
convert_to_RPN:
mov x2, #0 // counter stack elements
main_loop: //scan the input string
ldrb w10, [x0], #1
cmp w10, #10
b.eq empty_the_stack //if the character is '\n' the input string is finished
number: //check if the character is a number
cmp w10, #'0'
b.lt open_bracket
cmp w10, #'9'
b.gt open_bracket
strb w10, [x1], #1
b main_loop
open_bracket: //check if the character is an open parenthesis
cmp w10, #'('
b.ne close_bracket
str w10, [sp, #-16]! //push '(' in the stack
add x2, x2, #1 //increment the stack counter
b main_loop
close_bracket: //check if the character is a close parenthesis
cmp w10, #')'
b.ne operators
mov w12, #32
strb w12,[x1], #1 // add a space before the operators to the output string
find_open_bracket:
cmp x2, #0 //if the stack is empty then quit with an error
b.eq error_exit
ldrb w10, [sp], #16 //pop from the stack
add x2, x2, #-1 //decrement the stack counter
cmp w10, #'('
b.eq main_loop
strb w10, [x1], #1
b find_open_bracket
operators: //check if the character is a operator
mov w11, #32 //if the character is a operator add a space in the output string
strb w11, [x1], #1
cmp x2, #0
b.ne loop_priority
strb w10, [sp, #-16]! //push operator in the stack
add x2, x2, #1 //increment the stack counter
b main_loop
loop_priority:
ldrb w11, [sp] //peek to the top of the stack
cmp w11, #'('
b.eq push_operator
cmp w11, #'+'
b.eq equal_priority
cmp w11, #'-'
b.eq equal_priority
ldrb w11, [sp], #16 //pop from the stack
add x2, x2, #-1 //decrement the stack counter
strb w11, [x1], #1
cmp x2, #0
b.eq push_operator
b loop_priority
equal_priority:
cmp w10, #'*'
b.eq push_operator
cmp w10, #'/'
b.eq push_operator
ldrb w11, [sp], #16 //pop from the stack
add x2, x2, #-1 //decrement the stack counter
strb w11, [x1], #1
cmp x2, #0 // if the stack is empty quit the loop
b.eq push_operator
b loop_priority
push_operator:
strb w10, [sp, #-16]! //push operator in the stack
add x2, x2, #1 //increment the stack counter
b main_loop
empty_the_stack:
cmp x2, #0
b.eq exit
ldrb w10, [sp], #16
add x2, x2, #-1
cmp w10, #'('
b.eq error_exit
mov w12, #32 //add a space before the operator
strb w12, [x1], #1
strb w10, [x1] , #1
b empty_the_stack
exit:
//ad a space in the output string (fundamental when the expression is only a number)
mov w10, #32
strb w10, [x1], #1
// add \n to the end of the output string
mov w10, #10
strb w10, [x1]
mov w0, #0
ret
error_exit: //if the parenthesis are not balanced return -1
add sp, sp, x2, lsl #4 //reset the stack pointer to the initial state
mov w0, #-1
ret
/*
.global _start
_start:
adr x0, str
adr x1, res
bl convert_to_RPN
mov x0, #1
mov x8, #93
svc #0
.data
.p2align 2
.global str
str: .string "1+(4-2\n"
res: .string "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
*/