-
Notifications
You must be signed in to change notification settings - Fork 138
/
m0_args.m0
155 lines (126 loc) · 3.44 KB
/
m0_args.m0
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
.version 0
.chunk "args_test"
.constants
0 "1..2\n"
1 "\n"
2 "ok 1 - arg count: got 6 arguments!\n"
3 "not ok 1 - arg count: didn't get 6 arguments (got "
4 "ok 2 - arg contents: second argument was 'kittens'\n"
5 "nok 2 - arg contents: second argument was not 'kittens'\n"
6 " arguments)\n"
7 "kittens"
8 "looping\n"
9 "nok 2 - arg contents: second argument isn't 8 characters long\n"
.metadata
.bytecode
set_imm S2, 0, 8
deref S2, CONSTS, S2
set_imm S3, 0, 1
deref S3, CONSTS, S3
# print 1..2
set_imm I0, 0, 0
set_imm S0, 0, 0
deref S0, CONSTS, S0
print_s I0, S0, x
# I1 is the arg count
set_imm I1, 0, ARGC
deref I1, INTERP, I1
# I2 is the expected arg count
set_imm I2, 0, 6
sub_i I2, I2, I1
goto_if argc_nok, I2
goto argc_ok, x
argc_nok:
# print "nok 1 "...
set_imm S0, 0, 3
deref S0, CONSTS, S0
print_s I0, S0, x
# print the actual arg count
print_i I0, I1, x
# finish printing the nok message, continue to the argv test
set_imm S0, 0, 6
deref S0, CONSTS, S0
print_s I0, S0, x
goto argv_test, x
argc_ok:
# print "ok 1"...
set_imm S0, 0, 2
deref S0, CONSTS, S0
print_s I0, S0, x
# continue to the argv test
goto argv_test, x
argv_test:
# put argv[1] into S0 (argv[0] is the name of this file)
set_imm I0, 0, 0
set_imm I1, 0, 1
set_imm S0, 0, ARGV
deref S0, INTERP, S0
deref S0, S0, I1
# put the number of bytes in argv[1] string into I3
# (number of bytes in a string is in the first word of the string)
get_word I3, S0, I0
# put the expected value of argv[1] into S1 ("kittens")
set_imm S1, 0, 7
deref S1, CONSTS, S1
# put the number of bytes in string into I2
# (number of bytes in a string is in the first word of the string)
get_word I2, S1, I0
# because debugging m0 is hard
goto skip_print_92, x
print_s I0, S2, x
print_i I0, I3, x
print_s I0, S3, x
print_i I0, I2, x
print_s I0, S3, x
skip_print_92:
# test if argv[1] and the reference string are the same length
sub_i I3, I3, I2
goto_if argv_nok_size, I3
# subtract 1 to avoid comparing the terminal null
sub_i I2, I2, I1
# check the strings in S0 and S1 for equality,
string_cmp_loop:
# put number of characters remaining into I2
sub_i I2, I2, I1
# store the char at S1[I2 + 8] in I4
# skip past the string header
set_imm I5, 0, 8
add_i I5, I2, I5
# store the value of the current char in I4 and I3
get_byte I4, S1, I5
get_byte I3, S0, I5
goto skip_print_121, x
print_s I0, S2, x
print_i I0, I2, x
print_s I0, S3, x
print_i I0, I3, x
print_s I0, S3, x
print_i I0, I4, x
print_s I0, S3, x
skip_print_121:
# if i3 != i4 (the two characters from the string differ), fail
sub_i I3, I3, I4
goto_if argv_nok_chars, I3
# if there are more characters to compare, continue
goto_if string_cmp_loop, I2
goto argv_ok, x
argv_nok_chars:
set_imm S0, 0, 5
deref S0, CONSTS, S0
print_s I0, S0, x
goto end, x
argv_nok_size:
set_imm S0, 0, 9
deref S0, CONSTS, S0
print_s I0, S0, x
goto end, x
argv_ok:
set_imm S0, 0, 4
deref S0, CONSTS, S0
print_s I0, S0, x
goto end, x
end:
set_imm I0, 0, 0
exit I0, x, x
# This code isn't really PASM, but the highlighting works well.
# vim: expandtab shiftwidth=4 ft=pasm: