-
Notifications
You must be signed in to change notification settings - Fork 1
/
codegen.cpp
683 lines (600 loc) · 20.4 KB
/
codegen.cpp
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
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
// codegen.cpp : This is gode generatore for Etherest assemler
//
// With hope that this code useful stuff but without any warranty
//
// This file distributed under Xameleon Green License
//
#include "generators.h"
#include "yaforth.h"
#include <chrono>
#ifdef _WIN32
#define itoa _itoa
#else
char * itoa(uint32_t v, char * buff, int r)
{
int n = snprintf(buff, 16, "%d", v);
if(!n) {
n = snprintf(buff, 16, "0");
}
return buff;
}
#endif
static FILE* OUT = stdout;
static unsigned int label_idx = 0;
static unsigned int loop_count = 0;
bool show_pcode = true;
static std::map<word_t, std::string> iflabels;
void append_label(const char *s, word_t addr)
{
iflabels[addr] = s;
}
void genetate_strings(ram_memory& memory)
{
function_list_t program = get_program();
for (const auto& fun : program)
{
for (const auto& str : fun.strings)
{
auto name = str.first.c_str();
auto value = str.second;
function_t* cf = lookup_current_function();
if (cf)
{
uint32_t storage = memory.get_current_address();
{
fprintf(OUT, "%s\tdb\t'", name);
uint32_t idx = value;
memory.jump(idx);
uint32_t len = memory.get();
int rest = len % 4;
for (int l = (len + 3) / 4; l; --l)
{
bool lw = len == 1;
word_t w = memory.get();
for (int j = 0; j < (lw ? rest : 4); ++j)
{
int mask = 0xff & w;
w >>= 8;
if (!mask)
fprintf(OUT, "\0");
else
fprintf(OUT, "%c", mask);
}
}
fprintf(OUT, "\', 0\n");
// memory.jump(storage);
}
}
}
}
fprintf(OUT, "\n");
}
void generate_code(const char * src, ram_memory & memory, registry_t & words)
{
word_t word, prev;
memory.jump(0);
#if _WIN32
const std::chrono::time_point now{ std::chrono::system_clock::now() };
const std::chrono::year_month_day ymd{ std::chrono::floor<std::chrono::days>(now) };
#else
const auto now = std::chrono::system_clock::now();
const std::time_t t_c = std::chrono::system_clock::to_time_t(now);
#endif
if(src)
{
std::string filename(src);
filename.append(".asm");
OUT = fopen(filename.c_str(), "wt");
if (!OUT) {
OUT = stderr;
fprintf(OUT, "Unable open file '%s' for writing\n", filename.c_str());
}
}
else
{
OUT = stdout;
}
#ifdef _WIN32
fprintf(OUT, "; --- This is autogenerated on %04d%02d%02d from %s ---\n\n",
ymd.year(), ymd.month(),ymd.day(), src);
#else
std::string tns = std::ctime(&t_c);
fprintf(OUT, "; --- This is autogenerated on %s; --- from %s ----\n\n",
tns.c_str(), src);
#endif
fprintf(OUT, "assign r14 esp ; Return stack pointer\n");
fprintf(OUT, "assign r11 stack ; Data stack\n\n");
fprintf(OUT, "$fourth equ 3 ; Fourth element\n\n");
fprintf(OUT, "$third equ 2 ; Third element\n\n");
fprintf(OUT, "$second equ 1 ; Second element\n\n");
fprintf(OUT, "function crt0\n");
fprintf(OUT, " load stack, 0x8000; Set Data stack\n");
fprintf(OUT, " load esp, 0x7000; Set Return stack\n");
fprintf(OUT, " call decimal\n");
fprintf(OUT, " call _main\n");
fprintf(OUT, " send\n");
fprintf(OUT, "end\n\n");
fprintf(OUT, " include lib/asm/tty/tty.asm\n");
fprintf(OUT, " include lib/asm/tty/print_dec.asm\n");
fprintf(OUT, " include lib/asm/emulate/mul.asm\n\n");
word = prev = 0;
word_t prepre = 0;
bool vars_marked = false;
for (int i = 0; memory.get_current_address() < memory.get_execution_address(); ++i )
{
word_t a = memory.get_current_address();
if (iflabels.count(a)) {
fprintf(OUT, "%s:\n", iflabels[a].c_str());
}
prepre = prev;
prev = word;
word = memory.get();
if (words.count(word) == 0) {
const char* note = find_variable_by_address(a);
if (note == nullptr)
note = "Not in dictionary";
fprintf(OUT, " dq 0x%08x ; %s IP = %08x\n", word, note, a);
vars_marked = true;
continue;
}
if (vars_marked) {
fprintf(OUT, "\n");
vars_marked = false;
}
record_t* rec = &words[word];
switch (rec->TYPE)
{
case builtin:
if (rec->NAME.size() == 0)
{
;
}
if(show_pcode)
fprintf(OUT, "; --- WORD [%d] = %s\n", i, rec->NAME.c_str());
if (rec->GENERATE)
rec->GENERATE(&memory, rec);
break;
case user:
if (show_pcode)
fprintf(OUT, "; --- WORD [%d]\n", i);
fprintf(OUT, " call %s\n", rec->NAME.c_str());
break;
case constant:
if (show_pcode)
fprintf(OUT, "WORD [%d] = %d\n", i, rec->CONSTANT);
break;
default:
fprintf(OUT, "Unparsed type\n");
}
}
genetate_strings(memory);
}
void asm_push_value(ram_memory * mem, struct word_record* rec)
{
word_t value = mem->get();
fprintf(OUT, " load r6, %d\n", value);
fprintf(OUT, " dec stack, 4\n");
fprintf(OUT, " mov (stack), r6\n");
}
void asm_jump(ram_memory* mem, struct word_record* rec)
{
word_t a = mem->get();
char buff[100];
std::string label("label_");
label += itoa(a, buff, 10);
fprintf(OUT, " jmp %s\n", label.c_str());
append_label(label.c_str(), a);
}
void asm_here(ram_memory* mem, struct word_record* rec)
{
fprintf(OUT, " dec stack, 4\n");
fprintf(OUT, " mov (stack), stack\n");
}
void asm_store(ram_memory* mem, struct word_record* rec)
{
// fprintf(OUT, ";; --------- ASM store -----------\n");
fprintf(OUT, " mov r6, (stack)\n");
fprintf(OUT, " inc stack, 4\n");
fprintf(OUT, " mov r5, (stack)\n");
fprintf(OUT, " inc stack, 4\n");
fprintf(OUT, " shl r6, 2\n");
fprintf(OUT, " mov (r6), r5\n");
}
void asm_fetch(ram_memory* mem, struct word_record* rec)
{
fprintf(OUT, " mov r6, (stack)\n");
fprintf(OUT, " shl r6, 2\n");
fprintf(OUT, " mov r5, (r6)\n");
fprintf(OUT, " mov (stack), r5\n");
}
void asm_add(ram_memory* mem, struct word_record* rec)
{
fprintf(OUT, " mov r5, (stack)\n");
fprintf(OUT, " inc stack, 4\n");
fprintf(OUT, " mov r6, (stack)\n");
fprintf(OUT, " clc\n");
fprintf(OUT, " addc r6, r5\n");
fprintf(OUT, " mov (stack), r6\n");
}
void asm_sub(ram_memory* mem, struct word_record* rec)
{
fprintf(OUT, " mov r5, (stack)\n");
fprintf(OUT, " inc stack, 4\n");
fprintf(OUT, " mov r6, (stack)\n");
fprintf(OUT, " clc\n");
fprintf(OUT, " subc r6, r5\n");
fprintf(OUT, " mov (stack), r6\n");
}
void asm_mul(ram_memory* mem, struct word_record* rec)
{
fprintf(OUT, " mov r0, (stack)\n");
fprintf(OUT, " inc stack, 4\n");
fprintf(OUT, " mov r1, (stack)\n");
fprintf(OUT, " call _mul\n");
fprintf(OUT, " mov (stack), r2\n");
}
void asm_div(ram_memory* mem, struct word_record* rec)
{
fprintf(OUT, " mov r2, (stack)\n");
fprintf(OUT, " inc stack, 4\n");
fprintf(OUT, " mov r0, (stack)\n");
fprintf(OUT, " call _div\n");
fprintf(OUT, " mov (stack), r0\n");
}
void asm_check_equ(ram_memory* mem, struct word_record* rec)
{
fprintf(OUT, " mov r6, (stack)\n");
fprintf(OUT, " inc stack, 4\n");
fprintf(OUT, " xor r0, r0\n");
fprintf(OUT, " cmp r6, (stack)\n");
fprintf(OUT, " jnz notsame_%d\n", ++label_idx);
fprintf(OUT, " load r0, -1\n");
fprintf(OUT, "notsame_%d:\n", label_idx);
fprintf(OUT, " mov (stack), r0\n");
}
void asm_check_notequ(ram_memory* mem, struct word_record* rec)
{
fprintf(OUT, " mov r6, (stack)\n");
fprintf(OUT, " inc stack, 4\n");
fprintf(OUT, " xor r0, r0\n");
fprintf(OUT, " cmp r6, (stack)\n");
fprintf(OUT, " jz same_%d\n", ++label_idx);
fprintf(OUT, " load r0, -1\n");
fprintf(OUT, "same_%d:\n", label_idx);
fprintf(OUT, " mov (stack), r0\n");
}
void asm_check_less(ram_memory* mem, struct word_record* rec)
{
fprintf(OUT, " mov r6, (stack)\n");
fprintf(OUT, " inc stack, 4\n");
fprintf(OUT, " xor r0, r0\n");
fprintf(OUT, " cmp r6, (stack)\n");
fprintf(OUT, " jbe noless_%d\n", ++label_idx);
//fprintf(OUT, " jc noless_%d\n", ++label_idx);
//// fprintf(OUT, " jnc noless_%d\n", ++label_idx);
fprintf(OUT, " load r0, -1\n");
fprintf(OUT, "noless_%d:\n", label_idx);
fprintf(OUT, " mov (stack), r0\n");
}
void asm_check_more(ram_memory* mem, struct word_record* rec)
{
fprintf(OUT, " mov r6, (stack)\n");
fprintf(OUT, " inc stack, 4\n");
fprintf(OUT, " xor r0, r0\n");
fprintf(OUT, " cmp r6, (stack)\n");
fprintf(OUT, " ja nomore_%d\n", ++label_idx);
//fprintf(OUT, " jnc nomore_%d\n", ++label_idx);
//// fprintf(OUT, " jc nomore_%d\n", ++label_idx);
fprintf(OUT, " load r0, -1\n");
fprintf(OUT, "nomore_%d:\n", label_idx);
fprintf(OUT, " mov (stack), r0\n");
}
void asm_and(ram_memory* mem, struct word_record* rec)
{
fprintf(OUT, " mov r6, (stack)\n");
fprintf(OUT, " inc stack, 4\n");
fprintf(OUT, " and (stack), r6\n");
}
void asm_or(ram_memory* mem, struct word_record* rec)
{
fprintf(OUT, " mov r6, (stack)\n");
fprintf(OUT, " inc stack, 4\n");
fprintf(OUT, " or (stack), r6\n");
}
void asm_xor(ram_memory* mem, struct word_record* rec)
{
fprintf(OUT, " mov r6, (stack)\n");
fprintf(OUT, " inc stack, 4\n");
fprintf(OUT, " xor (stack), r6\n");
}
void asm_left_shift(ram_memory* mem, struct word_record* rec)
{
fprintf(OUT, " mov r5, (stack)\n");
fprintf(OUT, " inc stack, 4\n");
fprintf(OUT, " mov r6, (stack)\n");
fprintf(OUT, " shl r6, r5\n");
fprintf(OUT, " mov (stack), r6\n");
}
void asm_right_shift(ram_memory* mem, struct word_record* rec)
{
fprintf(OUT, " mov r5, (stack)\n");
fprintf(OUT, " inc stack, 4\n");
fprintf(OUT, " mov r6, (stack)\n");
fprintf(OUT, " shr r6, r5\n");
fprintf(OUT, " mov (stack), r6\n");
}
void asm_not(ram_memory* mem, struct word_record* rec)
{
fprintf(OUT, " not (stack)\n");
}
void asm_mod(ram_memory* mem, struct word_record* rec)
{
fprintf(OUT, " mov r2, (stack)\n");
fprintf(OUT, " inc stack, 4\n");
fprintf(OUT, " mov r0, (stack)\n");
fprintf(OUT, " call _div\n");
fprintf(OUT, " mov (stack), r2\n");
}
void asm_divmod(ram_memory* mem, struct word_record* rec)
{
// fprintf(OUT, " xor r1, r1\n");
fprintf(OUT, " mov r2, (stack)\n");
fprintf(OUT, " inc stack, 4\n");
fprintf(OUT, " mov r0, (stack)\n");
fprintf(OUT, " call _div\n");
fprintf(OUT, " mov (stack), r2\n");
fprintf(OUT, " dec stack, 4\n");
fprintf(OUT, " mov (stack), r0\n");
}
void asm_dup(ram_memory* mem, struct word_record* rec)
{
fprintf(OUT, " mov r6, (stack)\n");
fprintf(OUT, " dec stack, 4\n");
fprintf(OUT, " mov (stack), r6\n");
}
void asm_swap(ram_memory* mem, struct word_record* rec)
{
fprintf(OUT, " mov r6, stack.second\n");
fprintf(OUT, " mov r5, (stack)\n");
fprintf(OUT, " mov (stack), r6\n");
fprintf(OUT, " mov stack.second, r5\n");
}
void asm_over(ram_memory* mem, struct word_record* rec)
{
fprintf(OUT, " mov r6, stack.second\n");
fprintf(OUT, " dec stack, 4\n");
fprintf(OUT, " mov (stack), r6\n");
}
void asm_rot(ram_memory* mem, struct word_record* rec)
{
fprintf(OUT, " mov r6, (stack)\n");
fprintf(OUT, " mov r5, stack.second\n");
fprintf(OUT, " mov r4, stack.third\n");
fprintf(OUT, " mov (stack), r6\n"); // Лениво думать, легче отладить в эиуляторе
fprintf(OUT, " mov stack.second, r4\n");
fprintf(OUT, " mov stack.third, r5\n");
}
void asm_drop(ram_memory* mem, struct word_record* rec)
{
fprintf(OUT, " inc stack, 4\n");
}
void asm_dot(ram_memory* mem, struct word_record* rec)
{
label_idx += 3;
// Check current base
uint32_t h = hash("base");
record_t* r = find_record(h);
fprintf(OUT, " load r6, %x\n", r->ADDR);
fprintf(OUT, " mov r0, (r6)\n");
fprintf(OUT, " load r6, 10\n");
fprintf(OUT, " cmp r6, r0\n");
fprintf(OUT, " je label_dec_%d\n", label_idx - 2);
fprintf(OUT, " mov r0, (stack)\n");
fprintf(OUT, " call _print_hex\n");
fprintf(OUT, " load r3, 32\n");
fprintf(OUT, " jmp leave_%d\n", label_idx - 1);
fprintf(OUT, "label_dec_%d:\n", label_idx - 2);
// print decimal number
fprintf(OUT, " mov r0, (stack)\n");
fprintf(OUT, " load r3, 0x80000000\n");
fprintf(OUT, " and r3, r0\n");
fprintf(OUT, " je label_print_%d\n", label_idx);
fprintf(OUT, " neg r0\n");
fprintf(OUT, " mov (stack), r0\n");
fprintf(OUT, " load r3, 45 ; '-'\n");
fprintf(OUT, " call _putchar\n");
fprintf(OUT, " mov r0, (stack)\n");
fprintf(OUT, "label_print_%d:\n", label_idx);
fprintf(OUT, " call _print_dec\n");
fprintf(OUT, "leave_%d:\n", label_idx - 1);
fprintf(OUT, " load r3, 32\n");
fprintf(OUT, " call _putchar\n");
fprintf(OUT, " inc stack, 4\n");
}
void asm_key(ram_memory* mem, struct word_record* rec)
{
fprintf(OUT, " call _getchar\n");
fprintf(OUT, " dec stack, 4\n");
fprintf(OUT, " mov (stack), r0\n");
}
void asm_emit(ram_memory* mem, struct word_record* rec)
{
fprintf(OUT, " mov r3, (stack)\n");
fprintf(OUT, " inc stack, 4\n");
fprintf(OUT, " call _putchar\n");
}
void asm_print_string(ram_memory* mem, struct word_record* rec)
{
static int draw_string_counter = 0;
std::string text("$textline_");
++draw_string_counter;
text += std::to_string(draw_string_counter);
word_t jmp = mem->get();
word_t addr = mem->get();
bool local = try_register_local_string(text, mem->get_current_address());
word_t len = mem->get();
if (local)
{
if (len & 0x3)
len = 1 + (len % 4) + mem->get_current_address();
else
len = (len % 4) + mem->get_current_address();
mem->jump(addr);
}
else
{
// fprintf(OUT, " jmp puts_%d ; \n\n", ++label_idx);
fprintf(OUT, "%s\tdb\t'", text.c_str());
int rest = len % 4;
for (int l = (len + 3) / 4; l; --l)
{
bool lw = len == 1;
word_t w = mem->get();
for (int j = 0; j < (lw ? rest : 4); ++j)
{
int mask = 0xff & w;
w >>= 8;
if (!mask)
fprintf(OUT, "\0");
else
fprintf(OUT, "%c", mask);
}
}
fprintf(OUT, "\' ; To fix\n\n");
// fprintf(OUT, "puts_%d:\n", label_idx);
}
fprintf(OUT, " lea r1, %s\n", text.c_str());
fprintf(OUT, " call _puts\n");
}
void asm_return(ram_memory* mem, struct word_record* rec)
{
fprintf(OUT, " mov r15, (esp)\n");
fprintf(OUT, " inc esp, 4\n");
fprintf(OUT, " return\n");
fprintf(OUT, "end\n\n");
}
void asm_if(ram_memory* mem, struct word_record* rec)
{
word_t w = mem->get();
char buff[100];
std::string label("nottrue_");
label += itoa(w, buff, 10);
fprintf(OUT, " mov r0, (stack)\n");
fprintf(OUT, " inc stack, 4\n");
fprintf(OUT, " or r0, r0\n");
fprintf(OUT, " jz %s\n", label.c_str());
append_label(label.c_str(), w);
}
void asm_to_R(ram_memory* mem, struct word_record* rec)
{
fprintf(OUT, " mov r0, (stack)\n");
fprintf(OUT, " inc stack, 4\n");
fprintf(OUT, " dec esp, 4\n");
fprintf(OUT, " mov (esp), r0\n");
}
void asm_from_R(ram_memory* mem, struct word_record* rec)
{
fprintf(OUT, " mov r0, (esp)\n");
fprintf(OUT, " inc esp, 4\n");
fprintf(OUT, " dec stack, 4\n");
fprintf(OUT, " mov (stack), r0\n");
}
void asm_fetch_R(ram_memory* mem, struct word_record* rec)
{
fprintf(OUT, " mov r0, (esp)\n");
fprintf(OUT, " dec stack, 4\n");
fprintf(OUT, " mov (stack), r0\n");
}
void asm_function(ram_memory* mem, struct word_record* rec)
{
word_t w = mem->get();
struct word_record* fn = find_record(w);
if (!fn) {
fprintf(stderr, "Cannot find function\n");
return;
}
fprintf(OUT, "function %s\n", fn->NAME.c_str());
fprintf(OUT, " dec esp, 4\n");
fprintf(OUT, " mov (esp), r15\n");
}
void asm_loop(ram_memory* mem, struct word_record* rec)
{
++loop_count;
fprintf(OUT, " mov r0, (stack)\n");
fprintf(OUT, " inc stack, 4\n");
fprintf(OUT, " mov r1, (stack)\n");
fprintf(OUT, " inc stack, 4\n");
fprintf(OUT, " dec esp, 8\n");
// fprintf(OUT, " mov esp[4], r1\n"); // Или наоборт? В отладку!
fprintf(OUT, " mov esp.second, r1\n");
fprintf(OUT, " mov (esp), r0\n");
fprintf(OUT, "looplabel_%d:\n", loop_count); // Добаить стек меток
}
void asm_endloop(ram_memory* mem, struct word_record* rec)
{
word_t addr = mem->get();
fprintf(OUT, " mov r0, (esp)\n");
fprintf(OUT, " inc r0\n");
fprintf(OUT, " mov (esp), r0\n");
fprintf(OUT, " cmp r0, esp.second\n");
fprintf(OUT, " jne looplabel_%d\n", loop_count);
fprintf(OUT, "leave_%d:\n", loop_count--);
fprintf(OUT, " inc esp, 8\n");
}
void asm_endplusloop(ram_memory* mem, struct word_record* rec)
{
word_t addr = mem->get();
fprintf(OUT, " mov r6, (stack)\n");
fprintf(OUT, " inc stack, 4\n");
fprintf(OUT, " mov r0, (esp)\n");
fprintf(OUT, " clc\n");
fprintf(OUT, " addc r0, r6\n");
fprintf(OUT, " mov (esp), r0\n");
fprintf(OUT, " cmp r0, esp.second\n");
fprintf(OUT, " jne looplabel_%d\n", loop_count);
fprintf(OUT, "leave_%d:\n", loop_count--);
fprintf(OUT, " inc esp, 8\n");
}
void asm_index_i(ram_memory* mem, struct word_record* rec)
{
fprintf(OUT, " mov r0, (esp)\n");
fprintf(OUT, " dec stack, 4\n");
fprintf(OUT, " mov (stack), r0\n");
}
void asm_index_j(ram_memory* mem, struct word_record* rec)
{
if (loop_count < 2)
{
fprintf(stderr, "No j variable defined in current context\n");
exit(-1);
}
fprintf(OUT, ";;; debug\n");
fprintf(OUT, " mov r0, esp.third\n");
fprintf(OUT, " dec stack, 4\n");
fprintf(OUT, " mov (stack), r0\n");
}
void asm_leave(ram_memory* mem, struct word_record* rec)
{
word_t addr = mem->get();
fprintf(OUT, " jmp leave_%d\n", loop_count);
}
void asm_beginloop(ram_memory* mem, struct word_record* rec)
{
loop_count++;
fprintf(OUT, "loopbegin_%d:\n", loop_count); // Добаить стек меток
}
void asm_untilloop(ram_memory* mem, struct word_record* rec)
{
fprintf(OUT, " mov r0, (stack)\n");
fprintf(OUT, " inc stack, 4\n");
fprintf(OUT, " inc r0\n");
fprintf(OUT, " js loopbegin_%d\n", loop_count);
loop_count--;
}
void asm_again(ram_memory* mem, struct word_record* rec)
{
fprintf(OUT, " jmp loopbegin_%d\n", loop_count);
fprintf(OUT, "leave_%d:\n", loop_count);
loop_count--;
}