aboutsummaryrefslogtreecommitdiff
path: root/bootstrap
diff options
context:
space:
mode:
Diffstat (limited to 'bootstrap')
-rw-r--r--bootstrap/parse.c47
-rw-r--r--bootstrap/test.cff5
2 files changed, 33 insertions, 19 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;
diff --git a/bootstrap/test.cff b/bootstrap/test.cff
index be6cb95..95ee7bf 100644
--- a/bootstrap/test.cff
+++ b/bootstrap/test.cff
@@ -10,9 +10,8 @@ enum Color {
Red, Green, Blue
}
-defmacro arraylength(ary) [ (sizeof(ary)/sizeof(ary[0])) ]
defmacro each(i, x, arr, ...body) [
- for let i = 0; i < arraylength(arr); ++i {
+ for let i = 0; i < arr.#len; ++i {
let x = arr[i];
{ body }
}
@@ -60,7 +59,7 @@ extern fn main (argc int, argv **u8) int {
printf("mag = %g\n", (&x)->mag());
let is []int = { [4] = 1, 2, [1 - 1] = 3 };
- isort(is, arraylength(is));
+ isort(is, is.#len);
each(i, x, is,
printf("%d\n", x);
)