mirror of
https://github.com/uffejakobsen/acme.git
synced 2024-08-31 23:30:32 +00:00
strings now support "+", "=" and "!=" operators
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@192 4df02467-bbd4-4a76-a152-e7ce94205b78
This commit is contained in:
parent
bc0cd5b8ea
commit
78e7c32507
97
src/alu.c
97
src/alu.c
@ -42,14 +42,6 @@ static const char exception_div_by_zero[] = "Division by zero.";
|
|||||||
static const char exception_no_value[] = "No value given.";
|
static const char exception_no_value[] = "No value given.";
|
||||||
static const char exception_paren_open[] = "Too many '('.";
|
static const char exception_paren_open[] = "Too many '('.";
|
||||||
static const char exception_not_number[] = "Expression did not return a number.";
|
static const char exception_not_number[] = "Expression did not return a number.";
|
||||||
#define s_or (s_eor + 1) // Yes, I know I'm sick
|
|
||||||
#define s_xor (s_scrxor + 3) // Yes, I know I'm sick
|
|
||||||
static const char s_arcsin[] = "arcsin";
|
|
||||||
#define s_sin (s_arcsin + 3) // Yes, I know I'm sick
|
|
||||||
static const char s_arccos[] = "arccos";
|
|
||||||
#define s_cos (s_arccos + 3) // Yes, I know I'm sick
|
|
||||||
static const char s_arctan[] = "arctan";
|
|
||||||
#define s_tan (s_arctan + 3) // Yes, I know I'm sick
|
|
||||||
|
|
||||||
enum op_group {
|
enum op_group {
|
||||||
OPGROUP_SPECIAL, // start/end of expression, and parentheses
|
OPGROUP_SPECIAL, // start/end of expression, and parentheses
|
||||||
@ -196,9 +188,9 @@ static struct ronode op_list[] = {
|
|||||||
PREDEFNODE("div", &ops_intdiv),
|
PREDEFNODE("div", &ops_intdiv),
|
||||||
PREDEFNODE("mod", &ops_modulo),
|
PREDEFNODE("mod", &ops_modulo),
|
||||||
PREDEFNODE(s_and, &ops_and),
|
PREDEFNODE(s_and, &ops_and),
|
||||||
PREDEFNODE(s_or, &ops_or),
|
PREDEFNODE("or", &ops_or),
|
||||||
PREDEFNODE(s_eor, &ops_eor), // FIXME - remove
|
PREDEFNODE(s_eor, &ops_eor), // FIXME - remove
|
||||||
PREDEFLAST(s_xor, &ops_xor),
|
PREDEFLAST("xor", &ops_xor),
|
||||||
// ^^^^ this marks the last element
|
// ^^^^ this marks the last element
|
||||||
};
|
};
|
||||||
static struct ronode *function_tree = NULL; // tree to hold functions
|
static struct ronode *function_tree = NULL; // tree to hold functions
|
||||||
@ -208,12 +200,12 @@ static struct ronode function_list[] = {
|
|||||||
PREDEFNODE("int", &ops_int),
|
PREDEFNODE("int", &ops_int),
|
||||||
PREDEFNODE("float", &ops_float),
|
PREDEFNODE("float", &ops_float),
|
||||||
PREDEFNODE("len", &ops_len),
|
PREDEFNODE("len", &ops_len),
|
||||||
PREDEFNODE(s_arcsin, &ops_arcsin),
|
PREDEFNODE("arcsin", &ops_arcsin),
|
||||||
PREDEFNODE(s_arccos, &ops_arccos),
|
PREDEFNODE("arccos", &ops_arccos),
|
||||||
PREDEFNODE(s_arctan, &ops_arctan),
|
PREDEFNODE("arctan", &ops_arctan),
|
||||||
PREDEFNODE(s_sin, &ops_sin),
|
PREDEFNODE("sin", &ops_sin),
|
||||||
PREDEFNODE(s_cos, &ops_cos),
|
PREDEFNODE("cos", &ops_cos),
|
||||||
PREDEFLAST(s_tan, &ops_tan),
|
PREDEFLAST("tan", &ops_tan),
|
||||||
// ^^^^ this marks the last element
|
// ^^^^ this marks the last element
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -387,11 +379,10 @@ static void parse_program_counter(void) // Now GotByte = "*"
|
|||||||
|
|
||||||
|
|
||||||
// make new string object
|
// make new string object
|
||||||
static void string_init_string(struct object *self, const char *data, int len)
|
static void string_prepare_string(struct object *self, int len)
|
||||||
{
|
{
|
||||||
self->type = &type_string;
|
self->type = &type_string;
|
||||||
self->u.string = safe_malloc(sizeof(*(self->u.string)) + len);
|
self->u.string = safe_malloc(sizeof(*(self->u.string)) + len);
|
||||||
memcpy(self->u.string->payload, data, len);
|
|
||||||
self->u.string->payload[len] = 0; // terminate, to facilitate string_print()
|
self->u.string->payload[len] = 0; // terminate, to facilitate string_print()
|
||||||
self->u.string->length = len; // length does not include the added terminator
|
self->u.string->length = len; // length does not include the added terminator
|
||||||
self->u.string->refs = 1;
|
self->u.string->refs = 1;
|
||||||
@ -417,7 +408,9 @@ static void parse_quoted(char closing_quote)
|
|||||||
// with backslash escaping, ' is for characters and " is for strings:
|
// with backslash escaping, ' is for characters and " is for strings:
|
||||||
if ((closing_quote == '"') && (config.backslash_escaping)) {
|
if ((closing_quote == '"') && (config.backslash_escaping)) {
|
||||||
// string //////////////////////////////////
|
// string //////////////////////////////////
|
||||||
string_init_string(&arg_stack[arg_sp++], GLOBALDYNABUF_CURRENT, GlobalDynaBuf->size); // create string object and put on arg stack
|
string_prepare_string(&arg_stack[arg_sp], GlobalDynaBuf->size); // create string object and put on arg stack
|
||||||
|
memcpy(arg_stack[arg_sp].u.string->payload, GLOBALDYNABUF_CURRENT, GlobalDynaBuf->size); // copy payload
|
||||||
|
++arg_sp;
|
||||||
} else {
|
} else {
|
||||||
// single character ////////////////////////
|
// single character ////////////////////////
|
||||||
// too short?
|
// too short?
|
||||||
@ -1050,6 +1043,15 @@ static void unsupported_operation(struct object *optional, struct op *op, struct
|
|||||||
|
|
||||||
// int/float
|
// int/float
|
||||||
|
|
||||||
|
// int:
|
||||||
|
// create byte-sized int object (for comparison results, converted characters, ...)
|
||||||
|
static void int_create_byte(struct object *self, intval_t byte)
|
||||||
|
{
|
||||||
|
self->type = &type_int;
|
||||||
|
self->u.number.flags = NUMBER_IS_DEFINED | NUMBER_FITS_BYTE;
|
||||||
|
self->u.number.val.intval = byte;
|
||||||
|
self->u.number.addr_refs = 0;
|
||||||
|
}
|
||||||
|
|
||||||
// int:
|
// int:
|
||||||
// convert to float
|
// convert to float
|
||||||
@ -1642,24 +1644,65 @@ static void string_handle_dyadic_operator(struct object *self, struct op *op, st
|
|||||||
int length;
|
int length;
|
||||||
int index;
|
int index;
|
||||||
intval_t character;
|
intval_t character;
|
||||||
|
struct string *arthur,
|
||||||
|
*ford;
|
||||||
|
|
||||||
length = self->u.string->length;
|
length = self->u.string->length;
|
||||||
switch (op->id) {
|
switch (op->id) {
|
||||||
case OPID_ATINDEX:
|
case OPID_ATINDEX:
|
||||||
if (get_valid_index(&index, length, self, op, other))
|
if (get_valid_index(&index, length, self, op, other))
|
||||||
return; // error
|
return; // error has already been reported
|
||||||
|
|
||||||
character = (intval_t) (unsigned char) encoding_encode_char(self->u.string->payload[index]);
|
character = (intval_t) (unsigned char) encoding_encode_char(self->u.string->payload[index]);
|
||||||
self->u.string->refs--; // FIXME - call a function for this...
|
self->u.string->refs--; // FIXME - call a function for this...
|
||||||
self->type = &type_int;
|
int_create_byte(self, character);
|
||||||
self->u.number.flags = NUMBER_IS_DEFINED | NUMBER_FITS_BYTE;
|
return; // ok
|
||||||
self->u.number.val.intval = character;
|
|
||||||
self->u.number.addr_refs = 0;
|
case OPID_ADD:
|
||||||
break;
|
if (other->type != &type_string)
|
||||||
//case OPID_ADD: TODO?
|
break; // complain
|
||||||
|
arthur = self->u.string;
|
||||||
|
ford = other->u.string;
|
||||||
|
string_prepare_string(self, arthur->length + ford->length); // create string object and put on arg stack
|
||||||
|
memcpy(self->u.string->payload, arthur->payload, arthur->length);
|
||||||
|
memcpy(self->u.string->payload + arthur->length, ford->payload, ford->length);
|
||||||
|
arthur->refs--; // FIXME - call a function for this...
|
||||||
|
ford->refs--; // FIXME - call a function for this...
|
||||||
|
return;
|
||||||
|
|
||||||
|
case OPID_EQUALS:
|
||||||
|
if (other->type != &type_string)
|
||||||
|
break; // complain
|
||||||
|
arthur = self->u.string;
|
||||||
|
ford = other->u.string;
|
||||||
|
if (arthur->length != ford->length) {
|
||||||
|
int_create_byte(self, FALSE);
|
||||||
|
} else {
|
||||||
|
int_create_byte(self, !memcmp(arthur->payload, ford->payload, arthur->length));
|
||||||
|
}
|
||||||
|
arthur->refs--; // FIXME - call a function for this...
|
||||||
|
ford->refs--; // FIXME - call a function for this...
|
||||||
|
return;
|
||||||
|
|
||||||
|
case OPID_NOTEQUAL:
|
||||||
|
if (other->type != &type_string)
|
||||||
|
break; // complain
|
||||||
|
arthur = self->u.string;
|
||||||
|
ford = other->u.string;
|
||||||
|
if (arthur->length != ford->length) {
|
||||||
|
int_create_byte(self, TRUE);
|
||||||
|
} else {
|
||||||
|
int_create_byte(self, !!memcmp(arthur->payload, ford->payload, arthur->length));
|
||||||
|
}
|
||||||
|
arthur->refs--; // FIXME - call a function for this...
|
||||||
|
ford->refs--; // FIXME - call a function for this...
|
||||||
|
return;
|
||||||
|
|
||||||
|
//case ...: // maybe comparisons?
|
||||||
default:
|
default:
|
||||||
unsupported_operation(self, op, other);
|
break; // complain
|
||||||
}
|
}
|
||||||
|
unsupported_operation(self, op, other);
|
||||||
}
|
}
|
||||||
|
|
||||||
// int/float:
|
// int/float:
|
||||||
|
Loading…
Reference in New Issue
Block a user