summaryrefslogtreecommitdiff
path: root/pez.c
diff options
context:
space:
mode:
Diffstat (limited to 'pez.c')
-rw-r--r--pez.c61
1 files changed, 49 insertions, 12 deletions
diff --git a/pez.c b/pez.c
index 19d53ce..622ebc6 100644
--- a/pez.c
+++ b/pez.c
@@ -1021,6 +1021,8 @@ fixtrunc(fixnum f) { return f & ~(uint32_t)0xFFF; }
_(upval, 1) \
_(setupv,-1) \
_(close, 0) \
+ _(argc, 1) \
+ _(vararg, 0) \
_(global, 0) \
_(setglo,-2) \
_(putglo,-2) \
@@ -1619,6 +1621,19 @@ exefn(PezContext *cx, Fn *fn, uint nargs)
uint8_t idx = code[ip++];
closeups(cx, &locals[idx]);
}
+ CASE(Oargc) {
+ TRY(push(cx, box_num(inttofix(nargs - pr->nparams))));
+ }
+ CASE(Ovararg) {
+ Val a = pop(cx);
+ fixnum num = unbox_num(a);
+ int idx = fixtoint(num) + pr->nparams;
+ if (!isnum(a) || num < 0 || fixtrunc(num) != num) {
+ runerr(cx, fn, ip, "SEL expected positive integer index");
+ return 0;
+ }
+ TRY(push(cx, idx >= nargs ? VOID : args[idx]));
+ }
CASE(Oglobal) {
Val k = pop(cx), *v;
if ((v = getglobal(cx, k))) {
@@ -2488,6 +2503,15 @@ compclosure(Comp *cm, Proto *pr)
}
static bool
+reserved(const char *s)
+{
+ return !strcmp(s, "FOR")
+ || !strcmp(s, "RET")
+ || !strcmp(s, "SEL")
+ || !strcmp(s, "SEL$");
+}
+
+static bool
lambdaexpr(Comp *cm, const char *name)
{
Proto *proto = newproto(cm->cx, cm->proto->file, name, cm->line);
@@ -2510,13 +2534,23 @@ lambdaexpr(Comp *cm, const char *name)
char name[NAMEMAX];
int c;
eatspaces(cm);
- if ((c = peekchr(cm)) != '_' && !aisalpha(c)) {
- comperr(cm, c, "expected identifier");
- return 0;
+ if ((c = peekchr(cm)) == '_' || aisalpha(c)) {
+ ETRY(readident(cm, name, sizeof name));
+ if (reserved(name)) {
+ comperr(cm, *name, "'%s' is a reserved keyword", name);
+ goto Err;
+ }
+ ETRY(addparam(cm, name));
+ } else if (c == '*') {
+ nextchr(cm);
+ proto->variadic = 1;
+ matchspchr(cm, ',');
+ ETRY(expectspchr(cm, ']'));
+ break;
+ } else {
+ comperr(cm, c, "expected param name");
+ goto Err;
}
- ETRY(readident(cm, name, sizeof name));
-
- ETRY(addparam(cm, name));
if (!matchspchr(cm, ',')) {
ETRY(expectspchr(cm, ']'));
@@ -2555,12 +2589,6 @@ flushconst(Comp *cm)
}
static bool
-reserved(const char *s)
-{
- return !strcmp(s, "FOR") || !strcmp(s, "RET");
-}
-
-static bool
primaryexpr(Comp *cm)
{
char buf[NAMEMAX];
@@ -2615,6 +2643,15 @@ primaryexpr(Comp *cm)
// identifier
*buf = c;
TRY(readident(cm, buf + 1, sizeof buf - 1));
+ if (!strcmp(buf, "SEL$")) {
+ return compop(cm, Oargc);
+ } else if (!strcmp(buf, "SEL")) {
+ TRY(expectspchr(cm, '['));
+ TRY(expr(cm));
+ TRY(expectspchr(cm, ']'));
+ TRY(compop(cm, Ovararg));
+ return 1;
+ }
if (reserved(buf)) {
comperr(cm, *buf, "'%s' is a reserved keyword", buf);
return 0;