mirror of
https://github.com/uffejakobsen/acme.git
synced 2024-11-25 23:49:25 +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:
|
// special (pseudo) operators:
|
||||||
OPID_END_EXPRESSION, // end of expression (quasi-dyadic)
|
OPID_END_EXPRESSION, // end of expression (quasi-dyadic)
|
||||||
OPID_START_EXPRESSION, // start of expression
|
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_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):
|
// monadic operators (including functions):
|
||||||
OPID_NOT, // !v NOT v bit-wise NOT
|
OPID_NOT, // !v NOT v bit-wise NOT
|
||||||
OPID_NEGATE, // -v negation
|
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_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_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_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_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_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
|
||||||
@ -173,7 +173,7 @@ static int arg_sp;
|
|||||||
enum alu_state {
|
enum alu_state {
|
||||||
STATE_EXPECT_ARG_OR_MONADIC_OP,
|
STATE_EXPECT_ARG_OR_MONADIC_OP,
|
||||||
STATE_EXPECT_DYADIC_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_MAX_GO_ON, // "border value" to find the stoppers:
|
||||||
STATE_ERROR, // error has occurred
|
STATE_ERROR, // error has occurred
|
||||||
STATE_END // standard end
|
STATE_END // standard end
|
||||||
@ -803,7 +803,8 @@ static boolean expect_argument_or_monadic_operator(void)
|
|||||||
if (GotByte == ']') {
|
if (GotByte == ']') {
|
||||||
// list literal is empty, so we're basically done
|
// list literal is empty, so we're basically done
|
||||||
GetByte();
|
GetByte();
|
||||||
alu_state = STATE_EXPECT_DYADIC_OP;
|
goto now_expect_dyadic_op;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// non-empty list literal
|
// non-empty list literal
|
||||||
PUSH_OP(&ops_start_list); // quasi-monadic "start of list", makes sure earlier ops do not process empty list
|
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;
|
break;//goto done;
|
||||||
|
|
||||||
case '(': // left parenthesis
|
case '(': // left parenthesis
|
||||||
op = &ops_left_parenthesis;
|
op = &ops_subexpr_paren;
|
||||||
goto get_byte_and_push_monadic;
|
goto get_byte_and_push_monadic;
|
||||||
|
|
||||||
// arguments (state changes to ExpectDyadic)
|
// arguments (state changes to ExpectDyadic)
|
||||||
@ -1004,7 +1005,8 @@ static void expect_dyadic_operator(void)
|
|||||||
case '[': // indexing operator
|
case '[': // indexing operator
|
||||||
GetByte(); // eat char
|
GetByte(); // eat char
|
||||||
PUSH_OP(&ops_atindex); // first put high-priority dyadic on stack,
|
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.
|
// FIXME! this would work reliably if "atindex" had the highest priority.
|
||||||
// but function calls have higher priority than indexing:
|
// 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
|
// 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
|
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)
|
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.
|
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)
|
if (current != OPID_END_EXPRESSION)
|
||||||
Bug_found("StrangeParenthesis", current);
|
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)"
|
// unmatched parenthesis, as in "lda ($80,x)"
|
||||||
++(expression->open_parentheses); // count
|
++(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:
|
case OPID_START_LIST:
|
||||||
if (current != OPID_END_EXPRESSION)
|
if (current != OPID_END_EXPRESSION)
|
||||||
@ -2203,20 +2205,20 @@ static boolean handle_special_operator(struct expression *expression, enum op_id
|
|||||||
}
|
}
|
||||||
Throw_error("Unterminated list.");
|
Throw_error("Unterminated list.");
|
||||||
alu_state = STATE_ERROR;
|
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)
|
if (current != OPID_END_EXPRESSION)
|
||||||
Bug_found("StrangeIndexBracket", current);
|
Bug_found("StrangeIndexBracket", current);
|
||||||
if (GotByte == ']') {
|
if (GotByte == ']') {
|
||||||
GetByte(); // eat ']'
|
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;
|
alu_state = STATE_EXPECT_DYADIC_OP;
|
||||||
return FALSE; // we fixed the stack ourselves, so caller shouldn't touch it
|
return FALSE; // we fixed the stack ourselves, so caller shouldn't touch it
|
||||||
}
|
}
|
||||||
Throw_error("Unterminated index spec.");
|
Throw_error("Unterminated index spec.");
|
||||||
alu_state = STATE_ERROR;
|
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:
|
default:
|
||||||
Bug_found("IllegalOperatorId", previous);
|
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
|
// Try to reduce stacks by performing high-priority operations
|
||||||
// (if the previous operator has a higher priority than the current one, do it)
|
// (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)
|
static void try_to_reduce_stacks(struct expression *expression)
|
||||||
{
|
{
|
||||||
struct op *previous_op;
|
struct op *previous_op;
|
||||||
struct op *current_op;
|
struct op *current_op;
|
||||||
|
|
||||||
|
while (alu_state == STATE_TRY_TO_REDUCE_STACKS) {
|
||||||
|
|
||||||
if (op_sp < 2) {
|
if (op_sp < 2) {
|
||||||
// we only have one operator, which must be "start of expression",
|
// 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
|
// 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;
|
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
|
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!
|
// both monadics and dyadics clear "is_parenthesized", but here we don't touch it!
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
Bug_found("IllegalOperatorGroup", previous_op->group);
|
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:
|
// fix stack:
|
||||||
// remove previous operator and shift down current one
|
// remove previous operator and shift down current one
|
||||||
// CAUTION - fiddling with our local copies like "previous_op = current_op" is not enough... ;)
|
// 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_stack[op_sp - 2] = op_stack[op_sp - 1];
|
||||||
--op_sp; // decrement operator stack pointer
|
--op_sp; // decrement operator stack pointer
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user