pseudo opcodes like !by, !wo, !tx and friends now accept lists

git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@240 4df02467-bbd4-4a76-a152-e7ce94205b78
This commit is contained in:
marcobaye 2020-06-18 23:38:24 +00:00
parent eca73fb335
commit c3e651f4ca
9 changed files with 79 additions and 25 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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!
*/

View File

@ -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!
}
}

View File

@ -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

View File

@ -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;

View File

@ -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