add [] and ... operators

This commit is contained in:
icst 2024-06-20 23:40:41 -04:00
parent f6fb1a3cb5
commit 07c5f2fc15

31
lapis.c
View file

@ -78,9 +78,10 @@ void lapis_node_print(const lapis_node_t *nodes, size_t idx) {
if ( nodes[idx].rhs_idx != SIZE_MAX ) {
putchar(' ');
lapis_node_print(nodes, nodes[idx].rhs_idx);
if ( nodes[idx].value.str[0] == '[' ) putchar(' ');
}
if ( nodes[idx].value.type == LAPIS_TTYPE_OPER ) putchar(')');
if ( nodes[idx].value.type == LAPIS_TTYPE_OPER ) putchar(nodes[idx].value.str[0] == '[' ? ']' : ')');
}
size_t lapis_node_count(const lapis_node_t *nodes, size_t idx) {
@ -348,6 +349,7 @@ lapis_node_t *lapis_parse_expr(size_t *nnodes, FILE *f) {
(num_nodes++, nodes = realloc(nodes, num_nodes * sizeof(lapis_node_t)), nodes[num_nodes-1] = NODE)
int64_t paren_level = 0;
int64_t index_level = 0;
for (size_t n=0; n < ntokens; n++) {
@ -370,6 +372,10 @@ lapis_node_t *lapis_parse_expr(size_t *nnodes, FILE *f) {
oper_priorities[n] = 1;
oper_arg_form[n] = 3;
break;
case 1ul*'.'*'.'*'.':
oper_priorities[n] = 2;
oper_arg_form[n] = 1;
break;
case 1ul*'=':
case 1ul*'+'*'=':
case 1ul*'-'*'=':
@ -448,11 +454,11 @@ lapis_node_t *lapis_parse_expr(size_t *nnodes, FILE *f) {
if ( n > 0 && tokens[n-1].type == LAPIS_TTYPE_IDENT ) {
// treat the function identifier as a prefix operator
tokens[n-1].type = LAPIS_TTYPE_OPER;
oper_priorities[n-1] = 15 + paren_level * 16;
oper_priorities[n-1] = 15 + (paren_level + index_level) * 16;
oper_arg_form[n-1] = 2; // prefix-unary; takes only rhs
}
// clear the '(' as being an operator
oper_priorities[n] = -1;
oper_priorities[n] = -2;
tokens[n].type = LAPIS_TTYPE_NONE;
paren_level++;
break;
@ -462,13 +468,28 @@ lapis_node_t *lapis_parse_expr(size_t *nnodes, FILE *f) {
goto ERROR;
}
// clear the ')' as being an operator
oper_priorities[n] = -1;
oper_priorities[n] = -2;
tokens[n].type = LAPIS_TTYPE_NONE;
paren_level--;
break;
case 1ul*'[':
oper_priorities[n] = -1; /* == 15 once the level is incremented */
oper_arg_form[n] = 3;
index_level++;
break;
case 1ul*']':
if ( index_level == 0 ) {
fprintf(stderr, "ERROR(%d): unexpected ']'\n", __LINE__);
goto ERROR;
}
// clear the ']' as being an operator
oper_priorities[n] = -2;
tokens[n].type = LAPIS_TTYPE_NONE;
index_level--;
break;
}
if ( oper_priorities[n] != -1 ) oper_priorities[n] += paren_level * 16;
if ( oper_priorities[n] != -2 ) oper_priorities[n] += (paren_level + index_level) * 16;
}
while (1) {