~aleteoryx/uxn

ref: b75b4763502847f802b63ac0119ba27c07f9ec94 uxn/nanpa.tal -rw-r--r-- 4.8 KiB
b75b4763Aleteoryx gif work, brainfuck compiler 8 months ago
                                                                                
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
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
|0 @System &pad $f &state $1
|10 @Console &vector $2 &read $1 &pad $4 &type $1 &write $1 &error $1

|0 @State &numType $1 &number $2 &err $1 &errChar $1
	@flag $1

|0 @NumType &decimal $1 &binary $1 &octal $1 &hexcadecimal $1


|100
@on-reset ( -> )
	.Console/type DEI ?{ prompt BRK }
	;on-console .Console/vector DEO2
	BRK

@on-console ( -> )
	#63 .Console/write DEO
	.Console/type DEI #04 NEQ ?{ prompt } BRK

@on-prefix ( -> ) ( FIXME: this could be simpler )
	[ LITr 00 ]
	.Console/read DEI 
	DUP #30 NEQ ?{ .NumType/octal .State/numType STZ BRK }

	DUP LIT "b NEQ ?{ .NumType/binary	!&matched }
	DUP LIT "o NEQ ?{ .NumType/octal	!&matched }
	DUP LIT "d NEQ ?{ .NumType/decimal	!&matched }
	DUP LIT "x NEQ ?{ .NumType/hexcadecimal	!&matched }
	    LIT "q NEQ ?{ #80 .System/state DEO } ( exit on 'q' )
	.State/numType LDZ ( will fallthrough to decimal or octal )
	[ LITr 01 ]

	&matched
	DUP .State/numType STZ #10 SFT2 #00 SWP
	;&parsers ADD2 LDA2 DUP2 .Console/vector DEO2
	STHr ?{ BRK } JMP2 ( jump to the handler if we matched a non-prefix )

	&parsers [ =on-decimal =on-binary =on-octal =on-hexcadecimal ]

@peek2 ( val* -- val* )
	LIT "x .Console/write DEO
	DUP2 SWP printhex printhex
	JMP2r

@on-binary ( -> )
	.Console/read DEI
	DUP #0a NEQ ?{ finish-number }
	DUP #fe AND DUP #30 EQU ?{ err-encoding }
	EOR #00 SWP
	.State/number LDZ2 #10 SFT2 ORA2
	.State/number STZ2
	BRK
@on-octal ( -> )
	.Console/read DEI
	DUP #0a NEQ ?{ finish-number }
	DUP #f8 AND DUP #30 EQU ?{ err-encoding }
	EOR #00 SWP
	.State/number LDZ2 #30 SFT2 ORA2
	.State/number STZ2
	BRK
@on-decimal ( -> )
	.Console/read DEI
	DUP #0a NEQ ?{ finish-number }
	#30 SUB DUP #0a LTH ?{ err-encoding }
	#00 SWP
	.State/number LDZ2 #000a MUL2 ADD2
	.State/number STZ2
	BRK
@on-hexcadecimal ( -> )
	.Console/read DEI
	DUP #0a NEQ ?{ finish-number }
	#30 SUB DUP #09 GTH ?{ !&incr } ( 0-9 )
	#07 SUB DUP #0f GTH ?{ !&incr } ( A-F )
	#20 SUB DUP #0f GTH ?{ !&incr } ( a-f )
	err-encoding

	&incr
	#00 SWP
	.State/number LDZ2 #40 SFT2 ORA2
	.State/number STZ2
	BRK

@on-error ( -> )
	.Console/read DEI #0a EQU ?{ BRK }
	;Errors/prefix puts
	.State/errChar LDZ .Console/write DEO
	;Errors/prefix2 puts
	;Encodings/tab .State/numType LDZ indextab puts
	;Errors/prefix3 puts
	;Errors/tab .State/err LDZ indextab puts
	#0a .Console/write DEO
	prompt
	BRK

@err-encoding ( char -- )
	.Console/read DEI .State/errChar STZ
	#01 .State/err STZ
	;on-error .Console/vector DEO2
	BRK

@finish-number ( -- )
	.State/number LDZ2
	LIT "0 .Console/write DEO
	LIT "b .Console/write DEO
	DUP2 OVR #00 EQU ?{ SWP DUP printbinary SWP } NIP printbinary
	#09 .Console/write DEO

	LIT "0 .Console/write DEO
	DUP2 printoctal
	#09 .Console/write DEO

	DUP2 printdecimal
	#09 .Console/write DEO

	LIT "0 .Console/write DEO
	LIT "x .Console/write DEO
	OVR #00 EQU ?{ SWP DUP printhex SWP } NIP printhex
	#0a .Console/write DEO

	prompt
	BRK

@prompt ( -- )
	#0000 .State/number STZ2
	#00 .State/numType STZ
	;on-prefix .Console/vector DEO2
	LIT "% .Console/write DEO
	#20 .Console/write DEO
	JMP2r

( HELPER ROUTINES )
@indextab ( list* idx -- ptr* )
	#02 MUL #00 SWP ADD2
	LDA2
	JMP2r

@puts ( str* -- )
	LDA2k SWP2 INC2 INC2 ( end* str+2* )
	&loop EQU2k ?&break
		LDAk .Console/write DEO
	INC2 !&loop
	&break POP2 POP2 JMP2r

@printhex ( num -- )
	#10 DIVk DUP printhexdigit
	MUL SUB printhexdigit
	JMP2r

@printdecimal ( num* -- )
	#01 .flag STZ
	[ LITr 00 ]
	#2710 DIV2k DUP2 NIP DUP #00 EQU ?{
		DUP printbcddigit
		#00 .flag STZ
	} POP
	MUL2 SUB2
	&loop
		#03e8 DIV2k DUP2 NIP ( get 1000s place )
		DUP #00 EQU .flag LDZ AND ?{ ( if flag || s != 0 )
			DUP printbcddigit
			#00 .flag STZ
		} POP
		MUL2 SUB2 #000a MUL2 ( DUP2 SWP printhex printhex )
	STHr #01 ADD DUP STH #04 NEQ
	( end ) ?&loop
	POPr POP2 JMP2r

@printoctal ( num* -- )
	#01 .flag STZ
	[ LITr 00 ]
	DUP2 #0f SFT2 NIP #00 EQU ?{
		#31 .Console/write DEO
		#00 .flag STZ
	}
	#10 SFT2
	&loop
		DUP2 #0d SFT2 NIP ( get top 3 bits )
		DUP #00 EQU .flag LDZ AND ?{ ( if flag || s != 0 )
			DUP printbcddigit
			#00 .flag STZ
		} POP
		#30 SFT2
	STHr #01 ADD DUP STH #05 NEQ
	( end ) ?&loop
	POPr POP2 JMP2r

@printbinary ( num -- )
	[ LITr 00 ]
	&loop
		DUP #07 SFT #30 ADD
		.Console/write DEO
		#10 SFT
	STHr #01 ADD DUP STH #08 NEQ
	( end ) ?&loop
	POPr POP JMP2r

@printhexdigit ( digit -- )
	#0f AND
	DUP #0a LTH ?{ #27 ADD } ( take top part, if 10-15 move to a-f )
	#30 ADD .Console/write DEO
	JMP2r
@printbcddigit ( digit -- )
	#0f AND
	#30 ADD .Console/write DEO
	JMP2r


( STRING DATA )
@Errors
	&prefix		={ "bad 20 "char 20 "' }
	&prefix2	={ "' 20 "for 20 }
	&prefix3	={ 20 "encoding: 20 }
	&unknown	={ "unknown 20 "error }
	&encoding	={ "not 20 "in 20 "range. }
	&tab		=&unknown =&encoding

@Encodings
	&binary		={ "binary }
	&octal		={ "octal }
	&decimal	={ "decimal }
	&hexcadecimal	={ "hexcadecimal }
	&tab		=&decimal =&binary =&octal =&hexcadecimal