mirror of
https://github.com/uffejakobsen/acme.git
synced 2025-02-19 09:31:42 +00:00
more work on special operators
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@168 4df02467-bbd4-4a76-a152-e7ce94205b78
This commit is contained in:
parent
5ba17ccfc4
commit
665c579470
76
src/alu.c
76
src/alu.c
@ -109,8 +109,7 @@ static struct op ops_end_of_expr = {0, OPGROUP_SPECIAL, OPID_END_EXPRESSION, "en
|
|||||||
static struct op ops_start_of_expr = {2, OPGROUP_SPECIAL, OPID_START_EXPRESSION, "start of expression" };
|
static struct op ops_start_of_expr = {2, OPGROUP_SPECIAL, OPID_START_EXPRESSION, "start of expression" };
|
||||||
static struct op ops_closing = {4, OPGROUP_SPECIAL, OPID_CLOSING, "right parenthesis" };
|
static struct op ops_closing = {4, OPGROUP_SPECIAL, OPID_CLOSING, "right parenthesis" };
|
||||||
static struct op ops_opening = {6, OPGROUP_SPECIAL, OPID_OPENING, "left parenthesis" };
|
static struct op ops_opening = {6, OPGROUP_SPECIAL, OPID_OPENING, "left parenthesis" };
|
||||||
//static struct op ops_closeindex = {8, OPGROUP_SPECIAL, OPID_CLOSEINDEX, "right bracket" };
|
//static struct op ops_openindex = {10, OPGROUP_SPECIAL, OPID_OPENINDEX, "open index" };
|
||||||
//static struct op ops_openindex = {10, OPGROUP_SPECIAL, OPID_OPENINDEX, "left bracket" };
|
|
||||||
static struct op ops_or = {16, OPGROUP_DYADIC, OPID_OR, "logical or" };
|
static struct op ops_or = {16, OPGROUP_DYADIC, OPID_OR, "logical or" };
|
||||||
static struct op ops_eor = {18, OPGROUP_DYADIC, OPID_EOR, "exclusive or" }; // FIXME - remove
|
static struct op ops_eor = {18, OPGROUP_DYADIC, OPID_EOR, "exclusive or" }; // FIXME - remove
|
||||||
static struct op ops_xor = {18, OPGROUP_DYADIC, OPID_XOR, "exclusive or" };
|
static struct op ops_xor = {18, OPGROUP_DYADIC, OPID_XOR, "exclusive or" };
|
||||||
@ -1559,19 +1558,19 @@ struct type type_list = {
|
|||||||
|
|
||||||
|
|
||||||
// handler for special operators like parentheses and start/end of expression:
|
// handler for special operators like parentheses and start/end of expression:
|
||||||
// returns whether caller should just return without fixing stack (because this fn has fixed it)
|
// returns whether caller should remove operator from stack
|
||||||
static boolean handle_special_operator(struct expression *expression, enum op_id previous, enum op_id current)
|
static boolean handle_special_operator(struct expression *expression, enum op_id previous, enum op_id current)
|
||||||
{
|
{
|
||||||
// when this gets called, "previous" is a special operator, while "current" could be anything with a lower priority
|
// when this gets called, "previous" is a special operator, and "current" has a lower priority, so it is also a special operator
|
||||||
switch (previous) {
|
switch (previous) {
|
||||||
case OPID_START_EXPRESSION:
|
case OPID_START_EXPRESSION:
|
||||||
// the only operator with a lower priority than this
|
// the only operator with a lower priority than this
|
||||||
// "start-of-expression" operator is "end-of-expression",
|
// "start-of-expression" operator is "end-of-expression",
|
||||||
// therefore we know we are done.
|
// therefore we know we are done.
|
||||||
// don't touch "is_parenthesized", because start/end are obviously not "real" operators
|
// don't touch "is_parenthesized", because start/end are obviously not "real" operators
|
||||||
--op_sp; // decrement operator stack pointer
|
|
||||||
alu_state = STATE_END; // done
|
alu_state = STATE_END; // done
|
||||||
break;
|
return TRUE; // caller can remove this operator
|
||||||
|
|
||||||
case OPID_OPENING:
|
case OPID_OPENING:
|
||||||
expression->is_parenthesized = TRUE; // found parentheses. if this is not the outermost level, the outermost level will fix this flag later on.
|
expression->is_parenthesized = TRUE; // found parentheses. if this is not the outermost level, the outermost level will fix this flag later on.
|
||||||
// check current operator
|
// check current operator
|
||||||
@ -1579,49 +1578,74 @@ static boolean handle_special_operator(struct expression *expression, enum op_id
|
|||||||
case OPID_CLOSING: // matching parentheses
|
case OPID_CLOSING: // matching parentheses
|
||||||
op_sp -= 2; // remove both of them
|
op_sp -= 2; // remove both of them
|
||||||
alu_state = STATE_EXPECT_DYADIC_OP;
|
alu_state = STATE_EXPECT_DYADIC_OP;
|
||||||
break;
|
return FALSE; // we fixed the stack ourselves, so caller shouldn't touch it
|
||||||
|
|
||||||
case OPID_END_EXPRESSION: // unmatched parenthesis, as in "lda ($80,x)"
|
case OPID_END_EXPRESSION: // unmatched parenthesis, as in "lda ($80,x)"
|
||||||
++(expression->open_parentheses); // count
|
++(expression->open_parentheses); // count
|
||||||
return FALSE; // caller can remove operator from stack
|
return TRUE; // caller can remove "OPID_OPENING" operator from stack
|
||||||
|
|
||||||
default:
|
default:
|
||||||
Bug_found("StrangeParenthesis", current);
|
Bug_found("StrangeParenthesis", current);
|
||||||
}
|
}
|
||||||
break;
|
break; // this is unreachable
|
||||||
case OPID_CLOSING:
|
case OPID_CLOSING:
|
||||||
// this op should have been removed upon handling the preceding OPID_OPENING, so it must be an extra:
|
// this op should have been removed upon handling the preceding OPID_OPENING, so it must be an extra:
|
||||||
Throw_error("Too many ')'.");
|
Throw_error("Too many ')'.");
|
||||||
alu_state = STATE_ERROR;
|
alu_state = STATE_ERROR;
|
||||||
break;
|
return TRUE; // caller can remove operator from stack
|
||||||
/*
|
/*
|
||||||
case OPID_OPENINDEX:
|
case OPID_OPENINDEX:
|
||||||
// check current operator
|
// check current operator
|
||||||
switch (current) {
|
switch (current) {
|
||||||
case OPID_CLOSEINDEX: // matching brackets
|
|
||||||
op_sp -= 2; // remove both of them
|
|
||||||
alu_state = STATE_EXPECT_DYADIC_OP;
|
|
||||||
break;
|
|
||||||
case OPID_CLOSING: // [...)
|
|
||||||
case OPID_END_EXPRESSION: // [...
|
case OPID_END_EXPRESSION: // [...
|
||||||
|
if (GotByte == ']') {
|
||||||
|
GetByte(); // eat ']'
|
||||||
|
op_sp -= 2; // remove both OPENINDEX and END_EXPRESSION
|
||||||
|
alu_state = STATE_EXPECT_DYADIC_OP;
|
||||||
|
return FALSE; // we fixed the stack ourselves, so caller shouldn't touch it
|
||||||
|
}
|
||||||
|
*/ /*FALLTHROUGH*/
|
||||||
|
/* case OPID_CLOSING: // [...)
|
||||||
Throw_error("Unmatched '['."); // FIXME - add to docs!
|
Throw_error("Unmatched '['."); // FIXME - add to docs!
|
||||||
alu_state = STATE_ERROR;
|
alu_state = STATE_ERROR;
|
||||||
break;
|
return TRUE; // caller can remove operator from stack
|
||||||
case OPID_OPENING: canthappen
|
|
||||||
case OPID_START_EXPRESSION: canthappen
|
case OPID_OPENING: // cannot happen
|
||||||
|
case OPID_START_EXPRESSION: // cannot happen
|
||||||
default:
|
default:
|
||||||
Bug_found("StrangeBracket", current);
|
Bug_found("StrangeBracket", current);
|
||||||
}
|
}
|
||||||
break;
|
break; // this is unreachable
|
||||||
case OPID_CLOSEINDEX:
|
case OPID_LISTBUILDER:
|
||||||
// this op should have been removed upon handling the preceding OPID_OPENINDEX, so it must be an extra:
|
// check current operator
|
||||||
Throw_error("Too many ']'.");
|
switch (current) {
|
||||||
|
case OPID_END_EXPRESSION:
|
||||||
|
if (GotByte == ',') {
|
||||||
|
GetByte(); // eat ','
|
||||||
|
list.append(previous_arg, current_arg);
|
||||||
|
decrement arg stack pointer
|
||||||
|
alu_state = STATE_EXPECT_ARG_OR_MONADIC_OP;
|
||||||
|
return FALSE; // we fixed the stack ourselves, so caller shouldn't touch it
|
||||||
|
}
|
||||||
|
if (GotByte == ']') {
|
||||||
|
GetByte(); // eat ']'
|
||||||
|
list.append(previous_arg, current_arg);
|
||||||
|
decrement arg stack pointer
|
||||||
|
alu_state = STATE_EXPECT_DYADIC_OP;
|
||||||
|
return TRUE; // caller can remove LISTBUILDER op from stack
|
||||||
|
}
|
||||||
|
Throw_error("Unterminated list"); // FIXME - add to docs!
|
||||||
alu_state = STATE_ERROR;
|
alu_state = STATE_ERROR;
|
||||||
break;
|
return TRUE; // caller can remove LISTBUILDER operator from stack
|
||||||
*/
|
|
||||||
default:
|
default:
|
||||||
|
Bug_found("StrangeBracket2", current);
|
||||||
|
}
|
||||||
|
break; // this is unreachable
|
||||||
|
*/ default:
|
||||||
Bug_found("IllegalOperatorIdS", previous);
|
Bug_found("IllegalOperatorIdS", previous);
|
||||||
}
|
}
|
||||||
return TRUE; // stack is done, so caller shouldn't touch it
|
// this is unreachable
|
||||||
|
return FALSE; // stack is done, so caller shouldn't touch it
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1675,7 +1699,7 @@ static void try_to_reduce_stacks(struct expression *expression)
|
|||||||
expression->is_parenthesized = FALSE;
|
expression->is_parenthesized = FALSE;
|
||||||
break;
|
break;
|
||||||
case OPGROUP_SPECIAL: // special (pseudo) operators
|
case OPGROUP_SPECIAL: // special (pseudo) operators
|
||||||
if (handle_special_operator(expression, previous_op->id, current_op->id))
|
if (!handle_special_operator(expression, previous_op->id, current_op->id))
|
||||||
return; // called fn has fixed the stack, so we return and don't touch it
|
return; // called fn has fixed the stack, so we return and don't touch it
|
||||||
|
|
||||||
// both monadics and dyadics clear "is_parenthesized", but here we don't touch it!
|
// both monadics and dyadics clear "is_parenthesized", but here we don't touch it!
|
||||||
|
Loading…
x
Reference in New Issue
Block a user