aboutsummaryrefslogtreecommitdiff
path: root/src/parser.cpp
diff options
context:
space:
mode:
authorgingerBill <bill@gingerbill.org>2021-10-18 16:52:19 +0100
committergingerBill <bill@gingerbill.org>2021-10-18 16:52:19 +0100
commit4c655865e5d9af83a98c137609b01972f4e51beb (patch)
tree2963a8f22c8e2a54dc7f081834b72a6081568842 /src/parser.cpp
parent7aac8df2f2ddb89ffa8b1d096f41d89e689a2293 (diff)
Begin work on matrix type
Diffstat (limited to 'src/parser.cpp')
-rw-r--r--src/parser.cpp54
1 files changed, 53 insertions, 1 deletions
diff --git a/src/parser.cpp b/src/parser.cpp
index 716986b5d..499bd337b 100644
--- a/src/parser.cpp
+++ b/src/parser.cpp
@@ -159,6 +159,11 @@ Ast *clone_ast(Ast *node) {
n->IndexExpr.expr = clone_ast(n->IndexExpr.expr);
n->IndexExpr.index = clone_ast(n->IndexExpr.index);
break;
+ case Ast_MatrixIndexExpr:
+ n->MatrixIndexExpr.expr = clone_ast(n->MatrixIndexExpr.expr);
+ n->MatrixIndexExpr.row_index = clone_ast(n->MatrixIndexExpr.row_index);
+ n->MatrixIndexExpr.column_index = clone_ast(n->MatrixIndexExpr.column_index);
+ break;
case Ast_DerefExpr:
n->DerefExpr.expr = clone_ast(n->DerefExpr.expr);
break;
@@ -371,6 +376,11 @@ Ast *clone_ast(Ast *node) {
n->MapType.key = clone_ast(n->MapType.key);
n->MapType.value = clone_ast(n->MapType.value);
break;
+ case Ast_MatrixType:
+ n->MatrixType.row_count = clone_ast(n->MatrixType.row_count);
+ n->MatrixType.column_count = clone_ast(n->MatrixType.column_count);
+ n->MatrixType.elem = clone_ast(n->MatrixType.elem);
+ break;
}
return n;
@@ -574,6 +584,15 @@ Ast *ast_deref_expr(AstFile *f, Ast *expr, Token op) {
}
+Ast *ast_matrix_index_expr(AstFile *f, Ast *expr, Token open, Token close, Token interval, Ast *row, Ast *column) {
+ Ast *result = alloc_ast_node(f, Ast_MatrixIndexExpr);
+ result->MatrixIndexExpr.expr = expr;
+ result->MatrixIndexExpr.row_index = row;
+ result->MatrixIndexExpr.column_index = column;
+ result->MatrixIndexExpr.open = open;
+ result->MatrixIndexExpr.close = close;
+ return result;
+}
Ast *ast_ident(AstFile *f, Token token) {
@@ -1066,6 +1085,14 @@ Ast *ast_map_type(AstFile *f, Token token, Ast *key, Ast *value) {
return result;
}
+Ast *ast_matrix_type(AstFile *f, Token token, Ast *row_count, Ast *column_count, Ast *elem) {
+ Ast *result = alloc_ast_node(f, Ast_MatrixType);
+ result->MatrixType.token = token;
+ result->MatrixType.row_count = row_count;
+ result->MatrixType.column_count = column_count;
+ result->MatrixType.elem = elem;
+ return result;
+}
Ast *ast_foreign_block_decl(AstFile *f, Token token, Ast *foreign_library, Ast *body,
CommentGroup *docs) {
@@ -2214,6 +2241,19 @@ Ast *parse_operand(AstFile *f, bool lhs) {
count_expr = parse_expr(f, false);
f->expr_level--;
}
+ if (allow_token(f, Token_Semicolon)) {
+ Ast *row_count = count_expr;
+ Ast *column_count = nullptr;
+
+ f->expr_level++;
+ column_count = parse_expr(f, false);
+ f->expr_level--;
+
+ expect_token(f, Token_CloseBracket);
+
+ return ast_matrix_type(f, token, row_count, column_count, parse_type(f));
+ }
+
expect_token(f, Token_CloseBracket);
return ast_array_type(f, token, count_expr, parse_type(f));
} break;
@@ -2676,6 +2716,11 @@ Ast *parse_atom_expr(AstFile *f, Ast *operand, bool lhs) {
case Token_RangeHalf:
syntax_error(f->curr_token, "Expected a colon, not a range");
/* fallthrough */
+ case Token_Semicolon: // matrix index
+ if (f->curr_token.kind == Token_Semicolon && f->curr_token.string == "\n") {
+ syntax_error(f->curr_token, "Expected a ';', not a newline");
+ }
+ /* fallthrough */
case Token_Colon:
interval = advance_token(f);
is_interval = true;
@@ -2691,7 +2736,14 @@ Ast *parse_atom_expr(AstFile *f, Ast *operand, bool lhs) {
close = expect_token(f, Token_CloseBracket);
if (is_interval) {
- operand = ast_slice_expr(f, operand, open, close, interval, indices[0], indices[1]);
+ if (interval.kind == Token_Semicolon) {
+ if (indices[0] == nullptr || indices[1] == nullptr) {
+ syntax_error(open, "Matrix index expressions require both row and column indices");
+ }
+ operand = ast_matrix_index_expr(f, operand, open, close, interval, indices[0], indices[1]);
+ } else {
+ operand = ast_slice_expr(f, operand, open, close, interval, indices[0], indices[1]);
+ }
} else {
operand = ast_index_expr(f, operand, indices[0], open, close);
}