diff -Nru 64tass-1.54.1900/64tass.1 64tass-1.55.2200/64tass.1 --- 64tass-1.54.1900/64tass.1 2019-02-17 21:46:22.000000000 +0000 +++ 64tass-1.55.2200/64tass.1 2020-03-23 22:12:04.000000000 +0000 @@ -1,4 +1,4 @@ -.TH 64tass 1 "Feb 17 2019" "64tass 1.54" "64tass 1.54" +.TH 64tass 1 "Mar 23 2020" "64tass 1.55" "64tass 1.55" .SH NAME 64tass \- A multi pass optimizing macro assembler for the 65xx series of processors .SH SYNOPSIS @@ -10,10 +10,11 @@ only describing the command line options. The many features are described in the HTML manual. .SH OPTIONS .sp 1 +.SS Output options .TP 0.5i \fB\-o\fR \fIfilename\fR, \fB\--output\fR \fIfilename\fR Place output into \fIfilename\fR. The default output filename is "a.out", -this option changes it. +this option changes it. May be used multiple times. The format is remembered but section reverts to global after each file. .TP 0.5i \fB\--output\-section\fR \fIsectionname\fR Output this section instead of everything @@ -70,6 +71,7 @@ Overlapping blocks are kept, data is stored in the definition order, and uninitialized memory areas are skipped. S19 up to 64 KiB, S28 up to 16 MiB and S37 up to 4 GiB. +.SS Operation options .TP 0.5i \fB\-a\fR, \fB\-\-ascii\fR Use ASCII/Unicode text encoding instead of raw 8-bit. @@ -103,6 +105,9 @@ Suppress displaying of faulty source line and fault position after fault messages. .TP 0.5i +\fB\-\-macro\-caret\-diag\fR +Restrict source line and fault position display to macro expansions only. +.TP 0.5i \fB\-q\fR, \fB\-\-quiet\fR Suppress messages. Disables header and summary messages. .TP 0.5i @@ -120,11 +125,15 @@ specified by repeating this option. If multiple matches exist the first one is used. .TP 0.5i -\fB\-M\fR \fIfile\fR +\fB\-M\fR \fIfile\fR, \fB\-\-dependencies\fR \fIfile\fR Specify make rule output \fIfile\fR. Writes a dependency rule suitable for 'make' from the list of files used during compilation. .TP 0.5i +\fB\-\-make\-phony\fR +Enable phony target generation for dependencies. +.SS Diagnostic options +.TP 0.5i \fB\-E\fR \fIfile\fR, \fB\-\-error\fR \fIfile\fR Specify error output \fIfile\fR. Normally compilation errors a written to the standard error output. It's @@ -175,6 +184,17 @@ This option gives a warning for instructions which were modified by the long branch function. Less intrusive than disabling long branches and see where it fails. .TP 0.5i +\fB\-Wmacro\-prefix\fR +Warn about macro call without prefix. +Such macro calls can easily be mistaken to be labels if invoked without parameters. +Also it's hard to notice that an unchanged call turned into label after the +definition got renamed. This warning helps to find such calls so that prefixes +can be added. +.TP 0.5i +\fB\-Wno\-addr\-wrap\fR +Don't warn about memory location address space wrap around. +If a memory location ends up outside of the processors address space then just wrap it around. +.TP 0.5i \fB\-Wno\-deprecated\fR Don't warn about deprecated features. Unfortunately there were some features added previously which shouldn't @@ -185,6 +205,11 @@ Floating point numbers have a finite precision and comparing them might give unexpected results. .TP 0.5i +\fB\-Wno\-float\-round\fR +Don't warn when floating point numbers are implicitly rounded. +A lot of parameters are expecting integers but floating point numbers are +accepted as well. The style of rounding used may or may not be what you wanted. +.TP 0.5i \fB\-Wno\-ignored\fR Don't warn about ignored directives. .TP 0.5i @@ -256,6 +281,7 @@ .TP 0.5i \fB\-Wunused-variable\fR Warn about unused variables. +.SS Target selection options .TP 0.5i \fB\-\-m65xx\fR Standard 65xx (default). For writing compatible code, no extra codes. @@ -287,18 +313,29 @@ .TP 0.5i \fB\-\-m4510\fR CSG 4510. Enables extra opcodes and addressing modes specific to this CPU. Useful for C65 projects. +.SS Symbol listing options .TP 0.5i \fB\-l\fR \fIfile\fR, \fR\-\-labels\fR=\fIfile\fR -List labels into \fIfile\fR. May be used multiple times. +List labels into \fIfile\fR. May be used multiple times. The format is remembered but root reverts to global after each file. +.TP 0.5i +\fB\-\-labels\-root\fR=\fI\fR +Specify the scope to list labels from. +.TP 0.5i +\fB\-\-normal\-labels\fR +Lists labels in a 64tass readable format. (default) +.TP 0.5i +\fB\-\-export\-labels\fR +List labels for include in a 64tass readable format. This will always compile exported .proc/.pend blocks assuming they're needed externally. .TP 0.5i \fB\-\-vice\-labels\fR List labels in a VICE readable format. .TP 0.5i +\fB\-\-vice\-labels\-numeric\fR +List labels in a VICE readable format, including numeric constants. +.TP 0.5i \fB\-\-dump\-labels\fR List labels for debugging. -.TP 0.5i -\fB\-\-labels\-root\fR=\fI\fR -Specify the scope to list labels from +.SS Assembly listing options .TP 0.5i \fB\-L\fR \fIfile\fR, \fB\-\-list\fR=\fIfile\fR List into \fIfile\fR. Dumps source code and compiled code into file. Useful for @@ -327,6 +364,7 @@ Normally the assembler tries to minimize listing output by omitting "unimportant" lines. But sometimes it's better to just list everything including comments and empty lines. +.SS Other options .TP 0.5i \fB\-?\fR, \fB\-\-help\fR Give this help list. Prints help about command line options. @@ -341,9 +379,9 @@ .SH AUTHOR Written by Zsolt Kajtar. .SH "REPORTING BUGS" -Online bug tracker: +Online bug tracker: .SH COPYRIGHT -Copyright \(co 2019 Zsolt Kajtar. +Copyright \(co 2020 Zsolt Kajtar. License GPLv2+: GNU GPL version 2 or later . .br This is free software: you are free to change and redistribute it. diff -Nru 64tass-1.54.1900/64tass.c 64tass-1.55.2200/64tass.c --- 64tass-1.54.1900/64tass.c 2019-02-16 16:48:56.000000000 +0000 +++ 64tass-1.55.2200/64tass.c 2020-04-06 23:07:14.000000000 +0000 @@ -1,6 +1,6 @@ /* Turbo Assembler 6502/65C02/65816/DTV - $Id: 64tass.c 1896 2019-02-16 16:48:56Z soci $ + $Id: 64tass.c 2199 2020-04-06 21:07:14Z soci $ 6502/65C02 Turbo Assembler Version 1.3 (c) 1996 Taboo Productions, Marek Matula @@ -75,7 +75,6 @@ struct Listing *listing = NULL; int temporary_label_branch; /* function declaration in function context, not good */ -linepos_t poke_pos; line_t vline; /* current line */ address_t all_mem, all_mem2; unsigned int all_mem_bits; @@ -123,6 +122,11 @@ address_t addr; Label *label; size_t membp; + } cmd_with; + struct { + address_t addr; + Label *label; + size_t membp; } cmd_weak; struct { address2_t laddr; @@ -151,6 +155,9 @@ } cmd_macro; struct { Obj *val; + } cmd_function; + struct { + Obj *val; } cmd_switch; } u; } *waitfors, *waitfor; @@ -171,7 +178,9 @@ "\x50" "binclude", "\x39" "block", "\x5a" "break", + "\x66" "breakif", "\x62" "brept", + "\x65" "bwhile", "\x05" "byte", "\x54" "case", "\x4e" "cdef", @@ -180,6 +189,7 @@ "\x36" "check", "\x1b" "comment", "\x59" "continue", + "\x67" "continueif", "\x37" "cpu", "\x33" "cwarn", "\x28" "databank", @@ -206,6 +216,7 @@ "\x49" "endu", "\x61" "endv", "\x58" "endweak", + "\x69" "endwith", "\x40" "eor", "\x25" "error", "\x16" "fi", @@ -256,6 +267,8 @@ "\x60" "virtual", "\x2b" "warn", "\x57" "weak", + "\x64" "while", + "\x68" "with", "\x0a" "word", "\x24" "xl", "\x23" "xs", @@ -277,7 +290,8 @@ CMD_BINCLUDE, CMD_FUNCTION, CMD_ENDF, CMD_SWITCH, CMD_CASE, CMD_DEFAULT, CMD_ENDSWITCH, CMD_WEAK, CMD_ENDWEAK, CMD_CONTINUE, CMD_BREAK, CMD_AUTSIZ, CMD_MANSIZ, CMD_SEED, CMD_NAMESPACE, CMD_ENDN, CMD_VIRTUAL, CMD_ENDV, - CMD_BREPT, CMD_BFOR + CMD_BREPT, CMD_BFOR, CMD_WHILE, CMD_BWHILE, CMD_BREAKIF, CMD_CONTINUEIF, + CMD_WITH, CMD_ENDWITH } Command_types; /* --------------------------------------------------------------------------- */ @@ -289,12 +303,11 @@ destroy_longjump(); destroy_encoding(); destroy_values(); - destroy_namespacekeys(); err_destroy(); destroy_file(); destroy_ternary(); - destroy_pairs(); destroy_opt_bit(); + free(arguments.output); free(arguments.symbol_output); if (unfc(NULL)) {} if (unfkc(NULL, NULL, 0)) {} @@ -398,15 +411,15 @@ /* * Skip memory */ -static void memskip(address_t db) { /* poke_pos! */ +static void memskip(address_t db, linepos_t epoint) { if (current_address->moved) { - if (current_address->address < current_address->start) err_msg2(ERROR_OUTOF_SECTION, NULL, poke_pos); - if (current_address->wrapwarn) {err_msg_mem_wrap(poke_pos);current_address->wrapwarn = false;} + if (current_address->address < current_address->start) err_msg2(ERROR_OUTOF_SECTION, NULL, epoint); + if (current_address->wrapwarn) {err_msg_mem_wrap(epoint);current_address->wrapwarn = false;} current_address->moved = false; } if (current_address->l_address.address > 0xffff || db > 0x10000 - current_address->l_address.address) { current_address->l_address.address = ((current_address->l_address.address + db - 1) & 0xffff) + 1; - err_msg_pc_wrap(poke_pos); + err_msg_pc_wrap(epoint); } else current_address->l_address.address += db; if (db > (~current_address->address & all_mem2)) { if (db - 1 + current_address->address == all_mem2) { @@ -414,11 +427,11 @@ if (current_address->end <= all_mem2) current_address->end = all_mem2 + 1; current_address->address = 0; } else { - if (current_address->start != 0) err_msg2(ERROR_OUTOF_SECTION, NULL, poke_pos); + if (current_address->start != 0) err_msg2(ERROR_OUTOF_SECTION, NULL, epoint); if (current_address->end <= all_mem2) current_address->end = all_mem2 + 1; current_address->moved = false; current_address->address = (current_address->address + db) & all_mem2; - err_msg_mem_wrap(poke_pos);current_address->wrapwarn = false; + err_msg_mem_wrap(epoint);current_address->wrapwarn = false; } } else current_address->address += db; memjmp(current_address->mem, current_address->address); @@ -428,15 +441,15 @@ /* * output one byte */ -FAST_CALL uint8_t *pokealloc(address_t db) { /* poke_pos! */ +FAST_CALL uint8_t *pokealloc(address_t db, linepos_t epoint) { if (current_address->moved) { - if (current_address->address < current_address->start) err_msg2(ERROR_OUTOF_SECTION, NULL, poke_pos); - if (current_address->wrapwarn) {err_msg_mem_wrap(poke_pos);current_address->wrapwarn = false;} + if (current_address->address < current_address->start) err_msg2(ERROR_OUTOF_SECTION, NULL, epoint); + if (current_address->wrapwarn) {err_msg_mem_wrap(epoint);current_address->wrapwarn = false;} current_address->moved = false; } if (current_address->l_address.address > 0xffff || db > 0x10000 - current_address->l_address.address) { current_address->l_address.address = ((current_address->l_address.address + db - 1) & 0xffff) + 1; - err_msg_pc_wrap(poke_pos); + err_msg_pc_wrap(epoint); } else current_address->l_address.address += db; if (db > (~current_address->address & all_mem2)) { if (db - 1 + current_address->address == all_mem2) { @@ -444,11 +457,11 @@ if (current_address->end <= all_mem2) current_address->end = all_mem2 + 1; current_address->address = 0; } else { - if (current_address->start != 0) err_msg2(ERROR_OUTOF_SECTION, NULL, poke_pos); + if (current_address->start != 0) err_msg2(ERROR_OUTOF_SECTION, NULL, epoint); if (current_address->end <= all_mem2) current_address->end = all_mem2 + 1; current_address->moved = false; current_address->address = (current_address->address + db) & all_mem2; - err_msg_mem_wrap(poke_pos);current_address->wrapwarn = false; + err_msg_mem_wrap(epoint);current_address->wrapwarn = false; } } else current_address->address += db; return alloc_mem(current_address->mem, db); @@ -458,18 +471,18 @@ static int get_command(void) { unsigned int no, also, felso, elozo; const uint8_t *label; - uint8_t tmp[10]; + uint8_t tmp[12]; lpoint.pos++; label = pline + lpoint.pos; if (arguments.caseinsensitive) { int i, j; - for (i = j = 0; i < 10; i++) { + for (i = j = 0; i < (int)sizeof tmp; i++) { if ((uint8_t)(label[i] - 'a') <= ('z' - 'a')) continue; if ((uint8_t)(label[i] - 'A') > ('Z' - 'A')) break; while (j < i) { tmp[j] = label[j]; j++; } tmp[j++] = label[i] | 0x20; } - if ((unsigned int)(i - 2) >= (10 - 2)) return lenof(command); + if ((unsigned int)(i - 2) >= (sizeof tmp - 2)) return lenof(command); if (j != 0) { while (j <= i) { tmp[j] = label[j]; j++; } label = tmp; @@ -539,17 +552,41 @@ ssize_t len; size_t sum, max; int prm; - bool warn; + Error_types error; uint8_t buff[16]; + linepos_t epoint; }; +static void textdump(struct textrecursion_s *trec, uval_t uval) { + switch (trec->prm) { + case CMD_SHIFT: + if ((uval & 0x80) != 0) trec->error = ERROR___NO_HIGH_BIT; + uval &= 0x7f; + break; + case CMD_SHIFTL: + if ((uval & 0x80) != 0) trec->error = ERROR___NO_HIGH_BIT; + uval <<= 1; + break; + case CMD_NULL: + if (uval == 0) trec->error = ERROR_NO_ZERO_VALUE; + /* fall through */ + default: + break; + } + if (trec->len >= (ssize_t)sizeof trec->buff) { + memcpy(pokealloc(trec->len, trec->epoint), trec->buff, trec->len); + trec->len = 0; + } + trec->buff[trec->len++] = uval ^ outputeor; +} + static void textrecursion(struct textrecursion_s *trec, Obj *val) { - Iter *iter; - iter_next_t iter_next; + struct iter_s iter; Obj *val2 = NULL; uval_t uval; if (trec->sum >= trec->max) return; + retry: switch (val->obj->type) { case T_STR: @@ -562,23 +599,36 @@ case CMD_NULL: m = BYTES_MODE_NULL_CHECK; break; default: m = BYTES_MODE_TEXT; break; } - tmp = bytes_from_str((Str *)val, poke_pos, m); - iter = tmp->obj->getiter(tmp); + tmp = bytes_from_str((Str *)val, trec->epoint, m); + textrecursion(trec, tmp); val_destroy(tmp); - break; + return; } case T_ERROR: case T_FLOAT: case T_INT: case T_BOOL: - iter = NULL; + case T_NONE: + iter.data = NULL; val2 = val; goto doit; case T_CODE: - val = ((Code *)val)->addr; + { + Obj *tmp = get_code_value((Code *)val, trec->epoint); + textrecursion(trec, tmp); + val_destroy(tmp); + return; + } + case T_ADDRESS: + if (((Address *)val)->type != A_NONE) { + iter.data = NULL; + val2 = val; + goto doit; + } + val = ((Address *)val)->val; goto retry; case T_GAP: - iter = NULL; + iter.data = NULL; goto dogap; case T_BITS: { @@ -586,36 +636,25 @@ size_t bits = ((Bits *)val)->bits; if (bits == 0) return; if (bits <= 8) { - iter = NULL; + iter.data = NULL; val2 = val; goto doit; } - tmp = BYTES_OBJ->create(val, poke_pos); - iter = tmp->obj->getiter(tmp); + tmp = bytes_from_bits((Bits *)val, trec->epoint); + textrecursion(trec, tmp); val_destroy(tmp); - break; + return; } - case T_NONE: - trec->warn = true; - return; case T_BYTES: - { - ssize_t len = ((Bytes *)val)->len; - if (len < 0) len = ~len; - if (len == 0) return; - if (len == 1) { - iter = NULL; - val2 = val; - goto doit; - } - } - /* fall through */ + iter.data = NULL; + val2 = val; + goto dobytes; default: - iter = val->obj->getiter(val); + iter.data = val; val->obj->getiter(&iter); } - iter_next = iter->next; - while ((val2 = iter_next(iter)) != NULL) { + while ((val2 = iter.next(&iter)) != NULL) { + if (val2->obj->iterable) goto rec; switch (val2->obj->type) { case T_BITS: { @@ -624,105 +663,101 @@ if (bits <= 8) goto doit; } /* fall through */ - case T_LIST: - case T_TUPLE: case T_STR: + case T_CODE: + case T_ADDRESS: rec: textrecursion(trec, val2); break; case T_GAP: dogap: if (trec->len > 0) { - memcpy(pokealloc(trec->len), trec->buff, trec->len); + memcpy(pokealloc(trec->len, trec->epoint), trec->buff, trec->len); trec->len = 0; } trec->len--; trec->sum++; - if (iter == NULL) return; + if (iter.data == NULL) return; break; case T_BYTES: + dobytes: { - ssize_t len = ((Bytes *)val2)->len; - if (len < 0) len = ~len; - if (len == 0) break; - if (len > 1) goto rec; + Bytes *bytes = (Bytes *)val2; + ssize_t len = bytes->len; + if (len != 0) { + size_t i, len2, len3; + int inv; + if (len < 0) { + inv = ~0; + len2 = (size_t)~len; + } else { + inv = 0; + len2 = (size_t)len; + } + len3 = trec->max - trec->sum; + if (len2 > len3) len2 = len3; + trec->sum += len2; + if (trec->len < 0) { memskip(-trec->len, trec->epoint); trec->len = 0; } + for (i = 0; i < len2; i++) { + textdump(trec, bytes->data[i] ^ inv); + } + } } - /* fall through */ + if (iter.data == NULL) return; + break; default: doit: - if (touval(val2, &uval, 8, poke_pos)) uval = 256 + '?'; - switch (trec->prm) { - case CMD_SHIFT: - if ((uval & 0x80) != 0) err_msg2(ERROR___NO_HIGH_BIT, NULL, poke_pos); - uval &= 0x7f; - break; - case CMD_SHIFTL: - if ((uval & 0x80) != 0) err_msg2(ERROR___NO_HIGH_BIT, NULL, poke_pos); - uval <<= 1; - break; - case CMD_NULL: - if (uval == 0) err_msg2(ERROR_NO_ZERO_VALUE, NULL, poke_pos); - /* fall through */ - default: - break; - } - if (trec->len < 0) { memskip(-trec->len); trec->len = 0; } - else if (trec->len >= (ssize_t)sizeof trec->buff) { - memcpy(pokealloc(trec->len), trec->buff, trec->len); - trec->len = 0; - } - trec->buff[trec->len++] = uval ^ outputeor; + if (touval(val2, &uval, 8, trec->epoint)) uval = 256 + '?'; trec->sum++; - if (iter == NULL) return; + if (trec->len < 0) { memskip(-trec->len, trec->epoint); trec->len = 0; } + textdump(trec, uval); + if (iter.data == NULL) return; break; - case T_NONE: - trec->warn = true; } if (trec->sum >= trec->max) break; } - val_destroy(&iter->v); + iter_destroy(&iter); } struct byterecursion_s { ssize_t len; uint8_t buff[16]; bool warn; + linepos_t epoint; }; static void byterecursion(Obj *val, int prm, struct byterecursion_s *brec, int bits) { - Iter *iter; - iter_next_t iter_next; + struct iter_s iter; Obj *val2; uint32_t ch2; uval_t uv; ival_t iv; const Type *type = val->obj; - if (type != LIST_OBJ && type != TUPLE_OBJ) { + if (!type->iterable) { if (type == GAP_OBJ) { if (brec->len > 0) { - memcpy(pokealloc(brec->len), brec->buff, brec->len); + memcpy(pokealloc(brec->len, brec->epoint), brec->buff, brec->len); brec->len = 0; } brec->len -= (unsigned int)abs(bits) / 8; return; } - iter = NULL; + iter.data = NULL; if (type == NONE_OBJ) goto donone; val2 = val; goto doit; } - iter = type->getiter(val); - iter_next = iter->next; - while ((val2 = iter_next(iter)) != NULL) { - switch (val2->obj->type) { - case T_LIST: - case T_TUPLE: + iter.data = val; type->getiter(&iter); + while ((val2 = iter.next(&iter)) != NULL) { + if (val2->obj->iterable) { byterecursion(val2, prm, brec, bits); continue; + } + switch (val2->obj->type) { case T_GAP: if (brec->len > 0) { - memcpy(pokealloc(brec->len), brec->buff, brec->len); + memcpy(pokealloc(brec->len, brec->epoint), brec->buff, brec->len); brec->len = 0; } brec->len -= (unsigned int)abs(bits) / 8; @@ -730,32 +765,31 @@ default: doit: if (prm == CMD_RTA || prm == CMD_ADDR) { - atype_t am; - Obj *tmp = val2->obj->address(val2, &am); - if (touval(tmp, &uv, (am == A_KR) ? 16 : all_mem_bits, poke_pos)) { + atype_t am = val2->obj->address(val2); + if (touaddress(val2, &uv, (am == A_KR) ? 16 : all_mem_bits, brec->epoint)) { ch2 = 0; break; } uv &= all_mem; switch (am) { case A_NONE: - if ((current_address->l_address.bank ^ uv) > 0xffff) err_msg2(ERROR_CANT_CROSS_BA, tmp, poke_pos); + if ((current_address->l_address.bank ^ uv) > 0xffff) err_msg2(ERROR_CANT_CROSS_BA, val2, brec->epoint); break; case A_KR: break; default: - err_msg_output_and_destroy(err_addressing(am, poke_pos)); + err_msg_output_and_destroy(err_addressing(am, brec->epoint, -1)); } ch2 = (prm == CMD_RTA) ? (uv - 1) : uv; break; } if (bits >= 0) { - if (touval(val2, &uv, (unsigned int)bits, poke_pos)) { + if (touval(val2, &uv, (unsigned int)bits, brec->epoint)) { if (diagnostics.pitfalls) { static unsigned int once; - if (prm == CMD_BYTE && val2->obj == STR_OBJ) err_msg_byte_note(poke_pos); + if (prm == CMD_BYTE && val2->obj == STR_OBJ) err_msg_byte_note(brec->epoint); else if (prm != CMD_RTA && prm != CMD_ADDR && once != pass) { - Error *err = val2->obj->ival(val2, &iv, (unsigned int)bits, poke_pos); + Error *err = val2->obj->ival(val2, &iv, (unsigned int)bits, brec->epoint); if (err != NULL) val_destroy(&err->v); else { const char *txt; @@ -766,7 +800,7 @@ default: case CMD_WORD: txt = ".sint"; break; } - err_msg_char_note(txt, poke_pos); + err_msg_char_note(txt, brec->epoint); once = pass; } } @@ -775,7 +809,7 @@ } ch2 = uv; } else { - if (toival(val2, &iv, (unsigned int)-bits, poke_pos)) iv = 0; + if (toival(val2, &iv, (unsigned int)-bits, brec->epoint)) iv = 0; ch2 = (uint32_t)iv; } break; @@ -784,8 +818,8 @@ brec->warn = true; ch2 = 0; } - if (brec->len < 0) {memskip(-brec->len);brec->len = 0;} - else if (brec->len >= (ssize_t)(sizeof brec->buff) - 4) {memcpy(pokealloc(brec->len), brec->buff, brec->len); brec->len = 0;} + if (brec->len < 0) {memskip(-brec->len, brec->epoint);brec->len = 0;} + else if (brec->len >= (ssize_t)(sizeof brec->buff) - 4) {memcpy(pokealloc(brec->len, brec->epoint), brec->buff, brec->len); brec->len = 0;} ch2 ^= outputeor; brec->buff[brec->len++] = ch2; if (prm >= CMD_RTA) { @@ -795,26 +829,25 @@ if (prm >= CMD_DINT) brec->buff[brec->len++] = ch2 >> 24; } } - if (iter == NULL) return; + if (iter.data == NULL) return; } - val_destroy(&iter->v); + iter_destroy(&iter); } static bool instrecursion(Obj *o1, int prm, unsigned int w, linepos_t epoint, struct linepos_s *epoints) { - iter_next_t iter_next; - Iter *iter = o1->obj->getiter(o1); + struct iter_s iter; Error *err; bool was = false; - iter_next = iter->next; - while ((o1 = iter_next(iter)) != NULL) { - if (o1->obj == TUPLE_OBJ || o1->obj == LIST_OBJ) { + iter.data = o1; o1->obj->getiter(&iter); + while ((o1 = iter.next(&iter)) != NULL) { + if (o1->obj->iterable) { if (instrecursion(o1, prm, w, epoint, epoints)) was = true; } else { err = instruction(prm, w, o1, epoint, epoints); if (err != NULL) err_msg_output_and_destroy(err); else was = true; } } - val_destroy(&iter->v); + iter_destroy(&iter); return was; } @@ -883,8 +916,7 @@ end = (current_address->address < current_address->end) ? current_address->end : current_address->address; current_address->end = (waitfor->u.cmd_union.addr2 > end) ? waitfor->u.cmd_union.addr2 : end; if (end > current_address->address) { - poke_pos = epoint; - memskip(end - current_address->address); + memskip(end - current_address->address, epoint); } } @@ -908,7 +940,9 @@ case W_ENDM: if (waitfor->u.cmd_macro.val != NULL) val_destroy(waitfor->u.cmd_macro.val); return ".endm"; - case W_ENDF: return ".endf"; + case W_ENDF: + if (waitfor->u.cmd_function.val != NULL) val_destroy(waitfor->u.cmd_function.val); + return ".endf"; case W_NEXT3: pop_context(); /* fall through */ @@ -927,6 +961,12 @@ case W_ENDN: pop_context(); return ".endn"; + case W_ENDWITH2: + pop_context2(); + /* fall through */ + case W_ENDWITH: + if (waitfor->u.cmd_with.label != NULL) {set_size(waitfor->u.cmd_with.label, current_address->address - waitfor->u.cmd_with.addr, current_address->mem, waitfor->u.cmd_with.addr, waitfor->u.cmd_with.membp);val_destroy(&waitfor->u.cmd_with.label->v);} + return ".endwith"; case W_ENDC: return ".endc"; case W_ENDS: if ((waitfor->skip & 1) != 0) current_address->unionmode = waitfor->u.cmd_struct.unionmode; @@ -966,13 +1006,14 @@ new_waitfor(W_SEND, epoint);waitfor->u.cmd_section.section = current_section;waitfor->u.cmd_section.section_address = current_address; opoint = lpoint; - sectionname.data = pline + lpoint.pos; sectionname.len = get_label(); + sectionname.data = pline + lpoint.pos; sectionname.len = get_label(sectionname.data); if (sectionname.len == 0) {err_msg2(ERROR_LABEL_REQUIRE, NULL, &opoint); return true;} + lpoint.pos += sectionname.len; tmp = find_new_section(§ionname); if (tmp->usepass == 0 || tmp->defpass < pass - 1) { size_t ln = tmp->address.mem->mem.p, ln2 = tmp->address.mem->p; - tmp->address.end = tmp->address.start = tmp->restart = tmp->address.address = 0; - tmp->size = tmp->l_restart.address = tmp->l_restart.bank = tmp->address.l_address.address = tmp->address.l_address.bank = 0; + tmp->address.end = tmp->address.start = tmp->restart = tmp->address.address = current_address->address; + tmp->size = 0; tmp->l_restart = tmp->address.l_address = current_address->l_address; if (tmp->usepass != 0 && tmp->usepass >= pass - 1) err_msg_not_defined(§ionname, &opoint); else { if (fixeddig && pass > max_pass) err_msg_cant_calculate(§ionname, epoint); @@ -1026,9 +1067,10 @@ if (!get_exp(0, 0, 1, epoint)) {retval = true;break;} vs = get_val(); if (vs == NULL) break; - if (touval(vs->val->obj->address(vs->val, &am), &uval, all_mem_bits, &vs->epoint)) {retval = true; break;} + if (touaddress(vs->val, &uval, all_mem_bits, &vs->epoint)) {retval = true; break;} + am = vs->val->obj->address(vs->val); if (am != A_NONE && check_addr(am)) { - err_msg_output_and_destroy(err_addressing(am, &vs->epoint)); + err_msg_output_and_destroy(err_addressing(am, &vs->epoint, -1)); retval = true; break; } @@ -1036,7 +1078,7 @@ section_address->address = uval; section_address->l_address.address = uval & 0xffff; section_address->l_address.bank = uval & all_mem & ~(address_t)0xffff; - section_address->l_address_val = val_reference(tmp == NULL ? &int_value[0]->v : (tmp->obj == CODE_OBJ) ? ((Code *)tmp)->addr : tmp); + section_address->l_address_val = get_star_value(0, tmp); } while (false); if (tmp == NULL) { @@ -1068,22 +1110,21 @@ do { { address_t max = (all_mem2 == 0xffffffff && current_section->logicalrecursion == 0) ? all_mem2 : all_mem; - if (touval(val->obj->address(val, &am), &uval, (max == 0xffff) ? 16 : (max == 0xffffff) ? 24 : 32, epoint2)) { + if (touaddress(val, &uval, (max == 0xffff) ? 16 : (max == 0xffffff) ? 24 : 32, epoint2)) { break; } } + am = val->obj->address(val); if (am != A_NONE && check_addr(am)) { - err_msg_output_and_destroy(err_addressing(am, epoint2)); + err_msg_output_and_destroy(err_addressing(am, epoint2, -1)); break; } if (all_mem2 == 0xffffffff && current_section->logicalrecursion == 0) { current_address->l_address.address = uval & 0xffff; current_address->l_address.bank = uval & all_mem & ~(address_t)0xffff; val_destroy(current_address->l_address_val); - if (val->obj == CODE_OBJ) { - current_address->l_address_val = val_reference(((Code *)val)->addr); - val_destroy(val); - } else current_address->l_address_val = val; + current_address->l_address_val = get_star_value(0, val); + val_destroy(val); addr = (address_t)uval & all_mem2; if (current_address->address != addr) { current_address->address = addr; @@ -1106,10 +1147,8 @@ current_address->l_address.address = uval & 0xffff; current_address->l_address.bank = uval & all_mem & ~(address_t)0xffff; val_destroy(current_address->l_address_val); - if (val->obj == CODE_OBJ) { - current_address->l_address_val = val_reference(((Code *)val)->addr); - val_destroy(val); - } else current_address->l_address_val = val; + current_address->l_address_val = get_star_value(0, val); + val_destroy(val); return; } while (false); val_destroy(val); @@ -1164,7 +1203,12 @@ if (val->obj != NAMESPACE_OBJ) { val_destroy(val); *o = val = (Obj *)new_namespace(current_file_list, epoint); - } else ((Namespace *)val)->backr = ((Namespace *)val)->forwr = 0; + } else { + Namespace *names = (Namespace *)val; + names->backr = names->forwr = 0; + names->file_list = current_file_list; + names->epoint = *epoint; + } push_context((Namespace *)val); nf = compile(); pop_context(); @@ -1182,16 +1226,17 @@ if (diagnostics.optimize && newlabel->ref) cpu_opt_invalidate(); oaddr = current_address->address; if (val->obj == CODE_OBJ) { - Obj *tmp = get_star_value(current_address->l_address_val); + Obj *tmp = current_address->l_address_val; code = (Code *)val; - if (!tmp->obj->same(tmp, code->addr)) { - val_destroy(code->addr); code->addr = tmp; + if (!tmp->obj->same(tmp, code->typ)) { + val_destroy(code->typ); code->typ = val_reference(tmp); if (newlabel->usepass >= pass) { if (fixeddig && pass > max_pass) err_msg_cant_calculate(&newlabel->name, &newlabel->epoint); fixeddig = false; } - } else val_destroy(tmp); - if (code->requires != current_section->requires || code->conflicts != current_section->conflicts || code->offs != 0) { + } + if (code->addr != star || code->requires != current_section->requires || code->conflicts != current_section->conflicts || code->offs != 0) { + code->addr = star; code->requires = current_section->requires; code->conflicts = current_section->conflicts; code->offs = 0; @@ -1201,9 +1246,12 @@ } } code->names->backr = code->names->forwr = 0; + code->names->file_list = current_file_list; + code->names->epoint = newlabel->epoint; } else { code = new_code(); - code->addr = get_star_value(current_address->l_address_val); + code->addr = star; + code->typ = val_reference(current_address->l_address_val); code->size = 0; code->offs = 0; code->dtype = D_NONE; @@ -1238,55 +1286,21 @@ return nf; } -static MUST_CHECK bool list_extend(List *lst) { - Obj **vals; - size_t o = lst->len, n; - if (lst->data == lst->u.val) { - n = 16; - vals = (Obj **)malloc(n * sizeof *lst->data); - if (vals == NULL) return true; - memcpy(vals, lst->u.val, o * sizeof *lst->data); - } else { - if (o < 256) n = o * 2; - else { - n = o + 256; - if (/*n < 256 ||*/ n > SIZE_MAX / sizeof *lst->data) return true; /* overflow */ - } - vals = (Obj **)realloc(lst->data, n * sizeof *lst->data); - if (vals == NULL) return true; - } - while (o < n) vals[o++] = (Obj *)ref_none(); - lst->data = vals; - lst->len = n; - lst->u.max = n; +static MUST_CHECK bool list_extend2(List *lst) { + if (list_extend(lst)) return true; + size_t o = lst->len; + Obj **vals = lst->data; + while (o < lst->u.s.max) vals[o++] = (Obj *)ref_none(); + lst->len = o; return false; } -static void list_shrink(List *lst, size_t i) { - size_t j = i; - while (j < lst->len) val_destroy(lst->data[j++]); - lst->len = i; - if (lst->data != lst->u.val) { - if (lst->len <= lenof(lst->u.val)) { - memcpy(lst->u.val, lst->data, lst->len * sizeof *lst->data); - free(lst->data); - lst->data = lst->u.val; - } else { - Obj **v = (Obj **)realloc(lst->data, lst->len * sizeof *lst->data); - if (v != NULL) { - lst->data = v; - lst->u.max = lst->len; - } - } - } -} - static size_t for_command(Label *newlabel, List *lst, linepos_t epoint) { int wht; line_t lin; int nopos = -1; struct linepos_s epoint2, epoint3; - uint8_t *expr; + uint8_t *expr, *expr2; struct { size_t p, len; Label **data; @@ -1298,12 +1312,14 @@ struct avltree *stree_old; line_t ovline, lvline; bool starexists, foreach = false; - Iter *iter = NULL; + struct iter_s iter; size_t i = 0; labels.p = 0; + iter.data = NULL; if (diagnostics.optimize) cpu_opt_invalidate(); - listing_line(listing, epoint->pos); + if (lst != NULL) listing_equal2(listing, &lst->v, epoint->pos); + else listing_line(listing, epoint->pos); new_waitfor(W_NEXT, epoint);waitfor->skip = 0; do { /* label */ @@ -1311,9 +1327,9 @@ str_t varname; epoint2 = lpoint; - varname.data = pline + lpoint.pos; varname.len = get_label(); + varname.data = pline + lpoint.pos; varname.len = get_label(varname.data); if (varname.len == 0) break; - + lpoint.pos += varname.len; if (varname.len > 1 && varname.data[0] == '_' && varname.data[1] == '_') {err_msg2(ERROR_RESERVED_LABL, &varname, &epoint2); goto error;} ignore(); wht = here(); if (wht == ',') { @@ -1324,11 +1340,11 @@ if (wht != '=' || foreach) { if (wht == ':' && pline[lpoint.pos + 1] == '=' && !arguments.tasmcomp && !foreach) lpoint.pos += 2; else { - size_t l = get_label(); - if (l != 2 || (pline[lpoint.pos-2] | arguments.caseinsensitive) != 'i' || (pline[lpoint.pos-1] | arguments.caseinsensitive) != 'n') { - lpoint.pos -= l; + if ((pline[lpoint.pos] | arguments.caseinsensitive) != 'i' || (pline[lpoint.pos+1] | arguments.caseinsensitive) != 'n' || get_label(pline + lpoint.pos) != 2) { err_msg(ERROR______EXPECTED, foreach ? "',' or 'in'" : "':=' or ',' or 'in'"); goto error; - } else foreach = true; + } + lpoint.pos += 2; + foreach = true; } } else lpoint.pos++; if (foreach) { @@ -1345,7 +1361,7 @@ err_msg_output((Error *)val); } } else { - iter = val->obj->getiter(val); + iter.data = val; val->obj->getiter(&iter); } val_destroy(val); val = (Obj *)ref_none(); } else { @@ -1419,31 +1435,30 @@ if (foreach) { new_waitfor(W_NEXT2, epoint); waitfor->u.cmd_rept.breakout = false; - if (iter != NULL) { - iter_next_t iter_next = iter->next; + if (iter.data != NULL) { Obj *val2; - while ((val2 = iter_next(iter)) != NULL) { + while ((val2 = iter.next(&iter)) != NULL) { if (nopos < 0) nopos = 0; else if ((waitfor->skip & 1) != 0) listing_line_cut(listing, waitfor->epoint.pos); if (labels.p == 1) { val_destroy(label->value); label->value = val_reference(val2); } else { - Iter *iter2 = val2->obj->getiter(val2); - iter_next_t iter2_next = iter2->next; + struct iter_s iter2; size_t j; - for (j = 0; j < labels.p && (val2 = iter2_next(iter2)) != NULL; j++) { + iter2.data = val2; val2->obj->getiter(&iter2); + for (j = 0; j < labels.p && (val2 = iter2.next(&iter2)) != NULL; j++) { val_destroy(labels.data[j]->value); labels.data[j]->value = val_reference(val2); } - j += iter2->len(iter2); - if (j != labels.p) err_msg_cant_unpack(labels.p, j, epoint); + if (iter2.len != labels.p) err_msg_cant_unpack(labels.p, iter2.len, epoint); + iter_destroy(&iter2); } lpoint.line = lin; waitfor->skip = 1; lvline = vline; if (lst != NULL) { - if (i >= lst->len && list_extend(lst)) {i = lst->len - 1; err_msg2(ERROR_OUT_OF_MEMORY, NULL, epoint); nf = NULL;} + if (i >= lst->len && list_extend2(lst)) {i = lst->len - 1; err_msg2(ERROR_OUT_OF_MEMORY, NULL, epoint); nf = NULL;} else if (newlabel == NULL) nf = tuple_scope_light(&lst->data[i], epoint); else nf = tuple_scope(newlabel, &lst->data[i]); i++; @@ -1452,23 +1467,27 @@ break; } } - val_destroy(&iter->v); + iter_destroy(&iter); } if (labels.p != 0 && labels.data != labels.val) free(labels.data); - expr = NULL; + expr = expr2 = NULL; } else { struct linepos_s apoint = lpoint, bpoint = {0, 0}; line_t xlin = lpoint.line; struct oper_s tmp; - const uint8_t *oldpline = pline; - size_t lentmp = strlen((const char *)pline) + 1; - expr = (uint8_t *)mallocx(lentmp); - memcpy(expr, pline, lentmp); label = NULL; + const uint8_t *oldpline = pline, *oldpline2 = pline; + expr2 = (uint8_t *)oldpline2; + if ((size_t)(pline - current_file_list->file->data) >= current_file_list->file->len) { + size_t lentmp = strlen((const char *)pline) + 1; + expr = (uint8_t *)mallocx(lentmp); + memcpy(expr, pline, lentmp); + pline = expr; + } else expr = (uint8_t *)oldpline; + label = NULL; new_waitfor(W_NEXT2, epoint); waitfor->u.cmd_rept.breakout = false; tmp.op = NULL; for (;;) { - lpoint = apoint; if (here() != ',' && here() != 0) { struct values_s *vs; bool truth; @@ -1480,6 +1499,13 @@ if (nopos < 0) { ignore();if (here() != ',') {err_msg(ERROR______EXPECTED, "','"); break;} lpoint.pos++;ignore(); + oldpline2 = pline; + if (pline != expr && (size_t)(pline - current_file_list->file->data) >= current_file_list->file->len) { + size_t lentmp = strlen((const char *)pline) + 1; + expr2 = (uint8_t *)mallocx(lentmp); + memcpy(expr2, pline, lentmp); + pline = expr2; + } else expr2 = (uint8_t *)oldpline2; if (here() == 0 || here() == ';') {bpoint.pos = 0; nopos = 0;} else bpoint = lpoint; } else { @@ -1487,22 +1513,22 @@ } waitfor->skip = 1;lvline = vline; if (lst != NULL) { - if (i >= lst->len && list_extend(lst)) { i = lst->len - 1; err_msg2(ERROR_OUT_OF_MEMORY, NULL, epoint); nf = NULL; } + if (i >= lst->len && list_extend2(lst)) { i = lst->len - 1; err_msg2(ERROR_OUT_OF_MEMORY, NULL, epoint); nf = NULL; } else if (newlabel == NULL) nf = tuple_scope_light(&lst->data[i], epoint); else nf = tuple_scope(newlabel, &lst->data[i]); i++; } else nf = compile(); xlin = lpoint.line; - pline = expr; - lpoint.line = lin; if (nf == NULL || waitfor->u.cmd_rept.breakout) break; + pline = expr2; if (nopos < 0) { str_t varname; Namespace *context; bool labelexists; lpoint = bpoint; - varname.data = pline + lpoint.pos; varname.len = get_label(); + varname.data = pline + lpoint.pos; varname.len = get_label(varname.data); if (varname.len == 0) {err_msg2(ERROR_LABEL_REQUIRE, NULL, &bpoint);break;} + lpoint.pos += varname.len; if (varname.len > 1 && varname.data[0] == '_' && varname.data[1] == '_') {err_msg2(ERROR_RESERVED_LABL, &varname, &bpoint); break;} ignore(); wht = here(); while (wht != 0 && !arguments.tasmcomp) { @@ -1587,8 +1613,12 @@ label->value = val; label->usepass = 0; } + pline = expr; + lpoint = apoint; } pline = oldpline; + if (expr == oldpline) expr = NULL; + if (expr2 == oldpline2) expr2 = NULL; lpoint.line = xlin; } if (nf != NULL) { @@ -1597,6 +1627,7 @@ } close_waitfor(W_NEXT2); free(expr); + free(expr2); if (nf != NULL) close_waitfor(W_NEXT); star_tree = stree_old; vline = ovline + vline - lvline; return i; @@ -1608,7 +1639,8 @@ size_t i = 0; if (diagnostics.optimize) cpu_opt_invalidate(); - listing_line(listing, epoint->pos); + if (lst != NULL) listing_equal2(listing, &lst->v, epoint->pos); + else listing_line(listing, epoint->pos); new_waitfor(W_NEXT, epoint);waitfor->skip = 0; if (!get_exp(0, 1, 1, epoint)) cnt = 0; else { @@ -1634,7 +1666,7 @@ lpoint.line = lin; waitfor->skip = 1; lvline = vline; if (lst != NULL) { - if (i >= lst->len && list_extend(lst)) { i = lst->len - 1; err_msg2(ERROR_OUT_OF_MEMORY, NULL, epoint); nf = NULL; } + if (i >= lst->len && list_extend2(lst)) { i = lst->len - 1; err_msg2(ERROR_OUT_OF_MEMORY, NULL, epoint); nf = NULL; } else if (newlabel == NULL) nf = tuple_scope_light(&lst->data[i], epoint); else nf = tuple_scope(newlabel, &lst->data[i]); i++; @@ -1655,6 +1687,77 @@ return i; } +static size_t while_command(Label *newlabel, List *lst, linepos_t epoint) { + uint8_t *expr; + Obj *nf = NULL; + struct star_s *s; + struct avltree *stree_old; + line_t ovline, lvline; + bool starexists; + size_t i = 0; + struct linepos_s apoint; + line_t xlin; + const uint8_t *oldpline; + + if (diagnostics.optimize) cpu_opt_invalidate(); + if (lst != NULL) listing_equal2(listing, &lst->v, epoint->pos); + else listing_line(listing, epoint->pos); + new_waitfor(W_NEXT, epoint);waitfor->skip = 0; + + s = new_star(vline, &starexists); stree_old = star_tree; ovline = vline; + if (starexists && s->addr != star) { + if (fixeddig && pass > max_pass) err_msg_cant_calculate(NULL, epoint); + fixeddig = false; + } + s->addr = star; + star_tree = &s->tree; lvline = vline = 0; + + apoint = lpoint; + xlin = lpoint.line; + oldpline = pline; + if ((size_t)(pline - current_file_list->file->data) >= current_file_list->file->len) { + size_t lentmp = strlen((const char *)pline) + 1; + expr = (uint8_t *)mallocx(lentmp); + memcpy(expr, pline, lentmp); + pline = expr; + } else expr = (uint8_t *)oldpline; + new_waitfor(W_NEXT2, epoint); + waitfor->u.cmd_rept.breakout = false; + for (;;) { + struct values_s *vs; + bool truth; + if (!get_exp(1, 1, 1, &apoint)) break; + vs = get_val(); + if (tobool(vs, &truth)) break; + if (!truth) break; + if ((waitfor->skip & 1) != 0) listing_line_cut(listing, waitfor->epoint.pos); + waitfor->skip = 1;lvline = vline; + if (lst != NULL) { + if (i >= lst->len && list_extend2(lst)) { i = lst->len - 1; err_msg2(ERROR_OUT_OF_MEMORY, NULL, epoint); nf = NULL; } + else if (newlabel == NULL) nf = tuple_scope_light(&lst->data[i], epoint); + else nf = tuple_scope(newlabel, &lst->data[i]); + i++; + } else nf = compile(); + xlin = lpoint.line; + if (nf == NULL || waitfor->u.cmd_rept.breakout) break; + pline = expr; + lpoint = apoint; + } + pline = oldpline; + if (expr == oldpline) expr = NULL; + lpoint.line = xlin; + + if (nf != NULL) { + if ((waitfor->skip & 1) != 0) listing_line(listing, waitfor->epoint.pos); + else listing_line_cut2(listing, waitfor->epoint.pos); + } + close_waitfor(W_NEXT2); + free(expr); + if (nf != NULL) close_waitfor(W_NEXT); + star_tree = stree_old; vline = ovline + vline - lvline; + return i; +} + MUST_CHECK Obj *compile(void) { int wht; @@ -1672,9 +1775,8 @@ bool nobreak = true; str_t labelname; struct anonident_s { - uint8_t dir; - uint8_t padding[3]; - int32_t count; + uint8_t dir, pad; + uint8_t count[sizeof(uint32_t)]; } anonident; struct { uint8_t type; @@ -1708,1034 +1810,1131 @@ } star = (current_address->l_address.address & 0xffff) | current_address->l_address.bank; wht = here(); - switch (wht) { - case '*': - lpoint.pos++; - switch (here()) { - case ' ': - case '\t': - case ';': - case '=': - case '\0': - labelname.data = (const uint8_t *)"*";labelname.len = 1; - goto hh; - default: - lpoint.pos--; - } - break; - case '-': - case '+': - lpoint.pos++; - switch (here()) { - case ' ': - case '\t': - case ';': - case '\0': - if (sizeof(anonident) != sizeof(anonident.dir) + sizeof(anonident.padding) + sizeof(anonident.count)) memset(&anonident, 0, sizeof anonident); - else memset(anonident.padding, 0, sizeof anonident.padding); - anonident.dir = (uint8_t)wht; - anonident.count = (int32_t)((wht == '-') ? current_context->backr++ : current_context->forwr++); - labelname.data = (const uint8_t *)&anonident;labelname.len = sizeof anonident; - goto hh; - default: - lpoint.pos--; - } - break; - default: - break; - } - labelname.data = pline + lpoint.pos; labelname.len = get_label(); - if (labelname.len != 0) { - struct linepos_s cmdpoint; - bool islabel, error; - islabel = false; error = (waitfor->skip & 1) == 0; - while (here() == '.' && pline[lpoint.pos+1] != '.') { - if (!error) { - if (!islabel) { - if (labelname.data[0] != '_') { - tmp2 = find_label(&labelname, NULL); - if (tmp2 == NULL) {err_msg_not_defined2(&labelname, mycontext, true, &epoint); error = true;} + if (wht >= 'A') { + labelname.data = pline + lpoint.pos; + labelname.len = get_label(labelname.data); + if (labelname.len != 0) { + struct linepos_s cmdpoint; + bool islabel, error; + lpoint.pos += labelname.len; + islabel = false; error = (waitfor->skip & 1) == 0; + while (here() == '.' && pline[lpoint.pos+1] != '.') { + if (!error) { + if (!islabel) { + if (labelname.data[0] != '_') { + tmp2 = find_label(&labelname, NULL); + if (tmp2 == NULL) {err_msg_not_defined2(&labelname, mycontext, true, &epoint); error = true;} + } else { + tmp2 = find_label2(&labelname, cheap_context); + if (tmp2 == NULL) {err_msg_not_defined2(&labelname, cheap_context, false, &epoint); error = true;} + } } else { - tmp2 = find_label2(&labelname, cheap_context); - if (tmp2 == NULL) {err_msg_not_defined2(&labelname, cheap_context, false, &epoint); error = true;} + tmp2 = find_label2(&labelname, mycontext); + if (tmp2 == NULL) {err_msg_not_defined2(&labelname, mycontext, false, &epoint); error = true;} + } + if (tmp2 != NULL) { + if (diagnostics.case_symbol && str_cmp(&labelname, &tmp2->name) != 0) err_msg_symbol_case(&labelname, tmp2, &epoint); + tmp2->usepass = pass; /* touch_label(tmp2) */ } - } else { - tmp2 = find_label2(&labelname, mycontext); - if (tmp2 == NULL) {err_msg_not_defined2(&labelname, mycontext, false, &epoint); error = true;} } - if (tmp2 != NULL) { - if (diagnostics.case_symbol && str_cmp(&labelname, &tmp2->name) != 0) err_msg_symbol_case(&labelname, tmp2, &epoint); - tmp2->usepass = pass; /* touch_label(tmp2) */ + lpoint.pos++; islabel = true; epoint = lpoint; + labelname.data = pline + lpoint.pos; labelname.len = get_label(labelname.data); + if (labelname.len == 0) { + if (!error) err_msg2(ERROR______EXPECTED, "a symbol is", &lpoint); + goto breakerr; + } + lpoint.pos += labelname.len; + if (!error) { + Namespace *context = get_namespace(tmp2->value); + if (context == NULL) { + epoint.pos--; + if (tmp2->value == &none_value->v) err_msg_still_none(NULL, &epoint); + else if (tmp2->value->obj == ERROR_OBJ) err_msg_output((Error *)tmp2->value); + else { + Ident *idn = new_ident(&labelname); + err_msg_invalid_oper(&o_MEMBER, tmp2->value, &idn->v, &epoint); + val_destroy(&idn->v); + } + error = true; + } else mycontext = context; } } - lpoint.pos++; islabel = true; epoint = lpoint; - labelname.data = pline + lpoint.pos; labelname.len = get_label(); - if (labelname.len == 0) { - if (!error) err_msg2(ERROR______EXPECTED, "a symbol is", &lpoint); - goto breakerr; + if (!islabel && labelname.data[0] == '_') { + mycontext = cheap_context; } - if (!error) { - Namespace *context = get_namespace(tmp2->value); - if (context == NULL) { - Ident *idn = new_ident(&labelname); - epoint.pos--; - err_msg_invalid_oper(&o_MEMBER, tmp2->value, &idn->v, &epoint); - val_destroy(&idn->v); - error = true; - } else mycontext = context; + if (here() == ':' && pline[lpoint.pos + 1] != '=') {islabel = true; lpoint.pos++;} + if (!islabel && labelname.len == 3 && (prm = lookup_opcode(labelname.data)) >=0) { + if (!error) goto as_opcode; else continue; } - } - if (!islabel && labelname.data[0] == '_') { - mycontext = cheap_context; - } - if (here() == ':' && pline[lpoint.pos + 1] != '=') {islabel = true; lpoint.pos++;} - if (!islabel && labelname.len == 3 && (prm = lookup_opcode(labelname.data)) >=0) { - if (!error) goto as_opcode; else continue; - } - if (false) { - hh: islabel = true; error = (waitfor->skip & 1) == 0; - } - ignore();wht = here(); - if (error) {epoint = lpoint; goto jn;} /* skip things if needed */ - if (labelname.len > 1 && labelname.data[0] == '_' && labelname.data[1] == '_') {err_msg2(ERROR_RESERVED_LABL, &labelname, &epoint); goto breakerr;} - while (wht != 0 && !arguments.tasmcomp) { - bool minmax; - Label *label; - struct oper_s tmp; - Obj *result2, *val2; - struct linepos_s epoint2, epoint3; - int wht2 = pline[lpoint.pos + 1]; + if (false) { + hh: islabel = true; error = (waitfor->skip & 1) == 0; + } + ignore();wht = here(); + if (error) {epoint = lpoint; goto jn;} /* skip things if needed */ + if (labelname.len > 1 && labelname.data[0] == '_' && labelname.data[1] == '_') {err_msg2(ERROR_RESERVED_LABL, &labelname, &epoint); goto breakerr;} + while (wht != 0 && !arguments.tasmcomp) { + bool minmax; + Label *label; + struct oper_s tmp; + Obj *result2, *val2; + struct linepos_s epoint2, epoint3; + int wht2 = pline[lpoint.pos + 1]; - if (wht2 == '=') { - if (wht == ':') { - if (labelname.data[0] == '*') { - lpoint.pos++; - goto starassign; + if (wht2 == '=') { + if (wht == ':') { + if (labelname.data[0] == '*') { + lpoint.pos++; + goto starassign; + } + lpoint.pos += 2; + ignore(); + goto itsvar; } + tmp.op = oper_from_token(wht); + if (tmp.op == NULL) break; + epoint3 = lpoint; lpoint.pos += 2; - ignore(); - goto itsvar; - } - tmp.op = oper_from_token(wht); - if (tmp.op == NULL) break; - epoint3 = lpoint; - lpoint.pos += 2; - } else if (wht2 != 0 && pline[lpoint.pos + 2] == '=') { - tmp.op = oper_from_token2(wht, wht2); - if (tmp.op == NULL) break; - epoint3 = lpoint; - lpoint.pos += 3; - } else break; + } else if (wht2 != 0 && pline[lpoint.pos + 2] == '=') { + tmp.op = oper_from_token2(wht, wht2); + if (tmp.op == NULL) break; + epoint3 = lpoint; + lpoint.pos += 3; + } else break; - if (labelname.data[0] == '-') {current_context->backr--;((struct anonident_s *)labelname.data)->count--;} - else if (labelname.data[0] == '+') {current_context->forwr--;((struct anonident_s *)labelname.data)->count--;} - ignore(); - epoint2 = lpoint; - if (labelname.data[0] == '*') { - label = NULL; - if (diagnostics.optimize) cpu_opt_invalidate(); - val = get_star_value(current_address->l_address_val); - } else if (tmp.op == &o_COND) { - label = NULL; val = NULL; - } else { - label = find_label3(&labelname, mycontext, strength); - if (label == NULL) { - if (tmp.op == &o_MUL) { - if (diagnostics.star_assign) { - err_msg_star_assign(&epoint3); - if (pline[lpoint.pos] == '*') err_msg_compound_note(&epoint3); - } - lpoint.pos = epoint3.pos; - wht = '*'; - break; + if (labelname.data == (const uint8_t *)&anonident) { + uint32_t count = (uint32_t)((anonident.dir == '-') ? --current_context->backr : --current_context->forwr); + count--; + labelname.len = 2; + while (count != 0) { + anonident.count[labelname.len - 2] = count; + labelname.len++; + count >>= 8; } - err_msg_not_defined2(&labelname, mycontext, false, &epoint); - goto breakerr; } - if (label->constant) { - if (tmp.op == &o_MUL) { - if (diagnostics.star_assign) { - err_msg_star_assign(&epoint3); - if (pline[lpoint.pos] == '*') err_msg_compound_note(&epoint3); + ignore(); + epoint2 = lpoint; + if (labelname.data[0] == '*') { + label = NULL; + if (diagnostics.optimize) cpu_opt_invalidate(); + val = get_star(); + } else if (tmp.op == &o_COND) { + label = NULL; val = NULL; + } else { + label = find_label3(&labelname, mycontext, strength); + if (label == NULL) { + if (tmp.op == &o_MUL) { + if (diagnostics.star_assign) { + err_msg_star_assign(&epoint3); + if (pline[lpoint.pos] == '*') err_msg_compound_note(&epoint3); + } + lpoint.pos = epoint3.pos; + wht = '*'; + break; } - lpoint.pos = epoint3.pos; - wht = '*'; - break; + err_msg_not_defined2(&labelname, mycontext, false, &epoint); + goto breakerr; } - err_msg_not_variable(label, &labelname, &epoint); goto breakerr; - goto breakerr; - } - if (diagnostics.case_symbol && str_cmp(&labelname, &label->name) != 0) err_msg_symbol_case(&labelname, label, &epoint); - val = label->value; - label->usepass = 0; - } - if (here() == 0 || here() == ';') val2 = (Obj *)ref_addrlist(null_addrlist); - else { - struct linepos_s epoints[3]; - bool oldreferenceit = referenceit; - referenceit &= 1; /* not good... */ - if (!get_exp(0, 0, 0, NULL)) goto breakerr; - val2 = get_vals_addrlist(epoints); - referenceit = oldreferenceit; - } - oaddr = current_address->address; - if (val == NULL) { - bool labelexists; - label = new_label(&labelname, mycontext, strength, &labelexists, current_file_list); - if (labelexists) { if (label->constant) { + if (tmp.op == &o_MUL) { + if (diagnostics.star_assign) { + err_msg_star_assign(&epoint3); + if (pline[lpoint.pos] == '*') err_msg_compound_note(&epoint3); + } + lpoint.pos = epoint3.pos; + wht = '*'; + break; + } err_msg_not_variable(label, &labelname, &epoint); goto breakerr; - val_destroy(val2); goto breakerr; } - if (label->defpass != pass) { - label->ref = false; - label->defpass = pass; - } else { - val_destroy(val2); - goto finish; - } - label->owner = false; - if (label->file_list != current_file_list) { - label_move(label, &labelname, current_file_list); - } - label->epoint = epoint; - val_destroy(label->value); - label->value = val2; + if (diagnostics.case_symbol && str_cmp(&labelname, &label->name) != 0) err_msg_symbol_case(&labelname, label, &epoint); + val = label->value; label->usepass = 0; - } else { - label->constant = false; - label->owner = false; - label->value = val2; - label->epoint = epoint; } - goto finish; - } - minmax = (tmp.op == &o_MIN) || (tmp.op == &o_MAX); - tmp.v1 = val; - tmp.v2 = val2; - tmp.epoint = &epoint; - tmp.epoint2 = &epoint2; - tmp.epoint3 = &epoint3; - tmp.inplace = (tmp.v1->refcount == 1 && !minmax) ? tmp.v1 : NULL; - result2 = tmp.v1->obj->calc2(&tmp); - if (minmax) { - if (result2 == &true_value->v) val_replace(&result2, val); - else if (result2 == &false_value->v) val_replace(&result2, val2); - } - val_destroy(val2); - if (label != NULL) { - listing_equal(listing, result2); - if (label->file_list != current_file_list) { - label_move(label, &labelname, current_file_list); - } - label->epoint = epoint; - val_destroy(label->value); - label->value = result2; - } else { - val_destroy(val); - starhandle(result2, &epoint, &epoint2); - } - goto finish; - } - switch (wht) { - case '=': - { /* variable */ - struct linepos_s epoints[3]; - Label *label; - bool labelexists; - starassign: - if (labelname.data[0] == '*') { - label = NULL; - if (diagnostics.optimize) cpu_opt_invalidate(); - } else label = find_label3(&labelname, mycontext, strength); - lpoint.pos++; ignore(); - epoints[0] = lpoint; /* for no elements! */ - if (here() == 0 || here() == ';') { - if (labelname.data[0] == '*') { - err_msg(ERROR______EXPECTED, "an expression is"); - goto breakerr; - } - val = (Obj *)ref_addrlist(null_addrlist); - } else { + if (here() == 0 || here() == ';') val2 = (Obj *)ref_addrlist(null_addrlist); + else { + struct linepos_s epoints[3]; bool oldreferenceit = referenceit; - if (label != NULL && !label->ref) { - referenceit = false; - } + referenceit &= 1; /* not good... */ if (!get_exp(0, 0, 0, NULL)) goto breakerr; - val = get_vals_addrlist(epoints); + val2 = get_vals_addrlist(epoints); referenceit = oldreferenceit; } - if (labelname.data[0] == '*') { - starhandle(val, &epoint, &epoints[0]); - goto finish; - } - if (label != NULL) { - labelexists = true; - } else label = new_label(&labelname, mycontext, strength, &labelexists, current_file_list); oaddr = current_address->address; - listing_equal(listing, val); - label->ref = false; - if (labelexists) { - if (label->defpass == pass) { - val_destroy(val); - err_msg_double_defined(label, &labelname, &epoint); - } else { - if (!constcreated && temporary_label_branch == 0 && label->defpass != pass - 1) { - if (pass > max_pass) err_msg_cant_calculate(&label->name, &epoint); - constcreated = true; + if (val == NULL) { + bool labelexists; + label = new_label(&labelname, mycontext, strength, &labelexists, current_file_list); + if (labelexists) { + if (label->constant) { + err_msg_not_variable(label, &labelname, &epoint); goto breakerr; + val_destroy(val2); + goto breakerr; + } + if (label->defpass != pass) { + label->ref = false; + label->defpass = pass; + } else { + val_destroy(val2); + goto finish; } - label->constant = true; label->owner = false; if (label->file_list != current_file_list) { label_move(label, &labelname, current_file_list); } label->epoint = epoint; - const_assign(label, val); + val_destroy(label->value); + label->value = val2; + label->usepass = 0; + } else { + label->constant = false; + label->owner = false; + label->value = val2; + label->epoint = epoint; } - } else { - if (!constcreated && temporary_label_branch == 0) { - if (pass > max_pass) err_msg_cant_calculate(&label->name, &epoint); - constcreated = true; + goto finish; + } + minmax = (tmp.op == &o_MIN) || (tmp.op == &o_MAX); + tmp.v1 = val; + tmp.v2 = val2; + tmp.epoint = &epoint; + tmp.epoint2 = &epoint2; + tmp.epoint3 = &epoint3; + tmp.inplace = (tmp.v1->refcount == 1 && !minmax) ? tmp.v1 : NULL; + result2 = tmp.v1->obj->calc2(&tmp); + if (minmax) { + if (result2 == &true_value->v) val_replace(&result2, val); + else if (result2 == &false_value->v) val_replace(&result2, val2); + } + val_destroy(val2); + if (label != NULL) { + listing_equal(listing, result2); + if (label->file_list != current_file_list) { + label_move(label, &labelname, current_file_list); } - label->constant = true; - label->owner = false; - label->value = val; label->epoint = epoint; + val_destroy(label->value); + label->value = result2; + } else { + val_destroy(val); + starhandle(result2, &epoint, &epoint2); } goto finish; } - case '.': - cmdpoint = lpoint; - prm = get_command(); - ignore(); - if (labelname.data[0] == '*') { - err_msg2(ERROR_RESERVED_LABL, &labelname, &epoint); - newlabel = NULL; epoint = cmdpoint; goto as_command; - } - switch (prm) { - case CMD_VAR: /* variable */ - { + switch (wht) { + case '=': + { /* variable */ + struct linepos_s epoints[3]; Label *label; bool labelexists; - itsvar: - label = find_label3(&labelname, mycontext, strength); - if (here() == 0 || here() == ';') val = (Obj *)ref_addrlist(null_addrlist); - else { - struct linepos_s epoints[3]; + starassign: + if (labelname.data[0] == '*') { + label = NULL; + if (diagnostics.optimize) cpu_opt_invalidate(); + } else label = find_label3(&labelname, mycontext, strength); + lpoint.pos++; ignore(); + epoints[0] = lpoint; /* for no elements! */ + if (here() == 0 || here() == ';') { + if (labelname.data[0] == '*') { + err_msg(ERROR______EXPECTED, "an expression is"); + goto breakerr; + } + val = (Obj *)ref_addrlist(null_addrlist); + } else { bool oldreferenceit = referenceit; - referenceit &= 1; /* not good... */ + if (label != NULL && !label->ref) { + referenceit = false; + } if (!get_exp(0, 0, 0, NULL)) goto breakerr; val = get_vals_addrlist(epoints); referenceit = oldreferenceit; } + if (labelname.data[0] == '*') { + starhandle(val, &epoint, &epoints[0]); + goto finish; + } if (label != NULL) { labelexists = true; - if (diagnostics.case_symbol && str_cmp(&labelname, &label->name) != 0) err_msg_symbol_case(&labelname, label, &epoint); } else label = new_label(&labelname, mycontext, strength, &labelexists, current_file_list); oaddr = current_address->address; listing_equal(listing, val); if (labelexists) { - if (label->constant) { - err_msg_double_defined(label, &labelname, &epoint); + if (label->defpass == pass) { val_destroy(val); + err_msg_double_defined(label, &labelname, &epoint); } else { - if (label->defpass != pass) { - label->ref = false; - label->defpass = pass; - } else { - if (diagnostics.unused.variable && label->usepass != pass) err_msg_unused_variable(label); + if (label->fwpass == pass) fwcount--; + if (!constcreated && label->defpass != pass - 1) { + if (pass > max_pass) err_msg_cant_calculate(&label->name, &epoint); + constcreated = true; } + label->constant = true; label->owner = false; if (label->file_list != current_file_list) { label_move(label, &labelname, current_file_list); } label->epoint = epoint; - val_destroy(label->value); - label->value = val; - label->usepass = 0; + label->ref = false; + const_assign(label, val); } } else { - label->constant = false; + if (!constcreated) { + if (pass > max_pass) err_msg_cant_calculate(&label->name, &epoint); + constcreated = true; + } + label->constant = true; label->owner = false; label->value = val; label->epoint = epoint; + label->ref = false; } goto finish; } - case CMD_LBL: - { /* label */ - Label *label; - Lbl *lbl; - bool labelexists; - listing_line(listing, 0); - label = new_label(&labelname, mycontext, strength, &labelexists, current_file_list); - lbl = (Lbl *)val_alloc(LBL_OBJ); - lbl->sline = epoint.line; - lbl->waitforp = waitfor_p; - lbl->file_list = current_file_list; - lbl->parent = current_context; - if (labelexists) { - if (label->defpass == pass) { - val_destroy(&lbl->v); - err_msg_double_defined(label, &labelname, &epoint); + case '.': + cmdpoint = lpoint; + prm = get_command(); + ignore(); + if (labelname.data[0] == '*') { + err_msg2(ERROR_RESERVED_LABL, &labelname, &epoint); + newlabel = NULL; epoint = cmdpoint; goto as_command; + } + switch (prm) { + case CMD_VAR: /* variable */ + { + Label *label; + bool labelexists; + itsvar: + label = find_label3(&labelname, mycontext, strength); + if (here() == 0 || here() == ';') val = (Obj *)ref_addrlist(null_addrlist); + else { + struct linepos_s epoints[3]; + bool oldreferenceit = referenceit; + referenceit &= 1; /* not good... */ + if (!get_exp(0, 0, 0, NULL)) goto breakerr; + val = get_vals_addrlist(epoints); + referenceit = oldreferenceit; + } + if (label != NULL) { + labelexists = true; + if (diagnostics.case_symbol && str_cmp(&labelname, &label->name) != 0) err_msg_symbol_case(&labelname, label, &epoint); + } else label = new_label(&labelname, mycontext, strength, &labelexists, current_file_list); + oaddr = current_address->address; + listing_equal(listing, val); + if (labelexists) { + if (label->constant) { + err_msg_double_defined(label, &labelname, &epoint); + val_destroy(val); + } else { + if (label->defpass != pass) { + label->ref = false; + label->defpass = pass; + } else { + if (diagnostics.unused.variable && label->usepass != pass) err_msg_unused_variable(label); + } + label->owner = false; + if (label->file_list != current_file_list) { + label_move(label, &labelname, current_file_list); + } + label->epoint = epoint; + val_destroy(label->value); + label->value = val; + label->usepass = 0; + } + } else { + label->constant = false; + label->owner = false; + label->value = val; + label->epoint = epoint; + } + goto finish; + } + case CMD_LBL: + { /* label */ + Label *label; + Lbl *lbl; + bool labelexists; + listing_line(listing, 0); + label = new_label(&labelname, mycontext, strength, &labelexists, current_file_list); + lbl = (Lbl *)val_alloc(LBL_OBJ); + lbl->sline = epoint.line; + lbl->waitforp = waitfor_p; + lbl->file_list = current_file_list; + lbl->parent = current_context; + if (labelexists) { + if (label->defpass == pass) { + val_destroy(&lbl->v); + err_msg_double_defined(label, &labelname, &epoint); + } else { + if (label->fwpass == pass) fwcount--; + if (!constcreated && label->defpass != pass - 1) { + if (pass > max_pass) err_msg_cant_calculate(&label->name, &epoint); + constcreated = true; + } + label->constant = true; + label->owner = true; + if (label->file_list != current_file_list) { + label_move(label, &labelname, current_file_list); + } + label->epoint = epoint; + label->ref = false; + const_assign(label, &lbl->v); + } } else { - if (!constcreated && temporary_label_branch == 0 && label->defpass != pass - 1) { + if (!constcreated) { if (pass > max_pass) err_msg_cant_calculate(&label->name, &epoint); constcreated = true; } label->constant = true; label->owner = true; - if (label->file_list != current_file_list) { - label_move(label, &labelname, current_file_list); - } + label->value = &lbl->v; label->epoint = epoint; - const_assign(label, &lbl->v); + label->ref = false; } - } else { - if (!constcreated && temporary_label_branch == 0) { - if (pass > max_pass) err_msg_cant_calculate(&label->name, &epoint); - constcreated = true; - } - label->constant = true; - label->owner = true; - label->value = &lbl->v; - label->epoint = epoint; + if (!arguments.tasmcomp && diagnostics.deprecated) err_msg2(ERROR______OLD_GOTO, NULL, &cmdpoint); + goto finish; } - if (!arguments.tasmcomp && diagnostics.deprecated) err_msg2(ERROR______OLD_GOTO, NULL, &cmdpoint); - label->ref = false; - goto finish; - } - case CMD_NAMESPACE: - { /* namespace */ - Label *label; - struct values_s *vs; - bool labelexists; - listing_line(listing, 0); - new_waitfor(W_ENDN, &cmdpoint); - if (get_exp(0, 0, 1, &cmdpoint)) { - vs = get_val(); - if (vs != NULL) { - val = vs->val; - val = (Obj *)get_namespace(val); - if (val == NULL) err_msg_wrong_type2(vs->val, NULL, &vs->epoint); - } else val = NULL; - } else val = NULL; - label = new_label(&labelname, mycontext, strength, &labelexists, current_file_list); - if (labelexists) { - if (label->defpass == pass) err_msg_double_defined(label, &labelname, &epoint); - else { - if (!constcreated && temporary_label_branch == 0 && label->defpass != pass - 1) { + case CMD_NAMESPACE: + { /* namespace */ + bool labelexists; + Label *label = new_label(&labelname, mycontext, strength, &labelexists, current_file_list); + if (labelexists) { + if (label->defpass == pass) { + err_msg_double_defined(label, &labelname, &epoint); + epoint = cmdpoint; + goto as_command; + } + if (label->fwpass == pass) fwcount--; + if (!constcreated && label->defpass != pass - 1) { if (pass > max_pass) err_msg_cant_calculate(&label->name, &epoint); constcreated = true; } - label->constant = true; - label->owner = (val == NULL); if (label->file_list != current_file_list) { label_move(label, &labelname, current_file_list); } - label->epoint = epoint; + } else { + if (!constcreated) { + if (pass > max_pass) err_msg_cant_calculate(&label->name, &epoint); + constcreated = true; + } + label->owner = true; + label->value = &none_value->v; + } + label->constant = true; + label->epoint = epoint; + label->ref = false; + listing_line(listing, 0); + new_waitfor(W_ENDN, &cmdpoint); + if (get_exp(0, 0, 1, &cmdpoint)) { + struct values_s *vs = get_val(); + if (vs != NULL) { + val = vs->val; + val = (Obj *)get_namespace(val); + if (val == NULL) err_msg_wrong_type2(vs->val, NULL, &vs->epoint); + } else val = NULL; + } else val = NULL; + label->owner = (val == NULL); + if (labelexists) { if (val != NULL) const_assign(label, val_reference(val)); else { label->defpass = pass; if (label->value->obj != NAMESPACE_OBJ) { val_destroy(label->value); label->value = (Obj *)new_namespace(current_file_list, &epoint); - } else ((Namespace *)label->value)->backr = ((Namespace *)label->value)->forwr = 0; + } else { + Namespace *names = (Namespace *)label->value; + names->backr = names->forwr = 0; + names->file_list = current_file_list; + names->epoint = epoint; + } } + } else { + label->value = (val != NULL) ? val_reference(val) : (Obj *)new_namespace(current_file_list, &epoint); } - } else { - if (!constcreated && temporary_label_branch == 0) { - if (pass > max_pass) err_msg_cant_calculate(&label->name, &epoint); - constcreated = true; - } - label->constant = true; - label->owner = (val == NULL); - label->value = (val != NULL) ? val_reference(val) : (Obj *)new_namespace(current_file_list, &epoint); - label->epoint = epoint; + if (label->value->obj == NAMESPACE_OBJ) { + push_context((Namespace *)label->value); + waitfor->what = W_ENDN2; + } else push_context(current_context); + goto finish; } - if (label->value->obj == NAMESPACE_OBJ) { - push_context((Namespace *)label->value); - waitfor->what = W_ENDN2; - } else push_context(current_context); - label->ref = false; - goto finish; - } - case CMD_MACRO:/* .macro */ - case CMD_SEGMENT: - { - Label *label; - Macro *macro; - Type *obj = (prm == CMD_MACRO) ? MACRO_OBJ : SEGMENT_OBJ; - bool labelexists; - listing_line(listing, 0); - new_waitfor(W_ENDM, &cmdpoint);waitfor->skip = 0; - label = new_label(&labelname, mycontext, strength, &labelexists, current_file_list); - macro = (Macro *)val_alloc(obj); - macro->file_list = current_file_list; - macro->line = epoint.line; - macro->recursion_pass = 0; - get_macro_params(¯o->v); - if (labelexists) { - macro->retval = (label->value->obj == obj) && ((Macro *)label->value)->retval; - if (label->defpass == pass) { - waitfor->u.cmd_macro.val = ¯o->v; - err_msg_double_defined(label, &labelname, &epoint); + case CMD_MACRO:/* .macro */ + case CMD_SEGMENT: + { + Label *label; + Macro *macro; + Type *obj = (prm == CMD_MACRO) ? MACRO_OBJ : SEGMENT_OBJ; + bool labelexists; + listing_line(listing, 0); + new_waitfor(W_ENDM, &cmdpoint);waitfor->skip = 0; + label = new_label(&labelname, mycontext, strength, &labelexists, current_file_list); + macro = (Macro *)val_alloc(obj); + macro->file_list = current_file_list; + macro->line = epoint.line; + macro->recursion_pass = 0; + get_macro_params(¯o->v); + if (labelexists) { + macro->retval = (label->value->obj == obj) && ((Macro *)label->value)->retval; + if (label->defpass == pass) { + waitfor->u.cmd_macro.val = ¯o->v; + err_msg_double_defined(label, &labelname, &epoint); + } else { + if (label->fwpass == pass) fwcount--; + if (!constcreated && label->defpass != pass - 1) { + if (pass > max_pass) err_msg_cant_calculate(&label->name, &epoint); + constcreated = true; + } + label->constant = true; + label->owner = true; + if (label->file_list != current_file_list) { + label_move(label, &labelname, current_file_list); + } + label->epoint = epoint; + label->ref = false; + const_assign(label, ¯o->v); + waitfor->u.cmd_macro.val = val_reference(label->value); + } } else { - if (!constcreated && temporary_label_branch == 0 && label->defpass != pass - 1) { + macro->retval = false; + if (!constcreated == 0) { if (pass > max_pass) err_msg_cant_calculate(&label->name, &epoint); constcreated = true; } label->constant = true; label->owner = true; - if (label->file_list != current_file_list) { - label_move(label, &labelname, current_file_list); - } + label->value = ¯o->v; label->epoint = epoint; - const_assign(label, ¯o->v); - waitfor->u.cmd_macro.val = val_reference(label->value); - } - } else { - macro->retval = false; - if (!constcreated && temporary_label_branch == 0) { - if (pass > max_pass) err_msg_cant_calculate(&label->name, &epoint); - constcreated = true; + label->ref = false; + waitfor->u.cmd_macro.val = val_reference(¯o->v); } - label->constant = true; - label->owner = true; - label->value = ¯o->v; - label->epoint = epoint; - waitfor->u.cmd_macro.val = val_reference(¯o->v); + goto finish; } - label->ref = false; - goto finish; - } - case CMD_FUNCTION: - { - Label *label; - Mfunc *mfunc; - bool labelexists; - listing_line(listing, 0); - new_waitfor(W_ENDF, &cmdpoint);waitfor->skip = 0; - if (temporary_label_branch != 0) {err_msg2(ERROR___NOT_ALLOWED, ".function", &cmdpoint);goto breakerr;} - label = new_label(&labelname, mycontext, strength, &labelexists, current_file_list); - mfunc = (Mfunc *)val_alloc(MFUNC_OBJ); - mfunc->file_list = current_file_list; - mfunc->line = epoint.line; - mfunc->recursion_pass = 0; - mfunc->argc = 0; - mfunc->param = NULL; /* might be recursive through init */ - mfunc->nslen = 0; - mfunc->namespaces = NULL; - if (labelexists) { - if (label->defpass == pass) { - val_destroy(&mfunc->v); - err_msg_double_defined(label, &labelname, &epoint); + case CMD_FUNCTION: + { + Label *label; + Mfunc *mfunc; + bool labelexists; + listing_line(listing, 0); + new_waitfor(W_ENDF, &cmdpoint);waitfor->skip = 0; + label = new_label(&labelname, mycontext, strength, &labelexists, current_file_list); + mfunc = (Mfunc *)val_alloc(MFUNC_OBJ); + mfunc->file_list = current_file_list; + mfunc->line = epoint.line; + mfunc->recursion_pass = 0; + mfunc->argc = 0; + mfunc->param = NULL; /* might be recursive through init */ + mfunc->nslen = 0; + mfunc->namespaces = NULL; + mfunc->ipoint = 0; + if (labelexists) { + mfunc->retval = (label->value->obj == MFUNC_OBJ) && ((Mfunc *)label->value)->retval; + if (label->defpass == pass) { + waitfor->u.cmd_function.val = &mfunc->v; + mfunc->names = new_namespace(current_file_list, &epoint); + mfunc->inamespaces = ref_tuple(null_tuple); + err_msg_double_defined(label, &labelname, &epoint); + } else { + if (label->fwpass == pass) fwcount--; + if (!constcreated && label->defpass != pass - 1) { + if (pass > max_pass) err_msg_cant_calculate(&label->name, &epoint); + constcreated = true; + } + label->constant = true; + label->owner = true; + if (label->file_list != current_file_list) { + label_move(label, &labelname, current_file_list); + } + if (label->value->obj == MFUNC_OBJ) { + Mfunc *prev = (Mfunc *)label->value; + mfunc->names = ref_namespace(prev->names); + mfunc->names->backr = mfunc->names->forwr = 0; + mfunc->names->file_list = current_file_list; + mfunc->names->epoint = epoint; + mfunc->inamespaces = ref_tuple(prev->inamespaces); + } else { + mfunc->names = new_namespace(current_file_list, &epoint); + mfunc->inamespaces = ref_tuple(null_tuple); + } + label->epoint = epoint; + label->ref = false; + get_func_params(mfunc); + get_namespaces(mfunc); + const_assign(label, &mfunc->v); + if (label->value != &mfunc->v) ((Mfunc *)label->value)->ipoint = 0; + waitfor->u.cmd_function.val = val_reference(label->value); + } } else { - if (!constcreated && temporary_label_branch == 0 && label->defpass != pass - 1) { + mfunc->retval = false; + if (!constcreated) { if (pass > max_pass) err_msg_cant_calculate(&label->name, &epoint); constcreated = true; } label->constant = true; label->owner = true; - if (label->file_list != current_file_list) { - label_move(label, &labelname, current_file_list); - } + label->value = &mfunc->v; label->epoint = epoint; + label->ref = false; get_func_params(mfunc); get_namespaces(mfunc); - const_assign(label, &mfunc->v); - } - } else { - if (!constcreated && temporary_label_branch == 0) { - if (pass > max_pass) err_msg_cant_calculate(&label->name, &epoint); - constcreated = true; + mfunc->names = new_namespace(current_file_list, &epoint); + mfunc->inamespaces = ref_tuple(null_tuple); + waitfor->u.cmd_function.val = val_reference(&mfunc->v); } - label->constant = true; - label->owner = true; - label->value = &mfunc->v; - label->epoint = epoint; - get_func_params(mfunc); - get_namespaces(mfunc); + goto finish; } - label->ref = false; - goto finish; - } - case CMD_STRUCT: - case CMD_UNION: - { - Label *label; - Struct *structure; - struct section_address_s section_address, *oldsection_address = current_address; - uval_t provides = current_section->provides, requires = current_section->requires, conflicts = current_section->conflicts; - bool labelexists, doubledef = false; - Type *obj = (prm == CMD_STRUCT) ? STRUCT_OBJ : UNION_OBJ; + case CMD_STRUCT: + case CMD_UNION: + { + Label *label; + Struct *structure; + struct section_address_s section_address, *oldsection_address = current_address; + uval_t provides = current_section->provides, requires = current_section->requires, conflicts = current_section->conflicts; + bool labelexists, doubledef = false; + Type *obj = (prm == CMD_STRUCT) ? STRUCT_OBJ : UNION_OBJ; - if (diagnostics.optimize) cpu_opt_invalidate(); - new_waitfor((prm==CMD_STRUCT) ? W_ENDS : W_ENDU, &cmdpoint);waitfor->skip = 0; - label = new_label(&labelname, mycontext, strength, &labelexists, current_file_list); + if (diagnostics.optimize) cpu_opt_invalidate(); + new_waitfor((prm==CMD_STRUCT) ? W_ENDS : W_ENDU, &cmdpoint);waitfor->skip = 0; + label = new_label(&labelname, mycontext, strength, &labelexists, current_file_list); - current_section->provides = ~(uval_t)0;current_section->requires = current_section->conflicts = 0; - section_address.wrapwarn = section_address.moved = false; - section_address.unionmode = (prm == CMD_UNION); - section_address.address = section_address.start = section_address.end = 0; - section_address.l_start.address = section_address.l_start.bank = 0; - section_address.l_union.address = section_address.l_union.bank = 0; - section_address.l_address.address = section_address.l_address.bank = 0; - section_address.l_address_val = (Obj *)ref_int(int_value[0]); - section_address.mem = new_memblocks(0, 0); - section_address.mem->lastaddr = 0; - current_address = §ion_address; - - structure = (Struct *)val_alloc(obj); - structure->file_list = current_file_list; - structure->line = epoint.line; - structure->recursion_pass = 0; - get_macro_params(&structure->v); - if (labelexists) { - structure->retval = (label->value->obj == obj) && ((Struct *)label->value)->retval; - if (label->defpass == pass) { - doubledef = true; - structure->size = 0; - structure->names = new_namespace(current_file_list, &epoint); - err_msg_double_defined(label, &labelname, &epoint); - } else { - if (!constcreated && temporary_label_branch == 0 && label->defpass != pass - 1) { - if (pass > max_pass) err_msg_cant_calculate(&label->name, &epoint); - constcreated = true; - } - label->constant = true; - label->owner = true; - if (label->file_list != current_file_list) { - label_move(label, &labelname, current_file_list); - } - label->epoint = epoint; - if (label->value->obj == obj) { - Struct *prev = (Struct *)label->value; - structure->size = prev->size; - structure->names = ref_namespace(prev->names); - structure->names->backr = structure->names->forwr = 0; - } else { + current_section->provides = ~(uval_t)0;current_section->requires = current_section->conflicts = 0; + section_address.wrapwarn = section_address.moved = false; + section_address.unionmode = (prm == CMD_UNION); + section_address.address = section_address.start = section_address.end = 0; + section_address.l_start.address = section_address.l_start.bank = 0; + section_address.l_union.address = section_address.l_union.bank = 0; + section_address.l_address.address = section_address.l_address.bank = 0; + section_address.l_address_val = (Obj *)ref_int(int_value[0]); + section_address.mem = new_memblocks(0, 0); + section_address.mem->lastaddr = 0; + section_address.mem->enumeration = true; + current_address = §ion_address; + + structure = (Struct *)val_alloc(obj); + structure->file_list = current_file_list; + structure->line = epoint.line; + structure->recursion_pass = 0; + get_macro_params(&structure->v); + if (labelexists) { + structure->retval = (label->value->obj == obj) && ((Struct *)label->value)->retval; + if (label->defpass == pass) { + doubledef = true; structure->size = 0; structure->names = new_namespace(current_file_list, &epoint); - } - const_assign(label, &structure->v); - structure = (Struct *)label->value; - } - } else { - structure->retval = false; - if (!constcreated && temporary_label_branch == 0) { - if (pass > max_pass) err_msg_cant_calculate(&label->name, &epoint); - constcreated = true; - } - label->constant = true; - label->owner = true; - label->value = &structure->v; - label->epoint = epoint; - structure->size = 0; - structure->names = new_namespace(current_file_list, &epoint); - } - label->ref = false; - listing_line(listing, cmdpoint.pos); - current_section->structrecursion++; - waitfor->what = (prm == CMD_STRUCT) ? W_ENDS2 : W_ENDU2; - waitfor->skip = 1; - val = macro_recurse(W_ENDS, &structure->v, structure->names, &cmdpoint); - structure->retval = (val != NULL); - if (val != NULL) val_destroy(val); - close_waitfor((prm == CMD_STRUCT) ? W_ENDS2 : W_ENDU2); - current_section->structrecursion--; - - current_section->provides = provides; current_section->requires = requires; current_section->conflicts = conflicts; - current_address = oldsection_address; - if (current_address->l_address.bank > all_mem) { - err_msg_big_address(&cmdpoint); - current_address->l_address.bank &= all_mem; - } - - if (doubledef) val_destroy(&structure->v); - else { - address_t end = (section_address.end < section_address.address) ? section_address.address : section_address.end; - if (structure->size != (end & all_mem2)) { - structure->size = end & all_mem2; - if (label->usepass >= pass) { - if (fixeddig && pass > max_pass) err_msg_cant_calculate(&label->name, &label->epoint); - fixeddig = false; - } - } - } - val_destroy(section_address.l_address_val); - val_destroy(§ion_address.mem->v); - goto breakerr; - } - case CMD_SECTION: - if (section_start(&cmdpoint)) goto breakerr; - star = (current_address->l_address.address & 0xffff) | current_address->l_address.bank; - break; - case CMD_VIRTUAL: - if (virtual_start(&cmdpoint)) goto breakerr; - star = (current_address->l_address.address & 0xffff) | current_address->l_address.bank; - break; - case CMD_BREPT: - case CMD_BFOR: - { /* .bfor */ - List *lst; - bool labelexists; - size_t i; - Label *label = new_label(&labelname, mycontext, strength, &labelexists, current_file_list); - if (labelexists) { - if (label->defpass == pass) { - err_msg_double_defined(label, &labelname, &epoint); - epoint = cmdpoint; - goto as_command; + err_msg_double_defined(label, &labelname, &epoint); + } else { + if (label->fwpass == pass) fwcount--; + if (!constcreated && label->defpass != pass - 1) { + if (pass > max_pass) err_msg_cant_calculate(&label->name, &epoint); + constcreated = true; + } + label->constant = true; + label->owner = true; + if (label->file_list != current_file_list) { + label_move(label, &labelname, current_file_list); + } + label->epoint = epoint; + label->ref = false; + if (label->value->obj == obj) { + Struct *prev = (Struct *)label->value; + structure->size = prev->size; + structure->names = ref_namespace(prev->names); + structure->names->backr = structure->names->forwr = 0; + structure->names->file_list = current_file_list; + structure->names->epoint = epoint; + } else { + structure->size = 0; + structure->names = new_namespace(current_file_list, &epoint); + } + const_assign(label, &structure->v); + structure = (Struct *)label->value; + } } else { - if (!constcreated && temporary_label_branch == 0 && label->defpass != pass - 1) { + structure->retval = false; + if (!constcreated == 0) { if (pass > max_pass) err_msg_cant_calculate(&label->name, &epoint); constcreated = true; } - if (label->file_list != current_file_list) { - label_move(label, &labelname, current_file_list); - } - label->defpass = pass; + label->constant = true; + label->owner = true; + label->value = &structure->v; + label->epoint = epoint; + label->ref = false; + structure->size = 0; + structure->names = new_namespace(current_file_list, &epoint); } - } else { - if (!constcreated && temporary_label_branch == 0) { - if (pass > max_pass) err_msg_cant_calculate(&label->name, &epoint); - constcreated = true; + listing_line(listing, cmdpoint.pos); + current_section->structrecursion++; + waitfor->what = (prm == CMD_STRUCT) ? W_ENDS2 : W_ENDU2; + waitfor->skip = 1; + val = macro_recurse(W_ENDS, &structure->v, structure->names, &cmdpoint); + structure->retval = (val != NULL); + if (val != NULL) val_destroy(val); + waitfor->what = (prm == CMD_STRUCT) ? W_ENDS : W_ENDU; + waitfor->skip = 0; + lpoint.line--; vline--; + current_section->structrecursion--; + + current_section->provides = provides; current_section->requires = requires; current_section->conflicts = conflicts; + current_address = oldsection_address; + if (current_address->l_address.bank > all_mem) { + err_msg_big_address(&cmdpoint); + current_address->l_address.bank &= all_mem; } - label->value = (Obj *)ref_none(); - } - label->constant = true; - label->owner = true; - label->epoint = epoint; - label->ref = false; - if (label->value->obj == TUPLE_OBJ) { - List *old = (List *)label->value; - lst = new_tuple(old->len); - for (i = 0; i < old->len; i++) lst->data[i] = val_reference(old->data[i]); - } else { - lst = new_tuple(lenof(lst->u.val)); - for (i = 0; i < lst->len; i++) lst->data[i] = (Obj *)ref_none(); + + if (doubledef) val_destroy(&structure->v); + else { + address_t end = (section_address.end < section_address.address) ? section_address.address : section_address.end; + if (structure->size != (end & all_mem2)) { + structure->size = end & all_mem2; + if (label->usepass >= pass) { + if (fixeddig && pass > max_pass) err_msg_cant_calculate(&label->name, &label->epoint); + fixeddig = false; + } + } + } + val_destroy(section_address.l_address_val); + val_destroy(§ion_address.mem->v); + goto breakerr; } - label = ref_label(label); - i = (prm == CMD_BFOR) ? for_command(label, lst, &cmdpoint) : rept_command(label, lst, &cmdpoint); - if (lst->len > i) list_shrink(lst, i); - const_assign(label, &lst->v); - val_destroy(&label->v); - goto breakerr; - } - case CMD_DSTRUCT: /* .dstruct */ - case CMD_DUNION: - { - address_t oldstart, oldend; - address2_t oldl_start, oldl_union; - bool oldunionmode; - bool labelexists, ret; - Type *obj; - Namespace *context; - Label *label = new_label(&labelname, mycontext, strength, &labelexists, current_file_list); - if (labelexists) { - if (label->defpass == pass) { - err_msg_double_defined(label, &labelname, &epoint); - epoint = cmdpoint; - goto as_command; + case CMD_SECTION: + if (section_start(&cmdpoint)) goto breakerr; + star = (current_address->l_address.address & 0xffff) | current_address->l_address.bank; + break; + case CMD_VIRTUAL: + if (virtual_start(&cmdpoint)) goto breakerr; + star = (current_address->l_address.address & 0xffff) | current_address->l_address.bank; + break; + case CMD_BREPT: + case CMD_BFOR: + case CMD_BWHILE: + { /* .bfor */ + List *lst; + bool labelexists; + size_t i; + Label *label = new_label(&labelname, mycontext, strength, &labelexists, current_file_list); + if (labelexists) { + if (label->defpass == pass) { + err_msg_double_defined(label, &labelname, &epoint); + epoint = cmdpoint; + goto as_command; + } else { + if (label->fwpass == pass) fwcount--; + if (!constcreated && label->defpass != pass - 1) { + if (pass > max_pass) err_msg_cant_calculate(&label->name, &epoint); + constcreated = true; + } + if (label->file_list != current_file_list) { + label_move(label, &labelname, current_file_list); + } + label->defpass = pass; + } } else { - if (!constcreated && temporary_label_branch == 0 && label->defpass != pass - 1) { + if (!constcreated) { if (pass > max_pass) err_msg_cant_calculate(&label->name, &epoint); constcreated = true; } - if (label->file_list != current_file_list) { - label_move(label, &labelname, current_file_list); - } + label->value = (Obj *)ref_none(); } - } else { - if (!constcreated && temporary_label_branch == 0) { - if (pass > max_pass) err_msg_cant_calculate(&label->name, &epoint); - constcreated = true; + label->constant = true; + label->owner = true; + label->epoint = epoint; + label->ref = false; + if (label->value->obj == TUPLE_OBJ) { + List *old = (List *)label->value; + lst = new_tuple(old->len); + for (i = 0; i < old->len; i++) lst->data[i] = val_reference(old->data[i]); + } else { + lst = new_tuple(lenof(lst->u.val)); + for (i = 0; i < lst->len; i++) lst->data[i] = (Obj *)ref_none(); } - label->value = (Obj *)ref_none(); + label = ref_label(label); + i = (prm == CMD_BFOR) ? for_command(label, lst, &cmdpoint) : (prm == CMD_BREPT) ? rept_command(label, lst, &cmdpoint) : while_command(label, lst, &cmdpoint); + if (lst->len > i) list_shrink(lst, i); + const_assign(label, &lst->v); + val_destroy(&label->v); + goto breakerr; } - label->constant = true; - label->owner = true; - label->epoint = epoint; - label->ref = false; - - if (diagnostics.optimize) cpu_opt_invalidate(); - listing_line(listing, cmdpoint.pos); - if (get_exp(1, 1, 0, &cmdpoint)) { - struct values_s *vs = get_val(); - val = vs->val; - obj = (prm == CMD_DSTRUCT) ? STRUCT_OBJ : UNION_OBJ; - if (val->obj != obj) { - err_msg_wrong_type2(val, obj, &vs->epoint); - val = NULL; + case CMD_DSTRUCT: /* .dstruct */ + case CMD_DUNION: + { + address_t oldstart, oldend; + address2_t oldl_start, oldl_union; + bool oldunionmode; + bool labelexists, ret, doubledef = false; + Type *obj; + Namespace *context; + Label *label = new_label(&labelname, mycontext, strength, &labelexists, current_file_list); + if (labelexists) { + if (label->defpass == pass) { + doubledef = true; + err_msg_double_defined(label, &labelname, &epoint); + } else { + if (label->fwpass == pass) fwcount--; + if (!constcreated && label->defpass != pass - 1) { + if (pass > max_pass) err_msg_cant_calculate(&label->name, &epoint); + constcreated = true; + } + label->constant = true; + label->owner = true; + if (label->file_list != current_file_list) { + label_move(label, &labelname, current_file_list); + } + label->epoint = epoint; + label->ref = false; + } + } else { + if (!constcreated) { + if (pass > max_pass) err_msg_cant_calculate(&label->name, &epoint); + constcreated = true; + } + label->value = (Obj *)ref_none(); + label->constant = true; + label->owner = true; + label->epoint = epoint; + label->ref = false; } - } else val = NULL; - ret = (val != NULL) && ((Struct *)val)->retval; - if (here() == ',') lpoint.pos++; - current_section->structrecursion++; - oaddr = current_address->address; - newmembp = get_mem(current_address->mem); - oldstart = current_address->start; - oldend = current_address->end; - oldl_start = current_address->l_start; - oldl_union = current_address->l_union; - oldunionmode = current_address->unionmode; - current_address->start = current_address->end = current_address->address; - current_address->l_start = current_address->l_address; - current_address->l_union = current_address->l_address; - current_address->unionmode = (prm == CMD_DUNION); - - if (!ret) { - Code *code = (Code *)label->value; - if (labelexists && code->v.obj == CODE_OBJ) { - Obj *tmp = get_star_value(current_address->l_address_val); - if (!tmp->obj->same(tmp, code->addr)) { - val_destroy(code->addr); code->addr = tmp; - if (label->usepass >= pass) { - if (fixeddig && pass > max_pass) err_msg_cant_calculate(&label->name, &epoint); - fixeddig = false; + if (diagnostics.optimize) cpu_opt_invalidate(); + listing_line(listing, cmdpoint.pos); + if (get_exp(1, 1, 0, &cmdpoint)) { + struct values_s *vs = get_val(); + val = vs->val; + obj = (prm == CMD_DSTRUCT) ? STRUCT_OBJ : UNION_OBJ; + if (val->obj != obj) { + err_msg_wrong_type2(val, obj, &vs->epoint); + val = NULL; + } + } else val = NULL; + ret = (val != NULL) && ((Struct *)val)->retval; + if (here() == ',') lpoint.pos++; + current_section->structrecursion++; + + oaddr = current_address->address; + newmembp = get_mem(current_address->mem); + oldstart = current_address->start; + oldend = current_address->end; + oldl_start = current_address->l_start; + oldl_union = current_address->l_union; + oldunionmode = current_address->unionmode; + current_address->start = current_address->end = current_address->address; + current_address->l_start = current_address->l_address; + current_address->l_union = current_address->l_address; + current_address->unionmode = (prm == CMD_DUNION); + + if (!ret && !doubledef) { + Code *code = (Code *)label->value; + if (labelexists && code->v.obj == CODE_OBJ) { + Obj *tmp = current_address->l_address_val; + if (!tmp->obj->same(tmp, code->typ)) { + val_destroy(code->typ); code->typ = val_reference(tmp); + if (label->usepass >= pass) { + if (fixeddig && pass > max_pass) err_msg_cant_calculate(&label->name, &epoint); + fixeddig = false; + } + } + if (code->addr != star || code->requires != current_section->requires || code->conflicts != current_section->conflicts || code->offs != 0) { + code->addr = star; + code->requires = current_section->requires; + code->conflicts = current_section->conflicts; + code->offs = 0; + if (label->usepass >= pass) { + if (fixeddig && pass > max_pass) err_msg_cant_calculate(&label->name, &epoint); + fixeddig = false; + } } - } else val_destroy(tmp); - if (code->requires != current_section->requires || code->conflicts != current_section->conflicts || code->offs != 0) { + code->apass = pass; + label->defpass = pass; + code->names->backr = code->names->forwr = 0; + code->names->file_list = current_file_list; + code->names->epoint = epoint; + } else { + val_destroy(&code->v); + code = new_code(); + label->value = (Obj *)code; + code->addr = star; + code->typ = val_reference(current_address->l_address_val); + code->size = 0; + code->offs = 0; + code->dtype = D_NONE; + code->pass = 0; + code->apass = pass; + code->memblocks = ref_memblocks(current_address->mem); + code->names = new_namespace(current_file_list, &epoint); code->requires = current_section->requires; code->conflicts = current_section->conflicts; - code->offs = 0; - if (label->usepass >= pass) { - if (fixeddig && pass > max_pass) err_msg_cant_calculate(&label->name, &epoint); - fixeddig = false; - } } - code->apass = pass; - label->defpass = pass; - code->names->backr = code->names->forwr = 0; + context = code->names; } else { - val_destroy(&code->v); - code = new_code(); - label->value = (Obj *)code; - code->addr = get_star_value(current_address->l_address_val); - code->size = 0; - code->offs = 0; - code->dtype = D_NONE; - code->pass = 0; - code->apass = pass; - code->memblocks = ref_memblocks(current_address->mem); - code->names = new_namespace(current_file_list, &epoint); - code->requires = current_section->requires; - code->conflicts = current_section->conflicts; - } - context = code->names; - } else { - Label *label2; - bool labelexists2; - str_t tmpname; - if (sizeof(anonident2) != sizeof(anonident2.type) + sizeof(anonident2.padding) + sizeof(anonident2.star_tree) + sizeof(anonident2.vline)) memset(&anonident2, 0, sizeof anonident2); - else anonident2.padding[0] = anonident2.padding[1] = anonident2.padding[2] = 0; - anonident2.type = '#'; - anonident2.star_tree = star_tree; - anonident2.vline = vline; - tmpname.data = (const uint8_t *)&anonident2; tmpname.len = sizeof anonident2; - label2 = new_label(&tmpname, mycontext, strength, &labelexists2, current_file_list); - if (labelexists2) { - if (label2->defpass == pass) err_msg_double_defined(label2, &tmpname, &epoint); - label2->constant = true; - label2->owner = true; - label2->defpass = pass; - if (label2->value->obj != NAMESPACE_OBJ) { - val_destroy(label2->value); + Label *label2; + bool labelexists2; + str_t tmpname; + if (sizeof(anonident2) != sizeof(anonident2.type) + sizeof(anonident2.padding) + sizeof(anonident2.star_tree) + sizeof(anonident2.vline)) memset(&anonident2, 0, sizeof anonident2); + else anonident2.padding[0] = anonident2.padding[1] = anonident2.padding[2] = 0; + anonident2.type = '#'; + anonident2.star_tree = star_tree; + anonident2.vline = vline; + tmpname.data = (const uint8_t *)&anonident2; tmpname.len = sizeof anonident2; + label2 = new_label(&tmpname, mycontext, strength, &labelexists2, current_file_list); + if (labelexists2) { + if (label2->defpass == pass) err_msg_double_defined(label2, &tmpname, &epoint); + else if (label2->fwpass == pass) fwcount--; + label2->constant = true; + label2->owner = true; + label2->defpass = pass; + if (label2->value->obj != NAMESPACE_OBJ) { + val_destroy(label2->value); + label2->value = (Obj *)new_namespace(current_file_list, &epoint); + } else { + Namespace *names = (Namespace *)label2->value; + names->backr = names->forwr = 0; + names->file_list = current_file_list; + names->epoint = epoint; + } + } else { + label2->constant = true; + label2->owner = true; label2->value = (Obj *)new_namespace(current_file_list, &epoint); - } else ((Namespace *)label2->value)->backr = ((Namespace *)label2->value)->forwr = 0; - } else { - label2->constant = true; - label2->owner = true; - label2->value = (Obj *)new_namespace(current_file_list, &epoint); - label2->epoint = epoint; - } - context = (Namespace *)label2->value; - } - label = ref_label(label); - if (val != NULL) { - val = macro_recurse((prm == CMD_DSTRUCT) ? W_ENDS3 : W_ENDU3, val, context, &cmdpoint); + label2->epoint = epoint; + } + context = (Namespace *)label2->value; + } + label = ref_label(label); if (val != NULL) { - if (ret) const_assign(label, val); - else val_destroy(val); + val = macro_recurse((prm == CMD_DSTRUCT) ? W_ENDS3 : W_ENDU3, val, context, &cmdpoint); + if (val != NULL) { + if (ret && !doubledef) const_assign(label, val); + else val_destroy(val); + } } - } - current_section->structrecursion--; + current_section->structrecursion--; - if (!ret) set_size(label, ((current_address->end < current_address->address) ? current_address->address : current_address->end) - oaddr, current_address->mem, oaddr, newmembp); - current_address->start = oldstart; - oldstart = current_address->unionmode ? current_address->end : current_address->address; - if (oldend > current_address->end) current_address->end = oldend; - current_address->l_start = oldl_start; - current_address->l_union = oldl_union; - current_address->unionmode = oldunionmode; - if (oldstart > current_address->address) { - poke_pos = &epoint; - memskip(oldstart - current_address->address); - } - val_destroy(&label->v); - goto breakerr; - } - } - break; - } - { - bool labelexists = false; - Code *code; - if (labelname.data[0] == '*') { - err_msg2(ERROR_RESERVED_LABL, &labelname, &epoint); - newlabel = NULL; - epoint = lpoint; - goto jn; - } - if (!islabel) { - Namespace *parent; - bool down = (labelname.data[0] != '_'); - if (down) { - parent = mycontext; - tmp2 = find_label(&labelname, &parent); - } else { - parent = cheap_context; - tmp2 = find_label2(&labelname, cheap_context); - } - if (tmp2 != NULL) { - const Type *obj = tmp2->value->obj; - if (diagnostics.case_symbol && str_cmp(&labelname, &tmp2->name) != 0) err_msg_symbol_case(&labelname, tmp2, &epoint); - if (obj == MACRO_OBJ || obj == SEGMENT_OBJ || obj == MFUNC_OBJ) { - touch_label(tmp2); - labelname.len = 0;val = tmp2->value; goto as_macro; - } - if (parent == mycontext && tmp2->strength == strength) { - newlabel = tmp2; - labelexists = true; + if (!ret && !doubledef) set_size(label, ((current_address->end < current_address->address) ? current_address->address : current_address->end) - oaddr, current_address->mem, oaddr, newmembp); + current_address->start = oldstart; + oldstart = current_address->unionmode ? current_address->end : current_address->address; + if (oldend > current_address->end) current_address->end = oldend; + current_address->l_start = oldl_start; + current_address->l_union = oldl_union; + current_address->unionmode = oldunionmode; + if (oldstart > current_address->address) { + memskip(oldstart - current_address->address, &epoint); + } + val_destroy(&label->v); + goto breakerr; } } + break; } - if (!labelexists) newlabel = new_label(&labelname, mycontext, strength, &labelexists, current_file_list); - oaddr = current_address->address; - if (labelexists) { - if (newlabel->defpass == pass) { - err_msg_double_defined(newlabel, &labelname, &epoint); + { + bool labelexists = false; + Code *code; + if (labelname.data[0] == '*') { + err_msg2(ERROR_RESERVED_LABL, &labelname, &epoint); newlabel = NULL; - if (wht == '.') { - epoint = cmdpoint; - goto as_command; - } epoint = lpoint; goto jn; } - if (!newlabel->update_after && newlabel->value->obj != CODE_OBJ) { - val_destroy(newlabel->value); - labelexists = false; - newlabel->defpass = pass; + if (!islabel) { + Namespace *parent; + bool down = (labelname.data[0] != '_'); + if (down) { + parent = mycontext; + tmp2 = find_label(&labelname, &parent); + } else { + parent = cheap_context; + tmp2 = find_label2(&labelname, cheap_context); + } + if (tmp2 != NULL) { + const Type *obj = tmp2->value->obj; + if (diagnostics.case_symbol && str_cmp(&labelname, &tmp2->name) != 0) err_msg_symbol_case(&labelname, tmp2, &epoint); + if (obj == MACRO_OBJ || obj == SEGMENT_OBJ || obj == MFUNC_OBJ) { + if (diagnostics.macro_prefix && (here() == 0 || here() == ';')) err_msg_macro_prefix(&epoint); + touch_label(tmp2); + labelname.len = 0;val = tmp2->value; goto as_macro; + } + if (parent == mycontext && tmp2->strength == strength) { + newlabel = tmp2; + labelexists = true; + } + } } - } - if (labelexists) { - if (!constcreated && temporary_label_branch == 0 && newlabel->defpass != pass - 1) { + if (!labelexists) newlabel = new_label(&labelname, mycontext, strength, &labelexists, current_file_list); + oaddr = current_address->address; + if (labelexists) { + if (newlabel->defpass == pass) { + err_msg_double_defined(newlabel, &labelname, &epoint); + newlabel = NULL; + if (wht == '.') { + epoint = cmdpoint; + goto as_command; + } + epoint = lpoint; + goto jn; + } + if (!constcreated && newlabel->defpass != pass - 1) { + if (pass > max_pass) err_msg_cant_calculate(&newlabel->name, &epoint); + constcreated = true; + } + if (newlabel->fwpass == pass) fwcount--; + if (newlabel->file_list != current_file_list) { + label_move(newlabel, &labelname, current_file_list); + } + if (!newlabel->update_after && newlabel->value->obj != CODE_OBJ) { + val_destroy(newlabel->value); + labelexists = false; + newlabel->defpass = pass; + } + } else if (!constcreated) { if (pass > max_pass) err_msg_cant_calculate(&newlabel->name, &epoint); constcreated = true; } - newlabel->constant = true; - newlabel->owner = true; - if (newlabel->file_list != current_file_list) { - label_move(newlabel, &labelname, current_file_list); - } - newlabel->epoint = epoint; - if (!newlabel->update_after) { - Obj *tmp; - if (diagnostics.optimize && newlabel->ref) cpu_opt_invalidate(); - tmp = get_star_value(current_address->l_address_val); - code = (Code *)newlabel->value; - if (!tmp->obj->same(tmp, code->addr)) { - val_destroy(code->addr); code->addr = tmp; - if (newlabel->usepass >= pass) { - if (fixeddig && pass > max_pass) err_msg_cant_calculate(&newlabel->name, &epoint); - fixeddig = false; + if (labelexists) { + newlabel->constant = true; + newlabel->owner = true; + newlabel->epoint = epoint; + if (newlabel->update_after) { + newlabel->update_after = false; + } else { + Obj *tmp; + if (diagnostics.optimize && newlabel->ref) cpu_opt_invalidate(); + tmp = current_address->l_address_val; + code = (Code *)newlabel->value; + if (!tmp->obj->same(tmp, code->typ)) { + val_destroy(code->typ); code->typ = val_reference(tmp); + if (newlabel->usepass >= pass) { + if (fixeddig && pass > max_pass) err_msg_cant_calculate(&newlabel->name, &epoint); + fixeddig = false; + } } - } else val_destroy(tmp); - if (code->requires != current_section->requires || code->conflicts != current_section->conflicts || code->offs != 0) { - code->requires = current_section->requires; - code->conflicts = current_section->conflicts; - code->offs = 0; - if (newlabel->usepass >= pass) { - if (fixeddig && pass > max_pass) err_msg_cant_calculate(&newlabel->name, &epoint); - fixeddig = false; + if (code->addr != star || code->requires != current_section->requires || code->conflicts != current_section->conflicts || code->offs != 0) { + code->addr = star; + code->requires = current_section->requires; + code->conflicts = current_section->conflicts; + code->offs = 0; + if (newlabel->usepass >= pass) { + if (fixeddig && pass > max_pass) err_msg_cant_calculate(&newlabel->name, &epoint); + fixeddig = false; + } } + newmembp = get_mem(current_address->mem); + code->apass = pass; + newlabel->defpass = pass; + code->names->backr = code->names->forwr = 0; + code->names->file_list = current_file_list; + code->names->epoint = epoint; } - newmembp = get_mem(current_address->mem); + } else { + if (diagnostics.optimize) cpu_opt_invalidate(); + code = new_code(); + newlabel->constant = true; + newlabel->owner = true; + newlabel->value = (Obj *)code; + newlabel->epoint = epoint; + code->addr = star; + code->typ = val_reference(current_address->l_address_val); + code->size = 0; + code->offs = 0; + code->dtype = D_NONE; + code->pass = 0; code->apass = pass; - newlabel->defpass = pass; - code->names->backr = code->names->forwr = 0; - } - } else { - if (diagnostics.optimize) cpu_opt_invalidate(); - code = new_code(); - if (!constcreated && temporary_label_branch == 0) { - if (pass > max_pass) err_msg_cant_calculate(&newlabel->name, &epoint); - constcreated = true; + code->memblocks = ref_memblocks(current_address->mem); + code->names = new_namespace(current_file_list, &epoint); + code->requires = current_section->requires; + code->conflicts = current_section->conflicts; + newmembp = get_mem(current_address->mem); } - newlabel->constant = true; - newlabel->owner = true; - newlabel->value = (Obj *)code; - newlabel->epoint = epoint; - code->addr = get_star_value(current_address->l_address_val); - code->size = 0; - code->offs = 0; - code->dtype = D_NONE; - code->pass = 0; - code->apass = pass; - code->memblocks = ref_memblocks(current_address->mem); - code->names = new_namespace(current_file_list, &epoint); - code->requires = current_section->requires; - code->conflicts = current_section->conflicts; - newmembp = get_mem(current_address->mem); } - } - if (wht == '.') { /* .proc */ - epoint = cmdpoint; - switch (prm) { - case CMD_PROC: - listing_line(listing, epoint.pos); - new_waitfor(W_PEND, &epoint); - if (!newlabel->ref && ((Code *)newlabel->value)->pass != 0) { - waitfor->skip = 0; set_size(newlabel, 0, current_address->mem, oaddr, newmembp); - push_dummy_context(); - waitfor->u.cmd_proc.label = NULL; - } else { /* TODO: first time it should not compile */ - push_context(((Code *)newlabel->value)->names); + if (wht == '.') { /* .proc */ + epoint = cmdpoint; + switch (prm) { + case CMD_PROC: + new_waitfor(W_PEND, &epoint); + if (newlabel->value->obj != CODE_OBJ) { + listing_line(listing, 0); + waitfor->skip = 0; push_dummy_context(); + waitfor->u.cmd_proc.label = NULL; + } else if (!newlabel->ref && ((Code *)newlabel->value)->pass != 0) { + listing_line(listing, 0); + waitfor->skip = 0; + set_size(newlabel, 0, current_address->mem, oaddr, newmembp); + ((Code *)newlabel->value)->pass = 1; + push_dummy_context(); + waitfor->u.cmd_proc.label = NULL; + } else { /* TODO: first time it should not compile */ + listing_line(listing, epoint.pos); + push_context(((Code *)newlabel->value)->names); + newlabel->ref = false; + waitfor->u.cmd_proc.addr = current_address->address;waitfor->u.cmd_proc.membp = newmembp;waitfor->u.cmd_proc.label = ref_label(newlabel); + } + newlabel = NULL; + goto finish; + case CMD_SECTION: + waitfor->u.cmd_section.addr = current_address->address;waitfor->u.cmd_section.membp = newmembp;waitfor->u.cmd_section.label = ref_label(newlabel); + listing_line(listing, epoint.pos); + newlabel->ref = false; + newlabel = NULL; + goto finish; + case CMD_VIRTUAL: + waitfor->u.cmd_virtual.membp = newmembp;waitfor->u.cmd_virtual.label = ref_label(newlabel); + listing_line(listing, epoint.pos); newlabel->ref = false; - waitfor->u.cmd_proc.addr = current_address->address;waitfor->u.cmd_proc.membp = newmembp;waitfor->u.cmd_proc.label = ref_label(newlabel); + newlabel = NULL; + goto finish; } - newlabel = NULL; - goto finish; - case CMD_SECTION: - waitfor->u.cmd_section.addr = current_address->address;waitfor->u.cmd_section.membp = newmembp;waitfor->u.cmd_section.label = ref_label(newlabel); - listing_line(listing, epoint.pos); - newlabel->ref = false; - newlabel = NULL; - goto finish; - case CMD_VIRTUAL: - waitfor->u.cmd_virtual.membp = newmembp;waitfor->u.cmd_virtual.label = ref_label(newlabel); - listing_line(listing, epoint.pos); newlabel->ref = false; - newlabel = NULL; - goto finish; + goto as_command; + } + if (labelname.len == 3 && !newlabel->ref && epoint.pos != 0 && !islabel && diagnostics.label_left) { + unsigned int i; + for (i = 0; i < 3; i++) { + uint8_t c = labelname.data[i] | arguments.caseinsensitive; + if ((c < 'a') || (c > 'z')) break; + } + if (i == 3) err_msg_label_left(&epoint); } + epoint = lpoint; newlabel->ref = false; - goto as_command; } - if (labelname.len == 3 && !newlabel->ref && epoint.pos != 0 && !islabel && diagnostics.label_left) { - unsigned int i; - for (i = 0; i < 3; i++) { - uint8_t c = labelname.data[i] | arguments.caseinsensitive; - if ((c < 'a') || (c > 'z')) break; + } else { + switch (wht) { + case '*': + lpoint.pos++; + switch (here()) { + case ' ': + case '\t': + case ';': + case '=': + case '\0': + labelname.data = (const uint8_t *)"*";labelname.len = 1; + goto hh; + default: + lpoint.pos--; } - if (i == 3) err_msg_label_left(&epoint); + break; + case '-': + case '+': + lpoint.pos++; + switch (here()) { + case ' ': + case '\t': + case ';': + case '\0': + { + uint32_t count = (uint32_t)((wht == '-') ? current_context->backr++ : current_context->forwr++); + anonident.dir = (uint8_t)wht; + anonident.pad = 0; + labelname.len = 2; + while (count != 0) { + anonident.count[labelname.len - 2] = count; + labelname.len++; + count >>= 8; + } + labelname.data = (const uint8_t *)&anonident; + } + goto hh; + default: + lpoint.pos--; + } + break; + default: + break; } - epoint = lpoint; - newlabel->ref = false; } jn: switch (wht) { @@ -2784,7 +2983,7 @@ case ';': case '\0': if ((waitfor->skip & 1) != 0) { - if (newlabel != NULL && newlabel->value->obj == CODE_OBJ && labelname.len != 0 && labelname.data[0] != '_' && labelname.data[0] != '+' && labelname.data[0] != '-' && mycontext == current_context) {val_destroy(&cheap_context->v);cheap_context = ref_namespace(((Code *)newlabel->value)->names);} + if (newlabel != NULL && newlabel->value->obj == CODE_OBJ && labelname.len != 0 && labelname.data[0] != '_' && labelname.data[0] != '+' && labelname.data[0] != '-') {val_destroy(&cheap_context->v);cheap_context = ref_namespace(((Code *)newlabel->value)->names);} listing_line(listing, epoint.pos); } break; @@ -2931,7 +3130,7 @@ if (waitfor->what == W_SWITCH) { err_msg2(ERROR______EXPECTED, "'.endswitch'", &epoint); goto breakerr; } if (waitfor->what != W_SWITCH2) { err_msg2(ERROR__MISSING_OPEN, ".switch", &epoint); goto breakerr; } waitfor->epoint = epoint; - if (skwait==2 || diagnostics.switch_case) { + if (skwait == 2 || diagnostics.switch_case) { struct values_s *vs; Obj *result2; struct oper_s tmp; @@ -2940,8 +3139,8 @@ tmp.epoint = tmp.epoint3 = &epoint; while (!truth && (vs = get_val()) != NULL) { val = vs->val; - if (val->obj == ERROR_OBJ) { err_msg_output((Error *)val); continue; } - if (val == &none_value->v) { err_msg_still_none(NULL, &vs->epoint);continue; } + if (val->obj == ERROR_OBJ) { if (skwait == 2) err_msg_output((Error *)val); continue; } + if (val == &none_value->v) { if (skwait == 2) err_msg_still_none(NULL, &vs->epoint);continue; } tmp.v1 = waitfor->u.cmd_switch.val; tmp.v2 = val; tmp.epoint2 = &vs->epoint; @@ -2977,7 +3176,12 @@ } else err_msg2(ERROR__MISSING_OPEN, ".macro' or '.segment", &epoint); goto breakerr; case CMD_ENDF: /* .endf */ - if (close_waitfor(W_ENDF)) { + if (waitfor->what==W_ENDF) { + if (waitfor->u.cmd_function.val != NULL) { + ((Mfunc *)waitfor->u.cmd_function.val)->retval = (here() != 0 && here() != ';'); + val_destroy(waitfor->u.cmd_function.val); + } + close_waitfor(W_ENDF); if ((waitfor->skip & 1) != 0) listing_line_cut2(listing, epoint.pos); } else if (waitfor->what==W_ENDF3) { /* not closed here */ nobreak = false; @@ -2996,7 +3200,7 @@ nobreak = false; } else if (close_waitfor(W_NEXT3)) { pop_context(); - } else {err_msg2(ERROR__MISSING_OPEN, ".for' or '.rept", &epoint); goto breakerr;} + } else {err_msg2(ERROR__MISSING_OPEN, ".for', '.rept' or '.while", &epoint); goto breakerr;} break; case CMD_PEND: /* .pend */ if (waitfor->what==W_PEND) { @@ -3029,13 +3233,14 @@ case CMD_SEND: /* .send */ if ((waitfor->skip & 1) != 0) listing_line(listing, epoint.pos); if (close_waitfor(W_SEND)) { - get_label(); + lpoint.pos += get_label(pline + lpoint.pos); } else if (waitfor->what==W_SEND2) { str_t sectionname; epoint = lpoint; - sectionname.data = pline + lpoint.pos; sectionname.len = get_label(); + sectionname.data = pline + lpoint.pos; sectionname.len = get_label(sectionname.data); if (sectionname.len != 0) { str_t cf; + lpoint.pos += sectionname.len; str_cfcpy(&cf, §ionname); if (str_cmp(&cf, ¤t_section->cfname) != 0) { char *s = (char *)mallocx(current_section->name.len + 1); @@ -3115,6 +3320,14 @@ close_waitfor(W_ENDN2); } else {err_msg2(ERROR__MISSING_OPEN, ".namespace", &epoint); goto breakerr;} break; + case CMD_ENDWITH: /* .endwith */ + if ((waitfor->skip & 1) != 0) listing_line(listing, epoint.pos); + if (close_waitfor(W_ENDWITH)) { + } else if (waitfor->what==W_ENDWITH2) { + if (pop_context2()) err_msg2(ERROR__MISSING_OPEN, ".with", &epoint); + close_waitfor(W_ENDWITH2); + } else {err_msg2(ERROR__MISSING_OPEN, ".with", &epoint); goto breakerr;} + break; case CMD_ENDWEAK: /* .endweak */ if ((waitfor->skip & 1) != 0) listing_line(listing, epoint.pos); if (close_waitfor(W_WEAK)) { @@ -3147,7 +3360,6 @@ { /* .binary */ if (diagnostics.optimize) cpu_opt_invalidate(); mark_mem(current_address->mem, current_address->address, star); - poke_pos = &epoint; if (prm 0) memcpy(pokealloc(trec.len), trec.buff, trec.len); - else if (trec.len < 0) memskip(-trec.len); + if (trec.len > 0) memcpy(pokealloc(trec.len, trec.epoint), trec.buff, trec.len); + else if (trec.len < 0) memskip(-trec.len, trec.epoint); trec.len = 0; } - poke_pos = &vs->epoint; + trec.epoint = &vs->epoint; textrecursion(&trec, vs->val); - if (trec.warn) { err_msg_still_none(NULL, poke_pos); trec.warn = false; } + if (trec.error != ERROR__USER_DEFINED) { err_msg2(trec.error, NULL, trec.epoint); trec.error = ERROR__USER_DEFINED;} } - if (trec.len < 0) { memskip(-trec.len); trec.len = 0; } + if (trec.len < 0) { memskip(-trec.len, trec.epoint); trec.len = 0; } switch (prm) { case CMD_SHIFTL: case CMD_SHIFT: if (trec.len > 0) trec.buff[trec.len - 1] ^= (prm == CMD_SHIFT) ? 0x80 : 0x01; - else if (trec.sum != 0) err_msg2(ERROR___NO_LAST_GAP, NULL, poke_pos); + else if (trec.sum != 0) err_msg2(ERROR___NO_LAST_GAP, NULL, trec.epoint); else err_msg2(ERROR__BYTES_NEEDED, NULL, &epoint); break; case CMD_NULL: if (trec.len >= (ssize_t)sizeof trec.buff) { - memcpy(pokealloc(trec.len), trec.buff, trec.len); + memcpy(pokealloc(trec.len, trec.epoint), trec.buff, trec.len); trec.len = 0; } trec.buff[trec.len++] = outputeor; break; default: break; } - if (trec.len > 0) memcpy(pokealloc(trec.len), trec.buff, trec.len); + if (trec.len > 0) memcpy(pokealloc(trec.len, trec.epoint), trec.buff, trec.len); if (prm == CMD_PTEXT) { if (trec.sum > 0x100) err_msg2(ERROR____PTEXT_LONG, &trec.sum, &epoint); write_mark_mem(current_address->mem, (trec.sum-1) ^ outputeor); @@ -3234,16 +3447,16 @@ brec.len = 0; brec.warn = false; for (ln = get_val_remaining(), vs = get_val(); ln != 0; ln--, vs++) { - poke_pos = &vs->epoint; + brec.epoint = &vs->epoint; byterecursion(vs->val, prm, &brec, bits); - if (brec.warn) { err_msg_still_none(NULL, poke_pos); brec.warn = false; } + if (brec.warn) { err_msg_still_none(NULL, brec.epoint); brec.warn = false; } if (brec.len == 0) continue; - if (brec.len > 0) memcpy(pokealloc(brec.len), brec.buff, brec.len); - else memskip(-brec.len); + if (brec.len > 0) memcpy(pokealloc(brec.len, brec.epoint), brec.buff, brec.len); + else memskip(-brec.len, brec.epoint); brec.len = 0; } } else if (prm==CMD_BINARY) { /* .binary */ - char *path = NULL; + struct file_s *cfile2 = NULL; ival_t foffs = 0; size_t fsize = SIZE_MAX; struct values_s *vs; @@ -3255,7 +3468,9 @@ if (!get_exp(0, 1, 3, &epoint)) goto breakerr; vs = get_val(); if (!tostr(vs, &filename)) { - path = get_path(&filename, current_file_list->file->realname); + char *path = get_path(&filename, current_file_list->file->realname); + cfile2 = openfile(path, current_file_list->file->realname, 1, &filename, &vs->epoint); + free(path); } if ((vs = get_val()) != NULL) { ival_t ival; @@ -3268,25 +3483,21 @@ } } - if (path != NULL) { - struct file_s *cfile2 = openfile(path, current_file_list->file->realname, 1, &filename, &epoint); - if (cfile2 != NULL) { - size_t foffset; - if (foffs < 0) foffset = (uval_t)-foffs < cfile2->len ? (cfile2->len - (uval_t)-foffs) : 0; - else foffset = (uval_t)foffs; - for (; fsize != 0 && foffset < cfile2->len;) { - size_t i, ln = cfile2->len - foffset; - uint8_t *d, *s = cfile2->data + foffset; - if (ln > fsize) ln = fsize; - d = pokealloc((address_t)ln); - if (outputeor != 0) { - for (i = 0; i < ln; i++) d[i] = s[i] ^ outputeor; - } else memcpy(d, s, ln); - foffset += ln; - fsize -= ln; - } + if (cfile2 != NULL) { + size_t foffset; + if (foffs < 0) foffset = (uval_t)-foffs < cfile2->len ? (cfile2->len - (uval_t)-foffs) : 0; + else foffset = (uval_t)foffs; + for (; fsize != 0 && foffset < cfile2->len;) { + size_t i, ln = cfile2->len - foffset; + uint8_t *d, *s = cfile2->data + foffset; + if (ln > fsize) ln = fsize; + d = pokealloc((address_t)ln, &epoint); + if (outputeor != 0) { + for (i = 0; i < ln; i++) d[i] = s[i] ^ outputeor; + } else memcpy(d, s, ln); + foffset += ln; + fsize -= ln; } - free(path); } } @@ -3336,9 +3547,10 @@ if (!get_exp(0, 1, 1, &epoint)) goto breakerr; vs = get_val(); tmp = vs->val; - if (touval(tmp->obj->address(tmp, &am), &uval, all_mem_bits, &vs->epoint)) break; + if (touaddress(tmp, &uval, all_mem_bits, &vs->epoint)) break; + am = tmp->obj->address(tmp); if (am != A_NONE && check_addr(am)) { - err_msg_output_and_destroy(err_addressing(am, &vs->epoint)); + err_msg_output_and_destroy(err_addressing(am, &vs->epoint, -1)); break; } if (current_address->unionmode) { @@ -3350,7 +3562,7 @@ } val_destroy(current_address->l_address_val); tmp = vs->val; - current_address->l_address_val = val_reference(tmp->obj == CODE_OBJ ? ((Code *)tmp)->addr : tmp); + current_address->l_address_val = get_star_value(0, tmp); } else new_waitfor(W_HERE, &epoint); break; case CMD_VIRTUAL: if ((waitfor->skip & 1) != 0) @@ -3402,13 +3614,19 @@ label = new_label(&tmpname, mycontext, strength, &labelexists, current_file_list); if (labelexists) { if (label->defpass == pass) err_msg_double_defined(label, &tmpname, &epoint); + else if (label->fwpass == pass) fwcount--; label->constant = true; label->owner = true; label->defpass = pass; if (label->value->obj != NAMESPACE_OBJ) { val_destroy(label->value); label->value = (Obj *)new_namespace(current_file_list, &epoint); - } else ((Namespace *)label->value)->backr = ((Namespace *)label->value)->forwr = 0; + } else { + Namespace *names = (Namespace *)label->value; + names->backr = names->forwr = 0; + names->file_list = current_file_list; + names->epoint = epoint; + } } else { label->constant = true; label->owner = true; @@ -3444,6 +3662,7 @@ label = new_label(&tmpname, mycontext, strength, &labelexists, current_file_list); if (labelexists) { if (label->defpass == pass) err_msg_double_defined(label, &tmpname, &epoint); + else if (label->fwpass == pass) fwcount--; label->constant = true; label->owner = (val == NULL); if (val != NULL) const_assign(label, val_reference(val)); @@ -3452,7 +3671,12 @@ if (label->value->obj != NAMESPACE_OBJ) { val_destroy(label->value); label->value = (Obj *)new_namespace(current_file_list, &epoint); - } else ((Namespace *)label->value)->backr = ((Namespace *)label->value)->forwr = 0; + } else { + Namespace *names = (Namespace *)label->value; + names->backr = names->forwr = 0; + names->file_list = current_file_list; + names->epoint = epoint; + } } } else { label->constant = true; @@ -3466,6 +3690,26 @@ } else push_context(current_context); } else {push_dummy_context(); new_waitfor(W_ENDN, &epoint);} break; + case CMD_WITH: if ((waitfor->skip & 1) != 0) + { /* .namespace */ + struct values_s *vs; + listing_line(listing, epoint.pos); + new_waitfor(W_ENDWITH, &epoint); + if (newlabel == NULL) waitfor->u.cmd_with.label = NULL; + else { + waitfor->u.cmd_with.addr = current_address->address;waitfor->u.cmd_with.membp = newmembp;waitfor->u.cmd_with.label = ref_label(newlabel); + newlabel = NULL; + } + if (!get_exp(0, 1, 1, &epoint)) goto breakerr; + vs = get_val(); + val = (Obj *)get_namespace(vs->val); + if (val == NULL) err_msg_wrong_type2(vs->val, NULL, &vs->epoint); + else { + push_context2((Namespace *)val); + waitfor->what = W_ENDWITH2; + } + } else new_waitfor(W_ENDWITH, &epoint); + break; case CMD_WEAK: if ((waitfor->skip & 1) != 0) { /* .weak */ listing_line(listing, epoint.pos); @@ -3546,29 +3790,27 @@ struct textrecursion_s trec; size_t membp = get_mem(current_address->mem); - poke_pos = &vs->epoint; trec.len = 0; trec.sum = 0; trec.max = db; trec.prm = CMD_TEXT; - trec.warn = false; + trec.error = ERROR__USER_DEFINED; + trec.epoint = &vs->epoint; textrecursion(&trec, vs->val); - if (trec.warn) { - err_msg_still_none(NULL, poke_pos); - } + if (trec.error != ERROR__USER_DEFINED) err_msg2(trec.error, NULL, trec.epoint); db -= trec.sum; if (db != 0) { if (trec.sum == 1 && trec.len == 1) { - memset(pokealloc(db + 1), trec.buff[0], db + 1); /* single byte shortcut */ + memset(pokealloc(db + 1, trec.epoint), trec.buff[0], db + 1); /* single byte shortcut */ trec.len = 0; } else if (trec.sum == (size_t)-trec.len) { - if (trec.sum == 0) err_msg2(ERROR__BYTES_NEEDED, NULL, poke_pos); + if (trec.sum == 0) err_msg2(ERROR__BYTES_NEEDED, NULL, trec.epoint); trec.len -= db; /* gap shortcut */ } else { size_t offs = 0; if (trec.len > 0) { - memcpy(pokealloc(trec.len), trec.buff, trec.len); + memcpy(pokealloc(trec.len, trec.epoint), trec.buff, trec.len); trec.len = 0; } while (db != 0) { /* pattern repeat */ @@ -3577,14 +3819,14 @@ ch = read_mem(current_address->mem, oaddr, membp, offs); if (ch < 0) { if (trec.len > 0) { - memcpy(pokealloc(trec.len), trec.buff, trec.len); + memcpy(pokealloc(trec.len, trec.epoint), trec.buff, trec.len); trec.len = 0; } trec.len--; } else { - if (trec.len < 0) {memskip(-trec.len); trec.len = 0;} + if (trec.len < 0) {memskip(-trec.len, trec.epoint); trec.len = 0;} else if (trec.len >= (ssize_t)sizeof trec.buff) { - memcpy(pokealloc(trec.len), trec.buff, trec.len); + memcpy(pokealloc(trec.len, trec.epoint), trec.buff, trec.len); trec.len = 0; } trec.buff[trec.len++] = ch; @@ -3594,11 +3836,10 @@ } } } - if (trec.len > 0) memcpy(pokealloc(trec.len), trec.buff, trec.len); - else if (trec.len < 0) memskip(-trec.len); + if (trec.len > 0) memcpy(pokealloc(trec.len, trec.epoint), trec.buff, trec.len); + else if (trec.len < 0) memskip(-trec.len, trec.epoint); } else if (db != 0) { - poke_pos = &epoint; - memskip(db); + memskip(db, &epoint); } if (nolisting == 0) { list_mem(current_address->mem); @@ -3701,7 +3942,8 @@ encname.len = 0; if (pline[lpoint.pos] != '"' && pline[lpoint.pos] != '\'') { /* will be removed to allow variables */ if (diagnostics.deprecated) err_msg2(ERROR_______OLD_ENC, NULL, &lpoint); - encname.data = pline + lpoint.pos; encname.len = get_label(); + encname.data = pline + lpoint.pos; encname.len = get_label(encname.data); + lpoint.pos += encname.len; } if (encname.len == 0) { struct values_s *vs; @@ -3831,17 +4073,11 @@ case CMD_CPU: if ((waitfor->skip & 1) != 0) { /* .cpu */ struct values_s *vs; - const struct cpu_list_s { - const char *name; - const struct cpu_s *def; - } *cpui; - static const struct cpu_list_s cpus[] = { - {"6502", &c6502}, {"65c02", &c65c02}, - {"65ce02", &c65ce02}, {"6502i", &c6502i}, - {"65816", &w65816}, {"65dtv02", &c65dtv02}, - {"65el02", &c65el02}, {"r65c02", &r65c02}, - {"w65c02", &w65c02}, {"4510", &c4510}, - {"default", NULL}, {NULL, NULL}, + const struct cpu_s **cpui; + static const struct cpu_s default_cpu = {"default", NULL, NULL, NULL, NULL, 0, 0, 0, 0, 0}; + static const struct cpu_s *cpus[] = { + &c6502, &c65c02, &c65ce02, &c6502i, &w65816, &c65dtv02, + &c65el02, &r65c02, &w65c02, &c4510, &default_cpu, NULL }; str_t cpuname; @@ -3850,9 +4086,9 @@ if (!get_exp(0, 1, 1, &epoint)) goto breakerr; vs = get_val(); if (tostr(vs, &cpuname)) break; - for (cpui = cpus; cpui->name != NULL; cpui++) { - if (cpuname.len == strlen(cpui->name) && memcmp(cpui->name, cpuname.data, cpuname.len) == 0) { - const struct cpu_s *cpumode = (cpui->def != NULL) ? cpui->def : arguments.cpumode; + for (cpui = cpus; *cpui != NULL; cpui++) { + if (cpuname.len == strlen((*cpui)->name) && memcmp((*cpui)->name, cpuname.data, cpuname.len) == 0) { + const struct cpu_s *cpumode = (*cpui != &default_cpu) ? *cpui : arguments.cpumode; if (current_address->l_address.bank > cpumode->max_address) { err_msg_big_address(&epoint); current_address->l_address.bank &= cpumode->max_address; @@ -3861,7 +4097,7 @@ break; } } - if (cpui->name == NULL) err_msg2(ERROR___UNKNOWN_CPU, &cpuname, &vs->epoint); + if (*cpui == NULL) err_msg2(ERROR___UNKNOWN_CPU, &cpuname, &vs->epoint); } break; case CMD_PRON: /* .pron */ @@ -3893,19 +4129,22 @@ { /* .include, .binclude */ struct file_s *f = NULL; struct values_s *vs; - char *path; str_t filename; if (diagnostics.optimize) cpu_opt_invalidate(); listing_line(listing, epoint.pos); if (!get_exp(0, 1, 1, &epoint)) goto breakerr; vs = get_val(); if (!tostr(vs, &filename)) { - path = get_path(&filename, current_file_list->file->realname); - f = openfile(path, current_file_list->file->realname, 2, &filename, &epoint); + char *path = get_path(&filename, current_file_list->file->realname); + f = openfile(path, current_file_list->file->realname, 2, &filename, &vs->epoint); free(path); } if (here() != 0 && here() != ';') err_msg(ERROR_EXTRA_CHAR_OL,NULL); + if (newlabel != NULL && prm == CMD_BINCLUDE && (f == NULL || f->open > 1) && newlabel->value->obj == CODE_OBJ) { + newlabel->update_after = true; + const_assign(newlabel, (Obj *)ref_none()); + } if (f == NULL) goto breakerr; if (f->open>1) { err_msg2(ERROR_FILERECURSION, NULL, &epoint); @@ -3939,13 +4178,19 @@ label = new_label(&tmpname, mycontext, strength, &labelexists, current_file_list); if (labelexists) { if (label->defpass == pass) err_msg_double_defined(label, &tmpname, &epoint); + else if (label->fwpass == pass) fwcount--; label->constant = true; label->owner = true; label->defpass = pass; if (label->value->obj != NAMESPACE_OBJ) { val_destroy(label->value); label->value = (Obj *)new_namespace(current_file_list, &epoint); - } else ((Namespace *)label->value)->backr = ((Namespace *)label->value)->forwr = 0; + } else { + Namespace *names = (Namespace *)label->value; + names->backr = names->forwr = 0; + names->file_list = current_file_list; + names->epoint = epoint; + } } else { label->constant = true; label->owner = true; @@ -3973,6 +4218,7 @@ } break; case CMD_BREPT: + case CMD_BWHILE: case CMD_BFOR: if ((waitfor->skip & 1) != 0) { /* .bfor */ List *lst; @@ -3989,6 +4235,7 @@ label = new_label(&tmpname, mycontext, strength, &labelexists, current_file_list); if (labelexists) { if (label->defpass == pass) err_msg_double_defined(label, &tmpname, &epoint); + else if (label->fwpass == pass) fwcount--; label->defpass = pass; } else { label->value = (Obj *)ref_none(); @@ -4004,7 +4251,7 @@ lst = new_tuple(lenof(lst->u.val)); for (i = 0; i < lst->len; i++) lst->data[i] = (Obj *)ref_none(); } - i = (prm == CMD_BFOR) ? for_command(NULL, lst, &epoint) : rept_command(NULL, lst, &epoint); + i = (prm == CMD_BFOR) ? for_command(NULL, lst, &epoint) : (prm == CMD_BREPT) ? rept_command(NULL, lst, &epoint) : while_command(NULL, lst, &epoint); if (lst->len > i) list_shrink(lst, i); const_assign(label, &lst->v); goto breakerr; @@ -4022,16 +4269,37 @@ goto breakerr; } else new_waitfor(W_NEXT, &epoint); break; + case CMD_WHILE: if ((waitfor->skip & 1) != 0) + { /* .while */ + while_command(NULL, NULL, &epoint); + goto breakerr; + } else new_waitfor(W_NEXT, &epoint); + break; + case CMD_CONTINUEIF: + case CMD_BREAKIF: case CMD_CONTINUE: case CMD_BREAK: if ((waitfor->skip & 1) != 0) - { /* .continue, .break */ + { /* .continue, .break, .continueif, .breakif */ size_t wp = waitfor_p + 1; - bool nok = true; + bool nok = true, doit = true; listing_line(listing, epoint.pos); + if (prm == CMD_CONTINUEIF || prm == CMD_BREAKIF) { + if (get_exp(0, 1, 1, &epoint)) { + struct values_s *vs = get_val(); + bool truth, result = tobool(vs, &truth); + if (prm == CMD_BREAKIF) { + if (!result && !truth) doit = false; + } else { + if (result || !truth) doit = false; + } + } + } while ((wp--) != 0) { if (waitfors[wp].what == W_NEXT2) { - if (wp != 0 && prm == CMD_BREAK) waitfors[wp].u.cmd_rept.breakout = true; - for (;wp <= waitfor_p; wp++) waitfors[wp].skip = 0; + if (doit) { + if (wp != 0 && (prm == CMD_BREAK || prm == CMD_BREAKIF)) waitfors[wp].u.cmd_rept.breakout = true; + for (;wp <= waitfor_p; wp++) waitfors[wp].skip = 0; + } nok = false; break; } @@ -4054,13 +4322,14 @@ break; case CMD_OPTION: if ((waitfor->skip & 1) != 0) { /* .option */ - static const str_t branch_across = {24, (const uint8_t *)"allow_branch_across_page"}; - static const str_t longjmp = {22, (const uint8_t *)"auto_longbranch_as_jmp"}; + static const str_t branch_across = {(const uint8_t *)"allow_branch_across_page", 24}; + static const str_t longjmp = {(const uint8_t *)"auto_longbranch_as_jmp", 22}; struct values_s *vs; str_t optname, cf; listing_line(listing, epoint.pos); - optname.data = pline + lpoint.pos; optname.len = get_label(); + optname.data = pline + lpoint.pos; optname.len = get_label(optname.data); if (optname.len == 0) { err_msg2(ERROR_LABEL_REQUIRE, NULL, &epoint); goto breakerr;} + lpoint.pos += optname.len; ignore();if (here() != '=') {err_msg(ERROR______EXPECTED, "'='"); goto breakerr;} epoint = lpoint; lpoint.pos++; @@ -4123,6 +4392,7 @@ if (labelname.len == 0) err_msg2(ERROR_LABEL_REQUIRE, NULL, &epoint); } new_waitfor(W_ENDF, &epoint); + waitfor->u.cmd_function.val = NULL; waitfor->skip = 0; break; case CMD_VAR: /* .var */ @@ -4205,8 +4475,7 @@ current_address->l_union = oldl_union; current_address->unionmode = oldunionmode; if (oldstart > current_address->address) { - poke_pos = &epoint; - memskip(oldstart - current_address->address); + memskip(oldstart - current_address->address, &epoint); } } goto breakerr; @@ -4219,8 +4488,9 @@ listing_line(listing, epoint.pos); if (current_section->structrecursion != 0) { err_msg2(ERROR___NOT_ALLOWED, ".dsection", &epoint); goto breakerr; } epoint = lpoint; - sectionname.data = pline + lpoint.pos; sectionname.len = get_label(); + sectionname.data = pline + lpoint.pos; sectionname.len = get_label(sectionname.data); if (sectionname.len == 0) {err_msg2(ERROR_LABEL_REQUIRE, NULL, &epoint); goto breakerr;} + lpoint.pos += sectionname.len; tmp3=new_section(§ionname); if (tmp3->defpass == pass) { err_msg_double_definedo(tmp3->file_list, &tmp3->epoint, §ionname, &epoint); @@ -4296,8 +4566,7 @@ tmp3->usepass = pass; tmp3->defpass = pass; if (t != 0) { - poke_pos = &epoint; - memskip(t); + memskip(t, &epoint); } memref(current_address->mem, tmp3->address.mem); } @@ -4337,7 +4606,6 @@ default : err_msg_wrong_type2(val, NULL, &vs->epoint); goto breakerr; } as_macro: - listing_line_cut(listing, epoint.pos); if (val->obj == MACRO_OBJ || val->obj == STRUCT_OBJ || val->obj == UNION_OBJ) { Namespace *context; if (newlabel != NULL && !((Macro *)val)->retval && newlabel->value->obj == CODE_OBJ) { @@ -4355,13 +4623,19 @@ label = new_label(&tmpname, mycontext, strength, &labelexists, current_file_list); if (labelexists) { if (label->defpass == pass) err_msg_double_defined(label, &tmpname, &epoint); + else if (label->fwpass == pass) fwcount--; label->constant = true; label->owner = true; label->defpass = pass; if (label->value->obj != NAMESPACE_OBJ) { val_destroy(label->value); label->value = (Obj *)new_namespace(current_file_list, &epoint); - } else ((Namespace *)label->value)->backr = ((Namespace *)label->value)->forwr = 0; + } else { + Namespace *names = (Namespace *)label->value; + names->backr = names->forwr = 0; + names->file_list = current_file_list; + names->epoint = epoint; + } } else { label->constant = true; label->owner = true; @@ -4370,6 +4644,11 @@ } context = (Namespace *)label->value; } + if (newlabel != NULL && ((Macro *)val)->retval) { + listing_equal(listing, newlabel->value); + } else { + listing_line_cut(listing, epoint.pos); + } val = macro_recurse(val->obj == MACRO_OBJ ? W_ENDM3 : val->obj == STRUCT_OBJ ? W_ENDS3 : W_ENDU3, val, context, &epoint); } else if (val->obj == MFUNC_OBJ) { Label *label; @@ -4385,13 +4664,19 @@ label = new_label(&tmpname, ((Mfunc *)val)->namespaces[((Mfunc *)val)->nslen - 1], strength, &labelexists, current_file_list); if (labelexists) { if (label->defpass == pass) err_msg_double_defined(label, &tmpname, &epoint); + else if (label->fwpass == pass) fwcount--; label->constant = true; label->owner = true; label->defpass = pass; if (label->value->obj != NAMESPACE_OBJ) { val_destroy(label->value); label->value = (Obj *)new_namespace(current_file_list, &epoint); - } else ((Namespace *)label->value)->backr = ((Namespace *)label->value)->forwr = 0; + } else { + Namespace *names = (Namespace *)label->value; + names->backr = names->forwr = 0; + names->file_list = current_file_list; + names->epoint = epoint; + } } else { label->constant = true; label->owner = true; @@ -4404,9 +4689,21 @@ val_destroy(&mfunc->v); goto breakerr; } + if (newlabel != NULL && ((Mfunc *)val)->retval) { + listing_equal(listing, newlabel->value); + } else { + listing_line_cut(listing, epoint.pos); + } val = mfunc_recurse(mfunc, (Namespace *)label->value, strength, &epoint); val_destroy(&mfunc->v); - } else val = macro_recurse(W_ENDM3, val, NULL, &epoint); + } else { /* segment */ + if (newlabel != NULL && ((Macro *)val)->retval) { + listing_equal(listing, newlabel->value); + } else { + listing_line_cut(listing, epoint.pos); + } + val = macro_recurse(W_ENDM3, val, NULL, &epoint); + } if (val != NULL) { if (newlabel != NULL) { newlabel->update_after = true; @@ -4421,8 +4718,9 @@ str_t opname; bool down; - if (newlabel != NULL && newlabel->value->obj == CODE_OBJ && labelname.len != 0 && labelname.data[0] != '_' && labelname.data[0] != '+' && labelname.data[0] != '-' && mycontext == current_context) {val_destroy(&cheap_context->v);cheap_context = ref_namespace(((Code *)newlabel->value)->names);} - opname.data = pline + lpoint.pos; opname.len = get_label(); + if (newlabel != NULL && newlabel->value->obj == CODE_OBJ && labelname.len != 0 && labelname.data[0] != '_' && labelname.data[0] != '+' && labelname.data[0] != '-') {val_destroy(&cheap_context->v);cheap_context = ref_namespace(((Code *)newlabel->value)->names);} + opname.data = pline + lpoint.pos; opname.len = get_label(opname.data); + lpoint.pos += opname.len; if (opname.len == 3 && (prm = lookup_opcode(opname.data)) >= 0) { Error *err; struct linepos_s oldlpoint; @@ -4453,7 +4751,7 @@ if (!get_exp(3, 0, 0, NULL)) goto breakerr; val = get_vals_addrlist(epoints); } - if (val->obj == TUPLE_OBJ || val->obj == LIST_OBJ) { + if (val->obj->iterable) { epoints[1] = epoints[0]; epoints[2] = epoints[0]; if (!instrecursion(val, prm, w, &epoint, epoints)) { @@ -4487,6 +4785,10 @@ const Type *obj = tmp2->value->obj; if (diagnostics.case_symbol && str_cmp(&opname, &tmp2->name) != 0) err_msg_symbol_case(&opname, tmp2, &epoint); if (obj == MACRO_OBJ || obj == SEGMENT_OBJ || obj == MFUNC_OBJ) { + if (diagnostics.macro_prefix) { + ignore(); + if (here() == 0 || here() == ';') err_msg_macro_prefix(&epoint); + } touch_label(tmp2); val = tmp2->value;goto as_macro; } @@ -4510,7 +4812,7 @@ } static void one_pass(int argc, char **argv, int opts, struct file_s *fin) { - static const str_t none_enc = {4, (const uint8_t *)"none"}; + static const str_t none_enc = {(const uint8_t *)"none", 4}; static struct linepos_s nopoint = {0, 0}; struct file_s *cfile; Obj *val; @@ -4519,7 +4821,7 @@ bool starexists; struct star_s *s; - fixeddig = true;constcreated = false;error_reset();random_reseed(&int_value[0]->v, NULL); + fixeddig = true;constcreated = false; fwcount = 0;error_reset();random_reseed(&int_value[0]->v, NULL); val_destroy(&root_section.address.mem->v); root_section.address.mem = new_memblocks(0, 0); if (diagnostics.optimize) cpu_opt_invalidate(); @@ -4527,7 +4829,7 @@ set_cpumode(arguments.cpumode); if (pass == 1 && i == opts - 1) constcreated = false; star = databank = dpage = strength = 0;longaccu = longindex = autosize = false;actual_encoding = new_encoding(&none_enc, &nopoint); allowslowbranch = true; longbranchasjmp = false; temporary_label_branch = 0; - reset_waitfor();lpoint.line = vline = 0;outputeor = 0; + reset_waitfor();lpoint.line = vline = 0;outputeor = 0; pline = (const uint8_t *)""; reset_context(); current_section = &root_section; current_address = &root_section.address; @@ -4563,6 +4865,7 @@ } } ref_labels(); + if (fwcount != 0) fixeddig = false; if (fixeddig) section_sizecheck(); /*garbage_collect();*/ } @@ -4631,19 +4934,24 @@ } if (labelprint(s, k != j)) break; } - if (arguments.make != NULL) makefile(argc - opts, argv + opts); + if (arguments.make != NULL) makefile(argc - opts, argv + opts, arguments.make_phony); if (error_serious()) {status();return EXIT_FAILURE;} - { - struct section_s *section = find_this_section(arguments.output.section); + for (j = 0; j < arguments.output_len; j++) { + const struct output_s *output = &arguments.output[j]; + struct section_s *section = find_this_section(output->section); if (section == NULL) { str_t sectionname; sectionname.data = pline; sectionname.len = lpoint.pos; err_msg2(ERROR__SECTION_ROOT, §ionname, &nopoint); + } else if (j == arguments.output_len - 1) { + output_mem(section->address.mem, output); } else { - output_mem(section->address.mem, &arguments.output); + Memblocks *tmp = copy_memblocks(section->address.mem); + output_mem(tmp, output); + val_destroy(&tmp->v); } } diff -Nru 64tass-1.54.1900/64tass.h 64tass-1.55.2200/64tass.h --- 64tass-1.54.1900/64tass.h 2019-02-17 21:46:22.000000000 +0000 +++ 64tass-1.55.2200/64tass.h 2020-04-07 21:18:24.000000000 +0000 @@ -1,5 +1,5 @@ /* - $Id: 64tass.h 1900 2019-02-17 21:46:21Z soci $ + $Id: 64tass.h 2200 2020-04-07 19:18:23Z soci $ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -23,10 +23,10 @@ #include "inttypes.h" #include "wait_e.h" #ifndef REVISION -#define REVISION "1900?" +#define REVISION "2200?" #endif #undef VERSION -#define VERSION "1.54." REVISION +#define VERSION "1.55." REVISION #define MAX_PASS 20 #define ignore() while(pline[lpoint.pos]==0x20 || pline[lpoint.pos]==0x09) lpoint.pos++ @@ -36,10 +36,9 @@ struct Listing; extern struct Listing *listing; -extern linepos_t poke_pos; extern address_t all_mem, all_mem2; extern unsigned int all_mem_bits; -extern unsigned int outputeor; +extern uint32_t outputeor; extern int temporary_label_branch; extern line_t vline; extern struct linepos_s lpoint; @@ -53,6 +52,6 @@ extern void new_waitfor(Wait_types, linepos_t); extern bool close_waitfor(Wait_types); extern struct Obj *compile(void); -extern FAST_CALL uint8_t *pokealloc(address_t); +extern FAST_CALL uint8_t *pokealloc(address_t, linepos_t); extern int main2(int *, char **[]); #endif diff -Nru 64tass-1.54.1900/addressobj.c 64tass-1.55.2200/addressobj.c --- 64tass-1.54.1900/addressobj.c 2019-01-31 18:49:50.000000000 +0000 +++ 64tass-1.55.2200/addressobj.c 2019-12-21 08:27:50.000000000 +0000 @@ -1,5 +1,5 @@ /* - $Id: addressobj.c 1857 2019-01-31 18:49:49Z soci $ + $Id: addressobj.c 2122 2019-12-21 06:27:50Z soci $ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -237,18 +237,16 @@ return false; } -static FAST_CALL Obj *address(Obj *o1, uint32_t *am) { +static FAST_CALL uint32_t address(const Obj *o1) { const Address *v1 = (Address *)o1; - atype_t type; Obj *v = v1->val; - v = v->obj->address(v, am); - type = v1->type; + uint32_t am = v->obj->address(v); + atype_t type = v1->type; while (type != A_NONE) { - *am <<= 4; + am <<= 4; type >>= 4; } - *am |= v1->type; - return v; + return am | v1->type; } static MUST_CHECK Error *ival(Obj *o1, ival_t *iv, unsigned int bits, linepos_t epoint) { @@ -281,6 +279,18 @@ return v->obj->uval2(v, uv, bits, epoint); } +static MUST_CHECK Error *iaddress(Obj *o1, ival_t *iv, unsigned int bits, linepos_t epoint) { + Address *v1 = (Address *)o1; + Obj *v = v1->val; + return v->obj->iaddress(v, iv, bits, epoint); +} + +static MUST_CHECK Error *uaddress(Obj *o1, uval_t *uv, unsigned int bits, linepos_t epoint) { + Address *v1 = (Address *)o1; + Obj *v = v1->val; + return v->obj->uaddress(v, uv, bits, epoint); +} + MUST_CHECK Obj *float_from_address(Address *v1, linepos_t epoint) { if (v1->type != A_NONE && v1->val != &none_value->v && v1->val->obj != ERROR_OBJ) { return (Obj *)new_error_conv(&v1->v, FLOAT_OBJ, epoint); @@ -319,14 +329,15 @@ return v->obj->sign(v, epoint); } -static MUST_CHECK Obj *function(Obj *o1, Func_types f, linepos_t epoint) { - Address *v1 = (Address *)o1; +static MUST_CHECK Obj *function(oper_t op) { + Address *v1 = (Address *)op->v2; Obj *v; if (v1->type != A_NONE && v1->val != &none_value->v && v1->val->obj != ERROR_OBJ) { - return DEFAULT_OBJ->function(o1, f, epoint); + return DEFAULT_OBJ->function(op); } - v = v1->val; - return v->obj->function(v, f, epoint); + op->v2 = v = v1->val; + op->inplace = op->inplace == &v1->v && v->refcount == 1 ? v : NULL; + return v->obj->function(op); } static MUST_CHECK Obj *calc1(oper_t op) { @@ -361,12 +372,12 @@ return obj_oper_error(op); } -static MUST_CHECK Obj *slice(Obj *o1, oper_t op, size_t indx) { - Obj *val = ((Address *)o1)->val; +static MUST_CHECK Obj *slice(oper_t op, size_t indx) { + Obj *val = ((Address *)op->v1)->val; if (val == &none_value->v || val->obj == ERROR_OBJ) { return val_reference(val); } - return DEFAULT_OBJ->slice(o1, op, indx); + return DEFAULT_OBJ->slice(op, indx); } static MUST_CHECK Obj *calc2(oper_t op) { @@ -529,27 +540,17 @@ case T_GAP: am = v2->type; switch (op->op->op) { - case O_CMP: - case O_EQ: - case O_NE: - case O_MIN: - case O_LT: - case O_LE: - case O_MAX: - case O_GT: - case O_GE: - if (am == A_NONE) { - op->v2 = v2->val; - op->inplace = NULL; - return t1->calc2(op); - } - break; default: if (am == A_NONE) { op->v2 = v2->val; op->inplace = NULL; return t1->calc2(op); } + break; + case O_MUL: + case O_OR: + case O_XOR: + case O_AND: if (check_addr2(am)) break; goto ok; case O_ADD: @@ -585,6 +586,8 @@ obj.ival = ival; obj.uval = uval; obj.uval2 = uval2; + obj.iaddress = iaddress; + obj.uaddress = uaddress; obj.sign = sign; obj.function = function; obj.calc1 = calc1; diff -Nru 64tass-1.54.1900/arguments.c 64tass-1.55.2200/arguments.c --- 64tass-1.54.1900/arguments.c 2018-12-09 17:44:10.000000000 +0000 +++ 64tass-1.55.2200/arguments.c 2020-04-07 21:18:24.000000000 +0000 @@ -1,5 +1,5 @@ /* - $Id: arguments.c 1687 2018-12-09 17:44:10Z soci $ + $Id: arguments.c 2200 2020-04-07 19:18:23Z soci $ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -30,7 +30,7 @@ struct arguments_s arguments = { true, /* warning */ - true, /* caret */ + CARET_ALWAYS,/* caret */ true, /* quiet */ false, /* to_ascii */ true, /* monitor */ @@ -39,13 +39,10 @@ false, /* longbranch */ false, /* tasmcomp */ false, /* verbose */ + false, /* make_phony */ 0x20, /* caseinsensitive */ - { /* output */ - "a.out", /* name */ - NULL, /* section */ - OUTPUT_CBM, /* mode */ - false /* longaddr */ - }, + NULL, /* output */ + 0, /* output_len */ &c6502, /* cpumode */ NULL, /* symbol_output */ 0, /* symbol_output_len */ @@ -61,8 +58,14 @@ false, /* optimize */ false, /* implied_reg */ true, /* jmp_bug */ - true, /* pc_wrap */ - true, /* mem_wrap */ + { + true, /* wrap-pc */ + true, /* wrap-mem */ + true, /* wrap-addr */ + true, /* wrap-dpage */ + true, /* wrap-bank0 */ + true, /* wrap-pbank */ + }, true, /* label_left */ false, /* branch_page */ true, /* deprecated */ @@ -86,7 +89,8 @@ false, /* long_branch */ false, /* altmode */ true, /* page */ - true /* type_mixing */ + false, /* macro_prefix */ + false /* float_round */ }; struct diagnostics_s diagnostic_errors = { @@ -95,8 +99,14 @@ false, /* optimize */ false, /* implied_reg */ false, /* jmp_bug */ - false, /* pc_wrap */ - false, /* mem_wrap */ + { + false, /* wrap-pc */ + false, /* wrap-mem */ + false, /* wrap-addr */ + false, /* wrap-dpage */ + false, /* wrap-bank0 */ + false, /* wrap-pbank */ + }, false, /* label_left */ false, /* branch_page */ false, /* deprecated */ @@ -120,7 +130,8 @@ false, /* long_branch */ false, /* altmode */ true, /* page */ - true /* type_mixing */ + false, /* macro_prefix */ + false /* float_round */ }; static struct diagnostics_s diagnostic_no_all; @@ -130,8 +141,14 @@ false, /* optimize */ true, /* implied_reg */ true, /* jmp_bug */ - true, /* pc_wrap */ - true, /* mem_wrap */ + { + true, /* wrap-pc */ + true, /* wrap-mem */ + true, /* wrap-addr */ + true, /* wrap-dpage */ + true, /* wrap-bank0 */ + true, /* wrap-pbank */ + }, true, /* label_left */ false, /* branch_page */ true, /* deprecated */ @@ -155,7 +172,8 @@ false, /* long_branch */ false, /* altmode */ true, /* page */ - true /* type_mixing */ + false, /* macro_prefix */ + true /* float_round */ }; static struct diagnostics_s diagnostic_no_error_all; @@ -165,8 +183,14 @@ true, /* optimize */ true, /* implied_reg */ true, /* jmp_bug */ - true, /* pc_wrap */ - true, /* mem_wrap */ + { + true, /* wrap-pc */ + true, /* wrap-mem */ + true, /* wrap-addr */ + true, /* wrap-dpage */ + true, /* wrap-bank0 */ + true, /* wrap-pbank */ + }, true, /* label_left */ true, /* branch_page */ true, /* deprecated */ @@ -190,7 +214,8 @@ true, /* long_branch */ true, /* altmode */ true, /* page */ - true /* type_mixing */ + true, /* macro_prefix */ + true /* float_round */ }; struct w_options_s { @@ -204,8 +229,14 @@ {"strict-bool", &diagnostics.strict_bool}, {"implied-reg", &diagnostics.implied_reg}, {"jmp-bug", &diagnostics.jmp_bug}, - {"pc-wrap", &diagnostics.pc_wrap}, - {"mem-wrap", &diagnostics.mem_wrap}, + {"pc-wrap", &diagnostics.wrap.pc}, + {"mem-wrap", &diagnostics.wrap.mem}, + {"wrap-pc", &diagnostics.wrap.pc}, + {"wrap-mem", &diagnostics.wrap.mem}, + {"wrap-addr", &diagnostics.wrap.addr}, + {"wrap-dpage", &diagnostics.wrap.dpage}, + {"wrap-bank0", &diagnostics.wrap.bank0}, + {"wrap-pbank", &diagnostics.wrap.pbank}, {"label-left", &diagnostics.label_left}, {"branch-page", &diagnostics.branch_page}, {"deprecated", &diagnostics.deprecated}, @@ -227,7 +258,8 @@ {"long-branch", &diagnostics.long_branch}, {"altmode", &diagnostics.altmode}, {"page", &diagnostics.page}, - {"type-mixing", &diagnostics.type_mixing}, + {"macro-prefix", &diagnostics.macro_prefix}, + {"float-round", &diagnostics.float_round}, {NULL, NULL} }; @@ -289,19 +321,26 @@ static const struct my_option long_options[] = { {"no-warn" , my_no_argument , NULL, 'w'}, + {"warn" , my_no_argument , NULL, 0x11f}, + {"no-quiet" , my_no_argument , NULL, 0x120}, {"quiet" , my_no_argument , NULL, 'q'}, {"nonlinear" , my_no_argument , NULL, 'n'}, {"nostart" , my_no_argument , NULL, 'b'}, {"flat" , my_no_argument , NULL, 'f'}, + {"no-long-address" , my_no_argument , NULL, 0x121}, {"long-address" , my_no_argument , NULL, 'X'}, {"atari-xex" , my_no_argument , NULL, 0x107}, {"apple-ii" , my_no_argument , NULL, 0x108}, {"intel-hex" , my_no_argument , NULL, 0x10e}, {"s-record" , my_no_argument , NULL, 0x10f}, {"cbm-prg" , my_no_argument , NULL, 0x10c}, + {"no-ascii" , my_no_argument , NULL, 0x11e}, {"ascii" , my_no_argument , NULL, 'a'}, + {"no-tasm-compatible",my_no_argument , NULL, 0x11d}, {"tasm-compatible" , my_no_argument , NULL, 'T'}, + {"no-case-sensitive", my_no_argument , NULL, 0x11c}, {"case-sensitive" , my_no_argument , NULL, 'C'}, + {"no-long-branch" , my_no_argument , NULL, 0x11b}, {"long-branch" , my_no_argument , NULL, 'B'}, {"m65xx" , my_no_argument , NULL, 0x101}, {"m6502" , my_no_argument , NULL, 'i'}, @@ -317,15 +356,27 @@ {"output" , my_required_argument, NULL, 'o'}, {"output-section" , my_required_argument, NULL, 0x114}, {"error" , my_required_argument, NULL, 'E'}, + {"normal-labels" , my_no_argument , NULL, 0x124}, + {"export-labels" , my_no_argument , NULL, 0x115}, {"vice-labels" , my_no_argument , NULL, 0x10b}, + {"vice-labels-numeric",my_no_argument , NULL, 0x123}, {"dump-labels" , my_no_argument , NULL, 0x10d}, {"labels-root" , my_required_argument, NULL, 0x113}, {"list" , my_required_argument, NULL, 'L'}, + {"dependencies" , my_required_argument, NULL, 'M'}, + {"no-make-phony" , my_no_argument , NULL, 0x126}, + {"make-phony" , my_no_argument , NULL, 0x125}, + {"no-verbose-list" , my_no_argument , NULL, 0x11a}, {"verbose-list" , my_no_argument , NULL, 0x110}, {"no-monitor" , my_no_argument , NULL, 'm'}, + {"monitor" , my_no_argument , NULL, 0x119}, {"no-source" , my_no_argument , NULL, 's'}, + {"source" , my_no_argument , NULL, 0x118}, + {"no-line-numbers" , my_no_argument , NULL, 0x117}, {"line-numbers" , my_no_argument , NULL, 0x112}, {"no-caret-diag" , my_no_argument , NULL, 0x10a}, + {"macro-caret-diag" , my_no_argument , NULL, 0x122}, + {"caret-diag" , my_no_argument , NULL, 0x116}, {"tab-size" , my_required_argument, NULL, 0x109}, {"version" , my_no_argument , NULL, 'V'}, {"usage" , my_no_argument , NULL, 0x102}, @@ -405,6 +456,29 @@ return (char *)data; } +static address_t get_all_mem2(void) { + size_t i; + bool tostdout = false; + address_t min = 0xffffffff; + for (i = 0; i < arguments.output_len; i++) { + const struct output_s *output = &arguments.output[i]; + switch (output->mode) { + case OUTPUT_RAW: + case OUTPUT_NONLINEAR: + case OUTPUT_CBM: min &= output->longaddr ? 0xffffff : 0xffff; break; + case OUTPUT_IHEX: + case OUTPUT_SREC: + case OUTPUT_FLAT: min &= 0xffffffff; break; + case OUTPUT_APPLE: + case OUTPUT_XEX: min &= 0xffff; break; + } + if (dash_name(output->name)) tostdout = true; + } + if (tostdout) arguments.quiet = false; + else setvbuf(stdout, NULL, _IOLBF, 1024); + return min; +} + int testarg(int *argc2, char **argv2[], struct file_s *fin) { int argc = *argc2; char **argv = *argv2; @@ -413,6 +487,7 @@ int max = 10; bool again; struct symbol_output_s symbol_output = { NULL, LABEL_64TASS, NULL }; + struct output_s output = { "a.out", NULL, OUTPUT_CBM, false }; do { int i; @@ -425,43 +500,59 @@ if (woption(my_optarg)) goto exit; break; case 'w':arguments.warning = false;break; + case 0x11f:arguments.warning = true;break; case 'q':arguments.quiet = false;break; - case 'X':arguments.output.longaddr = true;break; - case 'n':arguments.output.mode = OUTPUT_NONLINEAR;break; - case 0x107:arguments.output.mode = OUTPUT_XEX;break; - case 0x108:arguments.output.mode = OUTPUT_APPLE;break; - case 0x10e:arguments.output.mode = OUTPUT_IHEX;break; - case 0x10f:arguments.output.mode = OUTPUT_SREC;break; - case 0x10c:arguments.output.mode = OUTPUT_CBM;break; - case 'b':arguments.output.mode = OUTPUT_RAW;break; - case 'f':arguments.output.mode = OUTPUT_FLAT;break; + case 0x120:arguments.quiet = true;break; + case 'X':output.longaddr = true;break; + case 0x121:output.longaddr = false;break; + case 'n':output.mode = OUTPUT_NONLINEAR;break; + case 0x107:output.mode = OUTPUT_XEX;break; + case 0x108:output.mode = OUTPUT_APPLE;break; + case 0x10e:output.mode = OUTPUT_IHEX;break; + case 0x10f:output.mode = OUTPUT_SREC;break; + case 0x10c:output.mode = OUTPUT_CBM;break; + case 'b':output.mode = OUTPUT_RAW;break; + case 'f':output.mode = OUTPUT_FLAT;break; case 'a':arguments.to_ascii = true;break; + case 0x11e:arguments.to_ascii = false;break; case 'T':arguments.tasmcomp = true;break; - case 'o':arguments.output.name = my_optarg;break; - case 0x114: arguments.output.section = my_optarg; break; - case 0x10a:arguments.caret = false;break; + case 0x11d:arguments.tasmcomp = false;break; + case 'o': output.name = my_optarg; + arguments.output_len++; + arguments.output = (struct output_s *)realloc(arguments.output, arguments.output_len * sizeof *arguments.output); + if (arguments.output == NULL) err_msg_out_of_memory2(); + arguments.output[arguments.output_len - 1] = output; + output.section = NULL; + break; + case 0x114:output.section = my_optarg; break; + case 0x116:arguments.caret = CARET_ALWAYS;break; + case 0x122:arguments.caret = CARET_MACRO;break; + case 0x10a:arguments.caret = CARET_NEVER;break; case 'D': { size_t len = strlen(my_optarg) + 1; if (fin->lines >= max_lines) { max_lines += 1024; - if (/*max_lines < 1024 ||*/ max_lines > SIZE_MAX / sizeof *fin->line) err_msg_out_of_memory(); /* overflow */ - fin->line = (size_t *)reallocx(fin->line, max_lines * sizeof *fin->line); + if (/*max_lines < 1024 ||*/ max_lines > SIZE_MAX / sizeof *fin->line) err_msg_out_of_memory2(); /* overflow */ + fin->line = (size_t *)realloc(fin->line, max_lines * sizeof *fin->line); + if (fin->line == NULL) err_msg_out_of_memory2(); } fin->line[fin->lines++] = fp; - if (len < 1 || fp + len < len) err_msg_out_of_memory(); + if (len < 1 || fp + len < len) err_msg_out_of_memory2(); if (fp + len > fin->len) { fin->len = fp + len + 1024; - if (fin->len < 1024) err_msg_out_of_memory(); - fin->data = (uint8_t*)reallocx(fin->data, fin->len); + if (fin->len < 1024) err_msg_out_of_memory2(); + fin->data = (uint8_t*)realloc(fin->data, fin->len); + if (fin->data == NULL) err_msg_out_of_memory2(); } memcpy(fin->data + fp, my_optarg, len); fp += len; } break; case 'B': arguments.longbranch = true;break; + case 0x11b: arguments.longbranch = false;break; case 0x101: arguments.cpumode = &c6502;break; case 'i': arguments.cpumode = &c6502i;break; case 'c': arguments.cpumode = &c65c02;break; @@ -474,12 +565,15 @@ case 0x111: arguments.cpumode = &c4510;break; case 'l': symbol_output.name = my_optarg; arguments.symbol_output_len++; - arguments.symbol_output = (struct symbol_output_s *)reallocx(arguments.symbol_output, arguments.symbol_output_len * sizeof *arguments.symbol_output); + arguments.symbol_output = (struct symbol_output_s *)realloc(arguments.symbol_output, arguments.symbol_output_len * sizeof *arguments.symbol_output); + if (arguments.symbol_output == NULL) err_msg_out_of_memory2(); arguments.symbol_output[arguments.symbol_output_len - 1] = symbol_output; - symbol_output.mode = LABEL_64TASS; symbol_output.space = NULL; break; + case 0x124: symbol_output.mode = LABEL_64TASS; break; + case 0x115: symbol_output.mode = LABEL_EXPORT; break; case 0x10b: symbol_output.mode = LABEL_VICE; break; + case 0x123: symbol_output.mode = LABEL_VICE_NUMERIC; break; case 0x10d: symbol_output.mode = LABEL_DUMP; break; case 0x113: symbol_output.space = my_optarg; break; case 'E': arguments.error = my_optarg;break; @@ -487,10 +581,17 @@ case 'M': arguments.make = my_optarg;break; case 'I': include_list_add(my_optarg);break; case 'm': arguments.monitor = false;break; + case 0x119: arguments.monitor = true;break; case 's': arguments.source = false;break; + case 0x118: arguments.source = true;break; case 0x112: arguments.linenum = true;break; + case 0x117: arguments.linenum = false;break; case 'C': arguments.caseinsensitive = 0;break; + case 0x11c: arguments.caseinsensitive = 0x20;break; case 0x110: arguments.verbose = true;break; + case 0x11a: arguments.verbose = false;break; + case 0x125: arguments.make_phony = true;break; + case 0x126: arguments.make_phony = false;break; case 0x109: { char *s; @@ -506,11 +607,12 @@ " [--atari-xex] [--apple-ii] [--intel-hex] [--s-record] [--nonlinear]\n" " [--tasm-compatible] [--quiet] [--no-warn] [--long-address] [--m65c02]\n" " [--m6502] [--m65xx] [--m65dtv02] [--m65816] [--m65el02] [--mr65c02]\n" - " [--mw65c02] [--m65ce02] [--m4510] [--labels=] [--vice-labels]\n" + " [--mw65c02] [--m65ce02] [--m4510] [--labels=] [--normal-labels]\n" + " [--export-labels] [--vice-labels] [--vice-labels-numeric]\n" " [--dump-labels] [--list=] [--no-monitor] [--no-source]\n" - " [--line-numbers] [--tab-size=] [--verbose-list] [-W