add [] and ... operators
This commit is contained in:
parent
f6fb1a3cb5
commit
07c5f2fc15
1 changed files with 26 additions and 5 deletions
31
lapis.c
31
lapis.c
|
@ -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) {
|
||||
|
|
Loading…
Reference in a new issue