mirror of
https://github.com/uffejakobsen/acme.git
synced 2024-11-22 03:30:46 +00:00
refactoring, about to remove "try to reduce stacks" state
git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@237 4df02467-bbd4-4a76-a152-e7ce94205b78
This commit is contained in:
parent
c2978f7e15
commit
326f36fd4f
38
src/alu.c
38
src/alu.c
@ -52,9 +52,9 @@ enum op_id {
|
||||
// special (pseudo) operators:
|
||||
OPID_END_EXPRESSION, // end of expression (quasi-dyadic)
|
||||
OPID_START_EXPRESSION, // start of expression
|
||||
OPID_LEFT_PARENTHESIS, // (v '(' starts subexpression (quasi-monadic)
|
||||
OPID_SUBEXPR_PAREN, // (v '(' starts subexpression (quasi-monadic)
|
||||
OPID_START_LIST, // [1,2] '[' starts non-empty list literal (quasi-monadic, followed by dyadic OPID_LIST_APPEND)
|
||||
OPID_START_INDEX, // v[ '[' starts subexpression (quasi-monadic, after dyadic OPID_ATINDEX)
|
||||
OPID_SUBEXPR_BRACKET, // v[ '[' starts subexpression (quasi-monadic, after dyadic OPID_ATINDEX)
|
||||
// monadic operators (including functions):
|
||||
OPID_NOT, // !v NOT v bit-wise NOT
|
||||
OPID_NEGATE, // -v negation
|
||||
@ -103,9 +103,9 @@ struct op {
|
||||
};
|
||||
static struct op ops_end_expression = {0, OPGROUP_SPECIAL, OPID_END_EXPRESSION, "end of expression" };
|
||||
static struct op ops_start_expression = {2, OPGROUP_SPECIAL, OPID_START_EXPRESSION, "start of expression" };
|
||||
static struct op ops_left_parenthesis = {4, OPGROUP_SPECIAL, OPID_LEFT_PARENTHESIS, "left parenthesis" };
|
||||
static struct op ops_subexpr_paren = {4, OPGROUP_SPECIAL, OPID_SUBEXPR_PAREN, "left parenthesis" };
|
||||
static struct op ops_start_list = {6, OPGROUP_SPECIAL, OPID_START_LIST, "start list" };
|
||||
static struct op ops_start_index = {8, OPGROUP_SPECIAL, OPID_START_INDEX, "open index" };
|
||||
static struct op ops_subexpr_bracket = {8, OPGROUP_SPECIAL, OPID_SUBEXPR_BRACKET, "open index" };
|
||||
static struct op ops_list_append = {14, OPGROUP_DYADIC, OPID_LIST_APPEND, "append to list" };
|
||||
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
|
||||
@ -173,7 +173,7 @@ static int arg_sp;
|
||||
enum alu_state {
|
||||
STATE_EXPECT_ARG_OR_MONADIC_OP,
|
||||
STATE_EXPECT_DYADIC_OP,
|
||||
STATE_TRY_TO_REDUCE_STACKS,
|
||||
STATE_TRY_TO_REDUCE_STACKS, // FIXME - get rid of this state
|
||||
STATE_MAX_GO_ON, // "border value" to find the stoppers:
|
||||
STATE_ERROR, // error has occurred
|
||||
STATE_END // standard end
|
||||
@ -803,7 +803,8 @@ static boolean expect_argument_or_monadic_operator(void)
|
||||
if (GotByte == ']') {
|
||||
// list literal is empty, so we're basically done
|
||||
GetByte();
|
||||
alu_state = STATE_EXPECT_DYADIC_OP;
|
||||
goto now_expect_dyadic_op;
|
||||
|
||||
} else {
|
||||
// non-empty list literal
|
||||
PUSH_OP(&ops_start_list); // quasi-monadic "start of list", makes sure earlier ops do not process empty list
|
||||
@ -814,7 +815,7 @@ static boolean expect_argument_or_monadic_operator(void)
|
||||
break;//goto done;
|
||||
|
||||
case '(': // left parenthesis
|
||||
op = &ops_left_parenthesis;
|
||||
op = &ops_subexpr_paren;
|
||||
goto get_byte_and_push_monadic;
|
||||
|
||||
// arguments (state changes to ExpectDyadic)
|
||||
@ -1004,7 +1005,8 @@ static void expect_dyadic_operator(void)
|
||||
case '[': // indexing operator
|
||||
GetByte(); // eat char
|
||||
PUSH_OP(&ops_atindex); // first put high-priority dyadic on stack,
|
||||
PUSH_OP(&ops_start_index); // then low-priority special ops_start_index
|
||||
// FIXME - reduce stacks!
|
||||
PUSH_OP(&ops_subexpr_bracket); // then low-priority special ops_subexpr_bracket
|
||||
// FIXME! this would work reliably if "atindex" had the highest priority.
|
||||
// but function calls have higher priority than indexing:
|
||||
// fn(a+b)[c] -> fn d [c] -> e [c], but the code above would return fn(d[c]) instead
|
||||
@ -2171,7 +2173,7 @@ static boolean handle_special_operator(struct expression *expression, enum op_id
|
||||
alu_state = STATE_END; // done
|
||||
return TRUE; // caller can remove this operator (we are done, so not really needed, but there are sanity checks for stack pointers)
|
||||
|
||||
case OPID_LEFT_PARENTHESIS:
|
||||
case OPID_SUBEXPR_PAREN:
|
||||
expression->is_parenthesized = TRUE; // found parentheses. if this is not the outermost level, the outermost level will fix this flag later on.
|
||||
if (current != OPID_END_EXPRESSION)
|
||||
Bug_found("StrangeParenthesis", current);
|
||||
@ -2184,7 +2186,7 @@ static boolean handle_special_operator(struct expression *expression, enum op_id
|
||||
}
|
||||
// unmatched parenthesis, as in "lda ($80,x)"
|
||||
++(expression->open_parentheses); // count
|
||||
return TRUE; // caller can remove "OPID_LEFT_PARENTHESIS" operator from stack
|
||||
return TRUE; // caller can remove "SUBEXPR_PAREN" operator from stack
|
||||
|
||||
case OPID_START_LIST:
|
||||
if (current != OPID_END_EXPRESSION)
|
||||
@ -2203,20 +2205,20 @@ static boolean handle_special_operator(struct expression *expression, enum op_id
|
||||
}
|
||||
Throw_error("Unterminated list.");
|
||||
alu_state = STATE_ERROR;
|
||||
return TRUE; // caller can remove LISTBUILDER operator from stack
|
||||
return TRUE; // caller can remove START_LIST operator from stack
|
||||
|
||||
case OPID_START_INDEX:
|
||||
case OPID_SUBEXPR_BRACKET:
|
||||
if (current != OPID_END_EXPRESSION)
|
||||
Bug_found("StrangeIndexBracket", current);
|
||||
if (GotByte == ']') {
|
||||
GetByte(); // eat ']'
|
||||
op_sp -= 2; // remove both OPENINDEX and END_EXPRESSION
|
||||
op_sp -= 2; // remove both SUBEXPR_BRACKET and END_EXPRESSION
|
||||
alu_state = STATE_EXPECT_DYADIC_OP;
|
||||
return FALSE; // we fixed the stack ourselves, so caller shouldn't touch it
|
||||
}
|
||||
Throw_error("Unterminated index spec.");
|
||||
alu_state = STATE_ERROR;
|
||||
return TRUE; // caller can remove OPID_START_INDEX operator from stack
|
||||
return TRUE; // caller can remove SUBEXPR_BRACKET operator from stack
|
||||
|
||||
default:
|
||||
Bug_found("IllegalOperatorId", previous);
|
||||
@ -2228,11 +2230,14 @@ static boolean handle_special_operator(struct expression *expression, enum op_id
|
||||
|
||||
// Try to reduce stacks by performing high-priority operations
|
||||
// (if the previous operator has a higher priority than the current one, do it)
|
||||
// FIXME - rename to "push_dyadic_op" and add operator arg?
|
||||
static void try_to_reduce_stacks(struct expression *expression)
|
||||
{
|
||||
struct op *previous_op;
|
||||
struct op *current_op;
|
||||
|
||||
while (alu_state == STATE_TRY_TO_REDUCE_STACKS) {
|
||||
|
||||
if (op_sp < 2) {
|
||||
// we only have one operator, which must be "start of expression",
|
||||
// so there isn't anything left to do, so go on trying to parse the expression
|
||||
@ -2282,19 +2287,20 @@ static void try_to_reduce_stacks(struct expression *expression)
|
||||
break;
|
||||
case OPGROUP_SPECIAL: // special (pseudo) operators
|
||||
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
|
||||
continue; // called fn has fixed the stack, so we don't touch it
|
||||
|
||||
// both monadics and dyadics clear "is_parenthesized", but here we don't touch it!
|
||||
break;
|
||||
default:
|
||||
Bug_found("IllegalOperatorGroup", previous_op->group);
|
||||
}
|
||||
// shared endings for "we did the operation indicated by previous operator":
|
||||
// shared endings for "we did the operation indicated by previous operator":
|
||||
// fix stack:
|
||||
// remove previous operator and shift down current one
|
||||
// CAUTION - fiddling with our local copies like "previous_op = current_op" is not enough... ;)
|
||||
op_stack[op_sp - 2] = op_stack[op_sp - 1];
|
||||
--op_sp; // decrement operator stack pointer
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user