diff --git a/src/Makefile b/src/Makefile index a8c1152..426488a 100644 --- a/src/Makefile +++ b/src/Makefile @@ -32,7 +32,7 @@ encoding.o: config.h alu.h acme.h dynabuf.h global.h output.h input.h tree.h enc flow.o: config.h acme.h alu.h dynabuf.h global.h input.h mnemo.h symbol.h tree.h flow.h flow.c -global.o: config.h platform.h acme.h cpu.h input.h macro.h pseudoopcodes.h section.h symbol.h global.h global.c +global.o: config.h platform.h acme.h cpu.h encoding.h input.h macro.h pseudoopcodes.h section.h symbol.h global.h global.c input.o: config.h alu.h dynabuf.h global.h section.h symbol.h tree.h input.h input.c diff --git a/src/Makefile.dos b/src/Makefile.dos index 7cf90af..3ac7b96 100644 --- a/src/Makefile.dos +++ b/src/Makefile.dos @@ -32,7 +32,7 @@ encoding.o: config.h alu.h acme.h dynabuf.h global.h output.h input.h tree.h enc flow.o: config.h acme.h alu.h dynabuf.h global.h input.h mnemo.h symbol.h tree.h flow.h flow.c -global.o: config.h platform.h acme.h cpu.h input.h macro.h pseudoopcodes.h section.h symbol.h global.h global.c +global.o: config.h platform.h acme.h cpu.h encoding.h input.h macro.h pseudoopcodes.h section.h symbol.h global.h global.c input.o: config.h alu.h dynabuf.h global.h section.h symbol.h tree.h input.h input.c diff --git a/src/Makefile.mingw b/src/Makefile.mingw index 83442e2..2a40dac 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -35,7 +35,7 @@ encoding.o: config.h alu.h acme.h dynabuf.h global.h output.h input.h tree.h enc flow.o: config.h acme.h alu.h dynabuf.h global.h input.h mnemo.h symbol.h tree.h flow.h flow.c -global.o: config.h platform.h acme.h cpu.h input.h macro.h pseudoopcodes.h section.h symbol.h global.h global.c +global.o: config.h platform.h acme.h cpu.h encoding.h input.h macro.h pseudoopcodes.h section.h symbol.h global.h global.c input.o: config.h alu.h dynabuf.h global.h section.h symbol.h tree.h input.h input.c diff --git a/src/Makefile.riscos b/src/Makefile.riscos index 881a2a1..a34c33e 100644 --- a/src/Makefile.riscos +++ b/src/Makefile.riscos @@ -30,7 +30,7 @@ encoding.o: config.h alu.h acme.h dynabuf.h global.h output.h input.h tree.h enc flow.o: config.h acme.h alu.h dynabuf.h global.h input.h mnemo.h symbol.h tree.h flow.h flow.c -global.o: config.h platform.h acme.h cpu.h input.h macro.h pseudoopcodes.h section.h symbol.h global.h global.c +global.o: config.h platform.h acme.h cpu.h encoding.h input.h macro.h pseudoopcodes.h section.h symbol.h global.h global.c input.o: config.h alu.h dynabuf.h global.h section.h symbol.h tree.h input.h input.c diff --git a/src/alu.c b/src/alu.c index 22c14ff..9321c3d 100644 --- a/src/alu.c +++ b/src/alu.c @@ -155,8 +155,6 @@ static struct op ops_arcsin = {42, OPGROUP_MONADIC, OPID_ARCSIN, "arcsin()" }; static struct op ops_arccos = {42, OPGROUP_MONADIC, OPID_ARCCOS, "arccos()" }; static struct op ops_arctan = {42, OPGROUP_MONADIC, OPID_ARCTAN, "arctan()" }; static struct op ops_len = {42, OPGROUP_MONADIC, OPID_LEN, "len()" }; -// CAUTION: when adding a function that returns something indexable, fix the code inserting ops_atindex! -// FIXME - no, do this asap because of test program ;) // variables @@ -2511,6 +2509,9 @@ void ALU_any_result(struct object *result) pseudoopcodes.c !set don't care when throwing user-specified errors don't care + iterator for !by, !wo, etc. needvalue! + byte values in !raw, !tx, etc. needvalue! + !scrxor needvalue! symbol.c explicit symbol definition don't care @@ -2535,9 +2536,6 @@ void ALU_defined_int(struct number *intresult) void ALU_any_int(intval_t *target) pseudoopcodes.c !xor needvalue! - iterator for !by, !wo, etc. needvalue! - byte values in !raw, !tx, etc. needvalue! - !scrxor needvalue! !fill (2nd arg) needvalue! !align (3rd arg) needvalue! */ diff --git a/src/global.c b/src/global.c index c859622..b14acbe 100644 --- a/src/global.c +++ b/src/global.c @@ -17,6 +17,7 @@ #include "alu.h" #include "cpu.h" #include "dynabuf.h" +#include "encoding.h" #include "input.h" #include "macro.h" #include "output.h" @@ -473,3 +474,42 @@ void Bug_found(const char *message, int code) fprintf(stderr, "(0x%x:)", code); Throw_serious_error(message); } + + +// insert object (in case of list, will iterate/recurse until done) +void output_object(struct object *object, struct iter_context *iter) +{ + struct listitem *item; + int length; + char *read; + + if (object->type == &type_number) { + if (object->u.number.ntype == NUMTYPE_UNDEFINED) + iter->fn(0); + else if (object->u.number.ntype == NUMTYPE_INT) + iter->fn(object->u.number.val.intval); + else if (object->u.number.ntype == NUMTYPE_FLOAT) + iter->fn(object->u.number.val.fpval); + else + Bug_found("IllegalNumberType7", object->u.number.ntype); // FIXME - add to docs! + } else if (object->type == &type_list) { + // iterate over list + item = object->u.listhead->next; + while (item != object->u.listhead) { + output_object(&item->payload, iter); + item = item->next; + } + } else if (object->type == &type_string) { + // iterate over string + read = object->u.string->payload; + length = object->u.string->length; + if (iter->accept_long_strings || (length < 2)) { + while (length--) + iter->fn(iter->stringxor ^ encoding_encode_char(*(read++))); + } else { + Throw_error("There's more than one character."); // see alu.c for the original of this error + } + } else { + Bug_found("IllegalObjectType9", 0); // FIXME - add to docs! + } +} diff --git a/src/global.h b/src/global.h index dee8a78..cc7bec2 100644 --- a/src/global.h +++ b/src/global.h @@ -168,6 +168,13 @@ extern void Throw_error(const char *msg); extern void Throw_serious_error(const char *msg); // handle bugs extern void Bug_found(const char *msg, int code); +// insert object (in case of list, will iterate/recurse until done) +struct iter_context { + void (*fn)(intval_t); // output function + boolean accept_long_strings; // if FALSE, only 1-char-strings work + char stringxor; // for !scrxor, 0 otherwise +}; +extern void output_object(struct object *object, struct iter_context *iter); #endif diff --git a/src/pseudoopcodes.c b/src/pseudoopcodes.c index 13ea9c1..2a33829 100644 --- a/src/pseudoopcodes.c +++ b/src/pseudoopcodes.c @@ -181,11 +181,15 @@ static enum eos po_to(void) // helper function for !8, !16, !24 and !32 pseudo opcodes static enum eos iterate(void (*fn)(intval_t)) { - intval_t value; + struct iter_context iter; + struct object object; + iter.fn = fn; + iter.accept_long_strings = FALSE; + iter.stringxor = 0; do { - ALU_any_int(&value); - fn(value); + ALU_any_result(&object); + output_object(&object, &iter); } while (Input_accept_comma()); return ENSURE_EOS; } @@ -381,13 +385,21 @@ static enum eos po_convtab(void) static enum eos encode_string(const struct encoder *inner_encoder, char xor) { const struct encoder *outer_encoder = encoder_current; // buffer encoder - int offset; - intval_t value; + struct iter_context iter; + struct object object; + iter.fn = output_8; + iter.accept_long_strings = TRUE; + iter.stringxor = xor; // make given encoder the current one (for ALU-parsed values) encoder_current = inner_encoder; do { - if (GotByte == '"') { // FIXME - add "&& (config.wanted_version < VER_BACKSLASHESCAPING)", otherwise stuff like "string"[index] will not work + // we need to keep the old string handler code, because if user selects + // older dialect, the new code will complain about string lengths > 1! + if ((GotByte == '"') && (config.wanted_version < VER_BACKSLASHESCAPING)) { + // the old way of handling string literals: + int offset; + DYNABUF_CLEAR(GlobalDynaBuf); if (Input_quoted_to_dynabuf('"')) return SKIP_REMAINDER; // unterminated or escaping error @@ -402,14 +414,11 @@ static enum eos encode_string(const struct encoder *inner_encoder, char xor) for (offset = 0; offset < GlobalDynaBuf->size; ++offset) output_8(xor ^ encoding_encode_char(GLOBALDYNABUF_CURRENT[offset])); } else { - // Parse value. No problems with single characters - // because the current encoding is - // temporarily set to the given one. - ALU_any_int(&value); - output_8(value); - // FIXME - call ALU_any_result(FLOAT2INT) instead and support lists and strings: - // for lists, call some list_iter() fn to handle components - // for strings, do not forget to XOR! + // handle everything else (also strings in newer dialects): + // parse value. no problems with single characters because the + // current encoding is temporarily set to the given one. + ALU_any_result(&object); + output_object(&object, &iter); } } while (Input_accept_comma()); encoder_current = outer_encoder; // reactivate buffered encoder @@ -1044,7 +1053,7 @@ static enum eos po_for(void) // now GotByte = illegal char // now GotByte = illegal char loop.force_bit = Input_get_force_bit(); // skips spaces after - loop.symbol = symbol_find(scope); // FIXME - if type is not NULL, complain if not number! + loop.symbol = symbol_find(scope); // if not number, error will be reported on first assignment if (!Input_accept_comma()) { Throw_error(exception_syntax); return SKIP_REMAINDER; diff --git a/src/version.h b/src/version.h index 4805c51..823e255 100644 --- a/src/version.h +++ b/src/version.h @@ -9,7 +9,7 @@ #define RELEASE "0.96.5" // update before release FIXME #define CODENAME "Fenchurch" // update before release -#define CHANGE_DATE "18 June" // update before release FIXME +#define CHANGE_DATE "19 June" // update before release FIXME #define CHANGE_YEAR "2020" // update before release //#define HOME_PAGE "http://home.pages.de/~mac_bacon/smorbrod/acme/" #define HOME_PAGE "http://sourceforge.net/p/acme-crossass/" // FIXME