Allow unary +.

This commit is contained in:
Lawrence Kesteloot 2018-08-05 17:20:24 -07:00
parent 8fa3789ade
commit 1eccf0b089

50
main.c
View File

@ -80,6 +80,7 @@ uint8_t title_length = 9;
#define OP_DIV 0xCB #define OP_DIV 0xCB
#define OP_NEG 0xDD #define OP_NEG 0xDD
#define OP_EXP 0xEE #define OP_EXP 0xEE
#define OP_NO_OP 0xFC // Never on the stack.
#define OP_CLOSE_PARENS 0xFD // Never on the stack. #define OP_CLOSE_PARENS 0xFD // Never on the stack.
#define OP_OPEN_PARENS 0xFE // Ignore precedence. #define OP_OPEN_PARENS 0xFE // Ignore precedence.
#define OP_INVALID 0xFF #define OP_INVALID 0xFF
@ -560,7 +561,7 @@ static void push_operator_stack(uint8_t op) {
*/ */
static uint8_t *compile_expression(uint8_t *s) { static uint8_t *compile_expression(uint8_t *s) {
char have_value_in_ax = 0; char have_value_in_ax = 0;
uint8_t expect_unary_minus = 1; // Expect unary minus at start of expression. uint8_t expect_unary = 1; // Expect unary operator at start of expression.
while (1) { while (1) {
if (IS_DIGIT(*s)) { if (IS_DIGIT(*s)) {
@ -573,8 +574,8 @@ static uint8_t *compile_expression(uint8_t *s) {
compile_load_ax(parse_uint16(&s)); compile_load_ax(parse_uint16(&s));
have_value_in_ax = 1; have_value_in_ax = 1;
// Expect binary minus after operand. // Expect binary operator after operand.
expect_unary_minus = 0; expect_unary = 0;
} else if (IS_FIRST_VARIABLE_LETTER(*s)) { } else if (IS_FIRST_VARIABLE_LETTER(*s)) {
// Variable reference. // Variable reference.
uint8_t var = find_variable(&s); uint8_t var = find_variable(&s);
@ -599,16 +600,16 @@ static uint8_t *compile_expression(uint8_t *s) {
} }
have_value_in_ax = 1; have_value_in_ax = 1;
// Expect binary minus after operand. // Expect binary operator after operand.
expect_unary_minus = 0; expect_unary = 0;
} else { } else {
// Check if it's an operator. // Check if it's an operator.
uint8_t op = OP_INVALID; uint8_t op = OP_INVALID;
if (*s == T_PLUS) { if (*s == T_PLUS) {
op = OP_ADD; op = expect_unary ? OP_NO_OP : OP_ADD;
} else if (*s == T_MINUS) { } else if (*s == T_MINUS) {
op = expect_unary_minus ? OP_NEG : OP_SUB; op = expect_unary ? OP_NEG : OP_SUB;
} else if (*s == T_ASTERISK) { } else if (*s == T_ASTERISK) {
op = OP_MULT; op = OP_MULT;
} else if (*s == T_SLASH) { } else if (*s == T_SLASH) {
@ -618,7 +619,12 @@ static uint8_t *compile_expression(uint8_t *s) {
} else if (*s == T_OR) { } else if (*s == T_OR) {
op = OP_OR; op = OP_OR;
} else if (*s == T_NOT) { } else if (*s == T_NOT) {
op = OP_NOT; if (expect_unary) {
op = OP_NOT;
} else {
// TODO generate syntax error.
break;
}
} else if (*s == T_EQUAL) { } else if (*s == T_EQUAL) {
if (s[1] == T_LESS_THAN) { if (s[1] == T_LESS_THAN) {
s += 1; s += 1;
@ -659,6 +665,7 @@ static uint8_t *compile_expression(uint8_t *s) {
pop_operator_stack(); pop_operator_stack();
} }
if (g_op_stack_size == 0) { if (g_op_stack_size == 0) {
// TODO we should generate a syntax error here.
print("Extra close parenthesis\n"); print("Extra close parenthesis\n");
} else { } else {
// Pop open parenthesis. // Pop open parenthesis.
@ -666,13 +673,21 @@ static uint8_t *compile_expression(uint8_t *s) {
} }
} }
// Expect unary minus after operators or open parenthesis. Expect // Check that we didn't have an inappropriate unary operator.
// binary minus after close parenthesis. if (expect_unary && op != OP_NO_OP && op != OP_NEG && op != OP_NOT &&
expect_unary_minus = op != OP_CLOSE_PARENS; op != OP_OPEN_PARENS) {
// TODO we should generate a syntax error here.
break;
}
// Expect unary operator after operators or open parenthesis. Expect
// binary operator after close parenthesis.
expect_unary = op != OP_CLOSE_PARENS;
if (op != OP_INVALID) { if (op != OP_INVALID) {
s += 1; s += 1;
if (op != OP_CLOSE_PARENS) { if (op != OP_CLOSE_PARENS && op != OP_NO_OP) {
push_operator_stack(op); push_operator_stack(op);
} }
} else { } else {
@ -685,6 +700,7 @@ static uint8_t *compile_expression(uint8_t *s) {
// Empty the operator stack. // Empty the operator stack.
while (g_op_stack_size > 0) { while (g_op_stack_size > 0) {
if (g_op_stack[g_op_stack_size - 1] == OP_OPEN_PARENS) { if (g_op_stack[g_op_stack_size - 1] == OP_OPEN_PARENS) {
// TODO we should generate a syntax error here.
print("Extra open parenthesis\n"); print("Extra open parenthesis\n");
} }
pop_operator_stack(); pop_operator_stack();
@ -1353,16 +1369,6 @@ int16_t main(void)
{ {
int16_t blink; int16_t blink;
/*
// For testing generated code. TODO remove
{
int16_t a, b, c;
b = 5;
c = 6;
a = b && c;
}
*/
// Clear stored program. // Clear stored program.
new_statement(); new_statement();