aboutsummaryrefslogtreecommitdiff
path: root/bootstrap/parse.c
diff options
context:
space:
mode:
Diffstat (limited to 'bootstrap/parse.c')
-rw-r--r--bootstrap/parse.c47
1 files changed, 31 insertions, 16 deletions
diff --git a/bootstrap/parse.c b/bootstrap/parse.c
index e32a2a3..c48d1eb 100644
--- a/bootstrap/parse.c
+++ b/bootstrap/parse.c
@@ -344,6 +344,8 @@ lex(struct parser *P) {
tok.t = TKnullit;
} else if (!strcmp(s, "##")) {
tok.t = '##';
+ } else if (!strcmp(s, "#len")) {
+ tok.t = '#len';
} else if (c == '#') {
fatal(P, P->tokspan, "identifier cannot start with '#'");
} else if (c == '$') {
@@ -1044,24 +1046,37 @@ pexpostfix(struct parser *P) {
}
};
} else if (lexmatch(P, &tok, '.')) {
- const char *fnam = (tok = lexexpect(P, TKident)).str;
- const struct type *ty = ex.ty;
- if (ty->t == TYptr)
- ty = ty->child;
- if (ty->t == TYstruct || ty->t == TYunion) {
- int idx = structfldnam2idx(ty, fnam);
- struct aggfield *fld = &ty->agg.flds.d[idx];
- if (idx < 0)
- fatal(P, tok.span, "%t has no such field `%s'", ty, fnam);
-
- ex.get.lhs = exprdup(ex);
- ex.t = Eget;
+ if (lexmatch(P, &tok, '#len')) {
+ const struct type *ty = ex.ty;
+ if (ty->t == TYptr)
+ ty = ty->child;
+ if (ty->t != TYarr)
+ fatal(P, ex.span, "invalid operand to `.#len' (%t)", ex.ty);
+ assert(ty->length >= 0);
+ ex.t = Eintlit;
+ ex.ty = ty_usize;
ex.span = tok.span;
- ex.ty = fld->ty;
- ex.get.fld = fnam;
+ ex.i = ty->length;
} else {
- fatal(P, tok.span, "cannot access `%s': left-hand-side is not an aggregate (%t)",
- fnam, ex.ty);
+ const char *fnam = (tok = lexexpect(P, TKident)).str;
+ const struct type *ty = ex.ty;
+ if (ty->t == TYptr)
+ ty = ty->child;
+ if (ty->t == TYstruct || ty->t == TYunion) {
+ int idx = structfldnam2idx(ty, fnam);
+ struct aggfield *fld = &ty->agg.flds.d[idx];
+ if (idx < 0)
+ fatal(P, tok.span, "%t has no such field `%s'", ty, fnam);
+
+ ex.get.lhs = exprdup(ex);
+ ex.t = Eget;
+ ex.span = tok.span;
+ ex.ty = fld->ty;
+ ex.get.fld = fnam;
+ } else {
+ fatal(P, tok.span, "cannot access `%s': left-hand-side is not an aggregate (%t)",
+ fnam, ex.ty);
+ }
}
} else if (lexmatch(P, &tok, '->')) {
const char *fnam = (tok = lexexpect(P, TKident)).str;