diff --git a/lapis.c b/lapis.c index 66d1aae..0f0822a 100644 --- a/lapis.c +++ b/lapis.c @@ -5,6 +5,13 @@ #include #include +struct lapis_node_s; + +typedef struct { + size_t nnodes; + struct lapis_node_s *nodes; +} lapis_stmt_t; + typedef struct { enum lapis_ttype { LAPIS_TTYPE_NONE, @@ -14,9 +21,14 @@ typedef struct { LAPIS_TTYPE_INT, LAPIS_TTYPE_BOOL, LAPIS_TTYPE_OPER, + LAPIS_TTYPE_STMT_LIST, } type; union { + struct { + size_t nstmts; + lapis_stmt_t *stmts; + }; struct { size_t len; char * str; @@ -54,6 +66,13 @@ void lapis_node_print(const lapis_node_t *nodes, size_t idx) { case LAPIS_TTYPE_INT: printf("%ld", nodes[idx].value.i64); break; + case LAPIS_TTYPE_STMT_LIST: + for (size_t n=0; n < nodes[idx].value.nstmts; n++) { + lapis_node_print(nodes[idx].value.stmts[n].nodes, nodes[idx].value.stmts[n].nnodes-1); + fputs("; ", stdout); + } + fputs("} ", stdout); + break; } if ( nodes[idx].rhs_idx != SIZE_MAX ) { @@ -82,6 +101,8 @@ void lapis_token_free(lapis_token_t *token) { } } +lapis_node_t *lapis_parse_expr(size_t *nnodes, FILE *f); + lapis_token_t *lapis_parse_tokens(size_t *ntokens, FILE *f) { size_t num_tokens = 0; @@ -91,7 +112,62 @@ lapis_token_t *lapis_parse_tokens(size_t *ntokens, FILE *f) { _Bool end_of_expression = false; int c; - while ( (c = fgetc(f)) != EOF && !end_of_expression ) { + while ( !end_of_expression && ((c = fgetc(f)) != EOF) ) { + + if ( c == '{' ) { + + size_t nstmts = 0; + lapis_stmt_t *stmts = NULL; + + while (1) { + + //puts("++++++++++"); + size_t nnodes; + lapis_node_t *nodes = lapis_parse_expr(&nnodes, f); + //puts("----------"); + + if ( nodes == 0 ) break; + + //printf("%lu: ", nstmts); + //lapis_node_print(nodes, nnodes-1); + //putchar('\n'); + + nstmts++; + stmts = realloc(stmts, nstmts * sizeof(lapis_stmt_t)); + + if ( stmts == NULL ) { + fprintf(stderr, "ERROR[%d]: realloc failed!\n", __LINE__); + goto ERROR; + } + + stmts[nstmts-1] = (lapis_stmt_t) { .nnodes = nnodes, .nodes = nodes }; + } + + if ( nstmts > 0 ) { + + tokens = realloc(tokens, (num_tokens + 2) * sizeof(lapis_token_t)); + if ( tokens == NULL ) { + fprintf(stderr, "ERROR [%s:%d]: realloc failed!\n", __func__, __LINE__); + goto ERROR; + } + + // need an operator to connect the statement list to the outer statement + tokens[num_tokens].type = LAPIS_TTYPE_OPER; + tokens[num_tokens].str = strdup("{"); + tokens[num_tokens].len = 1; + + num_tokens++; + + // need an operator to connect the statement list to the outer statement + tokens[num_tokens].type = LAPIS_TTYPE_STMT_LIST; + tokens[num_tokens].stmts = stmts; + tokens[num_tokens].nstmts = nstmts; + + num_tokens++; + } + + c = ' '; + } _Bool in_escape = false; @@ -108,9 +184,9 @@ lapis_token_t *lapis_parse_tokens(size_t *ntokens, FILE *f) { if ( c == EOF ) break; } - if ( c == ';' || (!in_escape && c == '\n') ) { + if ( c == ';' || c == '}' || (!in_escape && c == '\n') ) { + if ( num_tokens || c == '}' ) end_of_expression = true; c = ' '; - if ( num_tokens ) end_of_expression = true; } enum lapis_ttype cur_ttype; @@ -290,6 +366,7 @@ lapis_node_t *lapis_parse_expr(size_t *nnodes, FILE *f) { fputs("'\n", stderr); goto ERROR; case 1ul*',': + case 1ul*'{': oper_priorities[n] = 1; oper_arg_form[n] = 3; break;