aboutsummaryrefslogtreecommitdiff
path: root/src/compiler/builtins.zc
diff options
context:
space:
mode:
Diffstat (limited to 'src/compiler/builtins.zc')
-rw-r--r--src/compiler/builtins.zc12
1 files changed, 9 insertions, 3 deletions
diff --git a/src/compiler/builtins.zc b/src/compiler/builtins.zc
index 9a89052..cbc380e 100644
--- a/src/compiler/builtins.zc
+++ b/src/compiler/builtins.zc
@@ -71,8 +71,10 @@ int ptagged(word t) {
// enum name { A, B = 5 } is a plain enum: each member is a constant, plain (A)
// and scoped (name.A). a member with a block of fields makes it a tagged enum
// (see enum_tagged): enum name { circle { int r; }, dot }.
+// the first member of the enum being read, so a member's value can name the members before it; -1 outside
+int enum_open = 0 - 1;
int kw_enum() {
- char* n; char* en = 0; int first = npm, cnt = 0, tagged = 0, gi, nf, v = 0, et = 0, sk, ft; char* fname;
+ char* n; char* en = 0; int first = npm, cnt = 0, tagged = 0, gi, nf, v = 0, et = 0, sk, ft, rv = 0; char* fname;
stmtonly();
next();
if (tk == T_ID) { en = tv; next(); }
@@ -97,7 +99,9 @@ int kw_enum() {
expect(s_semi);
}
expect(s_rb);
- } else if (accept(s_eq)) { pm_val[gi] = cexpr(); pm_exp[gi] = 1; }
+ } else { enum_open = first; if (accept(s_eq)) { pm_val[gi] = cexpr(); pm_exp[gi] = 1; } enum_open = 0 - 1; }
+ if (pm_exp[gi]) rv = pm_val[gi]; else if (!pm_nf[gi]) pm_val[gi] = rv; // the running value, read by cprim
+ rv++;
cnt++;
if (!accept(s_comma)) break;
if (is_op(s_rb)) break;
@@ -312,6 +316,7 @@ int inc_compile(char* buf, char* name, char*.d dir) {
int kw_include() {
int pp, sv; char* path; char* buf;
stmtonly();
+ if (infn) { die("include is top level only"); return 0; } // appendix b.2.9
next();
if (tk == T_ID) {
while (1) {
@@ -701,7 +706,8 @@ int array_len(word t) {
return 0;
}
if (t[0] == TY_ARR) { op(O_DROP); lit(t[3]); }
- else { tcneed(t[0] == TY_DYN || t == tword, "len needs an array", t); if (argloc >= 0) { op(O_DROP); vaddr(o3cache[argloc] + 1); op(O_LD); } else if (o3on && t[0] == TY_DYN) op(O_LD); else callname(s_dlen); }
+ else { if (!tc_on && t[0] == TY_PTR && t[4][0] == TY_CHAR) serr("len needs an array, not a char* (use rt.len_w, or a bstr)"); // b.2.14: it would read word 0
+ tcneed(t[0] == TY_DYN || t == tword, "len needs an array", t); if (argloc >= 0) { op(O_DROP); vaddr(o3cache[argloc] + 1); op(O_LD); } else if (o3on && t[0] == TY_DYN) op(O_LD); else callname(s_dlen); }
xty = tint;
xlenloc = -1; xstamp = 0;
if (a >= 0 && t[0] == TY_DYN && t[3]) xlenloc = a; // the whole expression is len of a fixed array