mirror of
https://github.com/odin-lang/Odin.git
synced 2025-12-30 09:54:45 +00:00
Slices and slice expressions
This commit is contained in:
@@ -47,6 +47,7 @@ AstNode__ExpressionBegin,
|
||||
AstNode_CallExpression,
|
||||
AstNode_SelectorExpression,
|
||||
AstNode_IndexExpression,
|
||||
AstNode_SliceExpression,
|
||||
AstNode_CastExpression,
|
||||
AstNode_DereferenceExpression,
|
||||
AstNode__ExpressionEnd,
|
||||
@@ -117,7 +118,7 @@ struct AstNode {
|
||||
struct { Token op; AstNode *left, *right; } binary_expression;
|
||||
struct { AstNode *expression; Token open, close; } paren_expression;
|
||||
struct { Token token; AstNode *operand, *selector; } selector_expression;
|
||||
struct { AstNode *expression, *value; Token open, close; } index_expression;
|
||||
struct { AstNode *expression, *value; Token open, close; } index_expression;
|
||||
struct { Token token; AstNode *type_expression, *operand; } cast_expression;
|
||||
struct {
|
||||
AstNode *proc, *arg_list;
|
||||
@@ -125,6 +126,12 @@ struct AstNode {
|
||||
Token open, close;
|
||||
} call_expression;
|
||||
struct { Token op; AstNode *operand; } dereference_expression;
|
||||
struct {
|
||||
AstNode *expression;
|
||||
Token open, close;
|
||||
AstNode *low, *high, *max;
|
||||
b32 triple_indexed; // [(1st):2nd:3rd]
|
||||
} slice_expression;
|
||||
|
||||
struct { Token begin, end; } bad_statement;
|
||||
struct { Token token; } empty_statement;
|
||||
@@ -271,6 +278,8 @@ Token ast_node_token(AstNode *node) {
|
||||
return ast_node_token(node->selector_expression.selector);
|
||||
case AstNode_IndexExpression:
|
||||
return node->index_expression.open;
|
||||
case AstNode_SliceExpression:
|
||||
return node->slice_expression.open;
|
||||
case AstNode_CastExpression:
|
||||
return node->cast_expression.token;
|
||||
case AstNode_DereferenceExpression:
|
||||
@@ -439,6 +448,19 @@ gb_inline AstNode *make_index_expression(Parser *p, AstNode *expression, AstNode
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
gb_inline AstNode *make_slice_expression(Parser *p, AstNode *expression, Token open, Token close, AstNode *low, AstNode *high, AstNode *max, b32 triple_indexed) {
|
||||
AstNode *result = make_node(p, AstNode_SliceExpression);
|
||||
result->slice_expression.expression = expression;
|
||||
result->slice_expression.open = open;
|
||||
result->slice_expression.close = close;
|
||||
result->slice_expression.low = low;
|
||||
result->slice_expression.high = high;
|
||||
result->slice_expression.max = max;
|
||||
result->slice_expression.triple_indexed = triple_indexed;
|
||||
return result;
|
||||
}
|
||||
|
||||
gb_inline AstNode *make_cast_expression(Parser *p, Token token, AstNode *type_expression, AstNode *operand) {
|
||||
AstNode *result = make_node(p, AstNode_CastExpression);
|
||||
result->cast_expression.token = token;
|
||||
@@ -865,14 +887,43 @@ AstNode *parse_atom_expression(Parser *p, b32 lhs) {
|
||||
if (lhs) {
|
||||
// TODO(bill): Handle this
|
||||
}
|
||||
AstNode *value;
|
||||
Token open, close;
|
||||
AstNode *indices[3] = {};
|
||||
|
||||
open = expect_token(p, Token_OpenBracket);
|
||||
value = parse_expression(p, false);
|
||||
if (p->cursor[0].kind != Token_Colon)
|
||||
indices[0] = parse_expression(p, false);
|
||||
isize colon_count = 0;
|
||||
Token colons[2] = {};
|
||||
|
||||
while (p->cursor[0].kind == Token_Colon && colon_count < 2) {
|
||||
colons[colon_count++] = p->cursor[0];
|
||||
next_token(p);
|
||||
if (p->cursor[0].kind != Token_Colon &&
|
||||
p->cursor[0].kind != Token_CloseBracket &&
|
||||
p->cursor[0].kind != Token_EOF) {
|
||||
indices[colon_count] = parse_expression(p, false);
|
||||
}
|
||||
}
|
||||
close = expect_token(p, Token_CloseBracket);
|
||||
|
||||
operand = make_index_expression(p, operand, value, open, close);
|
||||
if (colon_count == 0) {
|
||||
operand = make_index_expression(p, operand, indices[0], open, close);
|
||||
} else {
|
||||
b32 triple_indexed = false;
|
||||
if (colon_count == 2) {
|
||||
triple_indexed = true;
|
||||
if (indices[1] == NULL) {
|
||||
print_parse_error(p, colons[0], "Second index is required in a triple indexed slice");
|
||||
indices[1] = make_bad_expression(p, colons[0], colons[1]);
|
||||
}
|
||||
if (indices[2] == NULL) {
|
||||
print_parse_error(p, colons[1], "Third index is required in a triple indexed slice");
|
||||
indices[2] = make_bad_expression(p, colons[1], close);
|
||||
}
|
||||
}
|
||||
operand = make_slice_expression(p, operand, open, close, indices[0], indices[1], indices[2], triple_indexed);
|
||||
}
|
||||
} break;
|
||||
|
||||
case Token_Pointer: // Deference
|
||||
|
||||
Reference in New Issue
Block a user