diff options
| author | eunhhu <[email protected]> | 2026-10-19 07:15:34 +0100 |
|---|---|---|
| committer | eunhhu <[email protected]> | 2026-10-19 07:15:34 +0100 |
| commit | 39d4a024f91a042c5ffe8f5f76faf02f77b86f33 (patch) | |
| tree | b34fbdde6bc10b7b1d02c14084fd72f5f537c769 /compiler/compile.c | |
| parent | 11960e4e2353dc63660362660901183a2585cb08 (diff) | |
| download | aup-39d4a024f91a042c5ffe8f5f76faf02f77b86f33.tar.gz aup-39d4a024f91a042c5ffe8f5f76faf02f77b86f33.zip | |
abs(x) and a timer's period without a core change (140's RFC 6298 frictions): abs of a number or an i64, x once (a PICK of it, its negation, MAX: -0's is +0, i64's least overflows); tick.period, an every input's milliseconds as now counts them, a constant anywhere; frictions in make check, a diagnostic; no module of aup's, Pure's or Vega's changes
Diffstat (limited to 'compiler/compile.c')
| -rw-r--r-- | compiler/compile.c | 19 |
1 files changed, 18 insertions, 1 deletions
diff --git a/compiler/compile.c b/compiler/compile.c index b11acec..5475afe 100644 --- a/compiler/compile.c +++ b/compiler/compile.c @@ -40,6 +40,7 @@ enum { BIT_AND = 0x100, BIT_OR, BIT_XOR, BIT_LEFT, BIT_RIGHT, BIT_NOT }; enum { LOCALS = 64 }; /* an event's locals (Pure's) */ enum { NESTING = 8, LOOP_INTEGER = 256 }; /* loops (for) nest 8 deep; an i64's count (Pure 018) */ enum { FOLD_COUNT, FOLD_SUM, FOLD_MAX, FOLD_MIN, FOLD_FIRST, FOLD_DISTINCT, FOLD_INTEGER = 0x40 }; +enum { ABS = BIT_NOT + 1 }; /* abs(x), the compiler's alone: x, a PICK of it, its negation and MAX (no instruction of Pure's) */ /* An input as the app writes it; in Pure's module (027's 4d) each of them but an output and a view's arguments is a * message, its binding what makes it: a key's press (KIND_KEY) and its release (KIND_RELEASE, an `on k.up`'s, k.up), a * text's (one field, text), a timer's tick, a frame (one field, dt: frame, an `on frame`'s) or a pointing at a table's @@ -916,7 +917,8 @@ static Expr *expression(Compiler *c, int minimum, bool multiline) { } else if (token.kind == T_NAME) { static const struct { const char *name; unsigned count; int op; } calls[] = {{"min", 2, MIN}, {"max", 2, MAX}, {"clamp", 3, CLAMP}, {"text", 1, TEXT_FROM}, {"bytes", 1, BYTES_FROM}, - {"floor", 1, FLOOR}, {"i64", 1, I64_FROM}, {"number", 1, NUM_FROM}, {"byte", 1, BYTE}, {"char", 1, CHAR}}; + {"floor", 1, FLOOR}, {"i64", 1, I64_FROM}, {"number", 1, NUM_FROM}, {"byte", 1, BYTE}, {"char", 1, CHAR}, + {"abs", 1, ABS}}; int call = -1, how = -1; for (int i = 0; i < (int)(sizeof(calls) / sizeof(*calls)); ++i) if (!strcmp(token.text, calls[i].name)) call = i; static const char *const folds[] = {"count", "sum", "max", "min", "first", "distinct"}; @@ -3604,6 +3606,12 @@ static Kind value(Compiler *c, const Expr *e, bool handler, int height) { const Expr *base = e->args[0]; int item_list; char item[2 * NAME + 2]; + int timer = base->kind == E_NAME && !strcmp(e->member, "period") && !c->module && parameter(c, base->name) < 0 && + local_named(c, base->name) < 0 ? input_index(c, base->name) : -1; + if (timer >= 0 && c->inputs[timer].kind == KIND_TIMER) { /* tick.period: a timer's, in milliseconds, as now is */ + emit(c, e->line, e->column, CONST, 0, (double)c->inputs[timer].period); + return (Kind){NUM, -1}; + } int binding = binding_path(c, e, item); if (binding >= 0) { /* down a record's value held by name (027's 2c) */ Kind kind = binding_value(c, e, binding, item); @@ -4097,6 +4105,15 @@ static Kind value(Compiler *c, const Expr *e, bool handler, int height) { emit(c, e->line, e->column, (uint8_t)e->op, 0, 0); return (Kind){BOOL, -1}; } + if (e->op == ABS) { /* abs(x): x once, then the greater of it and its negation (-0's is +0, as IEEE's maximum) */ + Kind operand = wanted(c, e->args[0], handler, height, want); + if (operand.type != I64) expect_kind(c, e->args[0], operand, NUM); + if (height + 2 > STACK) fail_at(c, e->line, e->column, "expression needs more than 64 stack values"); + emit(c, e->line, e->column, PICK, 0, 0); + emit(c, e->line, e->column, operand.type == I64 ? I64_NEG : NEG, 0, 0); + emit(c, e->line, e->column, operand.type == I64 ? I64_MAX : MAX, 0, 0); + return (Kind){operand.type, -1}; + } if (e->op == BYTE) { /* byte(n): one byte, n an i64 0-255 */ integer(c, e->args[0], handler, height); emit(c, e->line, e->column, BYTE, 0, 0); |
