unfinished SETH
This commit is contained in:
parent
de86ce2aaa
commit
0af6895f4b
@ -216,5 +216,6 @@ A fancier message can be created with `thrF(message, …)` with printf-like (but
|
||||
```
|
||||
See `#define CATCH` in `src/h.h` for how to catch errors.
|
||||
|
||||
Use `assert(predicate)` for checks (for optimized builds they're replaced with `if (!predicate) invoke_undefined_behavior();` so it's still invoked!!).
|
||||
Use `assert(predicate)` for checks (for optimized builds they're replaced with `if (!predicate) invoke_undefined_behavior();` so it's still invoked!!). `UD;` can be used to explicitly invoke undefined behavior (equivalent in behavior to `assert(false);`), which is useful for things like untaken `default` branches in `switch` statements.
|
||||
|
||||
There's also `err("message")` that (at least currently) is kept in optimized builds as-is, and always kills the process on being called.
|
||||
@ -130,10 +130,11 @@ B shape_c2(B t, B w, B x) {
|
||||
} else {
|
||||
xf = getFillQ(x);
|
||||
if (xia<=1) {
|
||||
if (xia==0) {
|
||||
if (RARE(xia==0)) {
|
||||
thrM("⥊: Empty 𝕩 and non-empty result");
|
||||
dec(x);
|
||||
x = inc(xf);
|
||||
// if (xf.u == bi_noFill.u) thrM("⥊: No fill for empty array");
|
||||
// dec(x);
|
||||
// x = inc(xf);
|
||||
} else {
|
||||
B n = TI(x,get)(x,0);
|
||||
dec(x);
|
||||
@ -186,11 +187,11 @@ B shape_c2(B t, B w, B x) {
|
||||
extern B rt_pick;
|
||||
B pick_c1(B t, B x) {
|
||||
if (isAtm(x)) return x;
|
||||
if (a(x)->ia==0) {
|
||||
if (RARE(a(x)->ia==0)) {
|
||||
thrM("⊑: Argument cannot be empty");
|
||||
B r = getFillE(x);
|
||||
dec(x);
|
||||
return r;
|
||||
// B r = getFillE(x);
|
||||
// dec(x);
|
||||
// return r;
|
||||
}
|
||||
B r = TI(x,get)(x, 0);
|
||||
dec(x);
|
||||
|
||||
@ -10,7 +10,7 @@
|
||||
#elif MM==2
|
||||
#include "opt/mm_2buddy.h"
|
||||
#else
|
||||
#error bad MM value
|
||||
#error "bad MM value"
|
||||
#endif
|
||||
|
||||
#include "core/gstack.h"
|
||||
|
||||
@ -7,5 +7,5 @@
|
||||
#elif MM==2
|
||||
#include "../opt/mm_2buddy.c"
|
||||
#else
|
||||
#error bad MM value
|
||||
#error "bad MM value"
|
||||
#endif
|
||||
|
||||
3
src/h.h
3
src/h.h
@ -146,6 +146,9 @@ static const u16 VAL_TAG = 0b1111111111110 ; // FFF. 1111111111110............
|
||||
|
||||
void cbqn_init(void);
|
||||
|
||||
#if __STDC_IEC_559__ == 0
|
||||
#error "IEEE 754 floating point number support is required for CBQN"
|
||||
#endif
|
||||
typedef union B {
|
||||
u64 u;
|
||||
f64 f;
|
||||
|
||||
@ -124,6 +124,10 @@ INS B i_SETM(B s, B f, B x, Scope** pscs, u32* bc) { POS_UPD;
|
||||
v_set(pscs, s, r, true); dec(s);
|
||||
return r;
|
||||
}
|
||||
INS void i_SETH(B s, B x, Scope** pscs, u32* bc) { POS_UPD;
|
||||
bool ok = v_seth(pscs, s, x);
|
||||
if (!ok) thrM("VM: Header fallback NYI");
|
||||
}
|
||||
INS B i_SETNi( B x, Scope* sc, u32 p, u32* bc) { POS_UPD; v_setI(sc, p, inc(x), false); return x; }
|
||||
INS B i_SETUi( B x, Scope* sc, u32 p, u32* bc) { POS_UPD; v_setI(sc, p, inc(x), true ); return x; }
|
||||
INS B i_SETMi(B f, B x, Scope* sc, u32 p, u32* bc) { POS_UPD; B r = c2(f,v_getI(sc, p),x); dec(f); v_setI(sc, p, inc(r), true); return r; }
|
||||
@ -571,6 +575,7 @@ Nvm_res m_nvm(Body* body) {
|
||||
case SETN: TOPp; GET(R_A1,1,1); LEAi(R_A2,R_SP,VAR(pscs,0)); IMM(R_A3,off); CCALL(i_SETN); break; // (B s, B x, Scope** pscs, u32* bc)
|
||||
case SETU: TOPp; GET(R_A1,1,1); LEAi(R_A2,R_SP,VAR(pscs,0)); IMM(R_A3,off); CCALL(i_SETU); break; // (B s, B x, Scope** pscs, u32* bc)
|
||||
case SETM: TOPp; GET(R_A1,1,1) GET(R_A2,2,1); LEAi(R_A3,R_SP,VAR(pscs,0)); IMM(R_A4,off); CCALL(i_SETM); break; // (B s, B f, B x, Scope** pscs, u32* bc)
|
||||
case SETH: TOPp; GET(R_A1,1,1); LEAi(R_A2,R_SP,VAR(pscs,0)); IMM(R_A3,off); CCALL(i_SETH); break; // (B s, B x, Scope** pscs, u32* bc)
|
||||
// TODO SETNi doesn't really need to update gStack
|
||||
case SETNi:TOPp; { u64 d=*bc++; u64 p=*bc++; GET(R_A1,0,2); LSC(R_A1,d); IMM(R_A2,p); IMM(R_A3,off); CCALL(i_SETNi); break; } // ( B x, Scope* sc, u32 p, u32* bc)
|
||||
case SETUi:TOPp; { u64 d=*bc++; u64 p=*bc++; GET(R_A1,0,2); LSC(R_A1,d); IMM(R_A2,p); IMM(R_A3,off); CCALL(i_SETUi); break; } // ( B x, Scope* sc, u32 p, u32* bc)
|
||||
|
||||
71
src/vm.c
71
src/vm.c
@ -47,8 +47,8 @@ i32 stackDiff(u32* p) {
|
||||
switch(*p) { default: UD; // case ARRO: case ARRM: return 1-p[1];
|
||||
case PUSH: case VARO: case VARM: case DFND: case LOCO: case LOCM: case LOCU: case EXTO: case EXTM: case EXTU: case SYSV: case ADDI: case ADDU: return 1;
|
||||
case FN1Ci:case FN1Oi:case CHKV: case VFYM: case FLDO: case FLDM: case RETD: case NSPM: return 0;
|
||||
case FN2Ci:case FN2Oi:case FN1C: case FN1O: case OP1D: case TR2D: case POPS: case OP2H: case SETH: case RETN: return -1;
|
||||
case OP2D: case TR3D: case FN2C: case FN2O: case TR3O: return -2;
|
||||
case FN2Ci:case FN2Oi:case FN1C: case FN1O: case OP1D: case TR2D: case POPS: case OP2H: case RETN: return -1;
|
||||
case OP2D: case TR3D: case FN2C: case FN2O: case TR3O: case SETH: return -2;
|
||||
|
||||
case SETN: return -1; case SETNi:return 0; case SETNv:return -1;
|
||||
case SETU: return -1; case SETUi:return 0; case SETUv:return -1;
|
||||
@ -420,31 +420,55 @@ NOINLINE void v_setR(Scope* pscs[], B s, B x, bool upd) {
|
||||
B* sp = harr_ptr(s);
|
||||
usz ia = a(s)->ia;
|
||||
if (isAtm(x) || !eqShape(s, x)) {
|
||||
if (isNsp(x)) {
|
||||
for (u64 i = 0; i < ia; i++) {
|
||||
B c = sp[i];
|
||||
if (isVar(c)) {
|
||||
Scope* sc = pscs[(u16)(c.u>>32)];
|
||||
i32 nameID = sc->body->varIDs[(u32)c.u];
|
||||
v_set(pscs, c, ns_getU(x, sc->body->nsDesc->nameList, nameID), upd);
|
||||
} else if (isExt(c)) {
|
||||
ScopeExt* ext = pscs[(u16)(c.u>>32)]->ext;
|
||||
v_set(pscs, c, ns_getNU(x, ext->vars[(u32)c.u + ext->varAm]), upd);
|
||||
} else if (isObj(c)) {
|
||||
assert(v(c)->type == t_fldAlias);
|
||||
Scope* sc = pscs[0];
|
||||
FldAlias* cf = c(FldAlias,c);
|
||||
v_set(pscs, cf->obj, ns_getU(x, sc->body->nsDesc->nameList, cf->p), upd);
|
||||
} else thrM("Assignment: extracting non-name from namespace");
|
||||
}
|
||||
return;
|
||||
if (!isNsp(x)) thrM("Assignment: Mismatched shape for spread assignment");
|
||||
for (u64 i = 0; i < ia; i++) {
|
||||
B c = sp[i];
|
||||
if (isVar(c)) {
|
||||
Scope* sc = pscs[(u16)(c.u>>32)];
|
||||
i32 nameID = sc->body->varIDs[(u32)c.u];
|
||||
v_set(pscs, c, ns_getU(x, sc->body->nsDesc->nameList, nameID), upd);
|
||||
} else if (isExt(c)) {
|
||||
ScopeExt* ext = pscs[(u16)(c.u>>32)]->ext;
|
||||
v_set(pscs, c, ns_getNU(x, ext->vars[(u32)c.u + ext->varAm]), upd);
|
||||
} else if (isObj(c)) {
|
||||
assert(v(c)->type == t_fldAlias);
|
||||
Scope* sc = pscs[0];
|
||||
FldAlias* cf = c(FldAlias,c);
|
||||
v_set(pscs, cf->obj, ns_getU(x, sc->body->nsDesc->nameList, cf->p), upd);
|
||||
} else thrM("Assignment: extracting non-name from namespace");
|
||||
}
|
||||
thrM("Assignment: Mismatched shape for spread assignment");
|
||||
return;
|
||||
}
|
||||
BS2B xgetU = TI(x,getU);
|
||||
for (u64 i = 0; i < ia; i++) v_set(pscs, sp[i], xgetU(x,i), upd);
|
||||
}
|
||||
}
|
||||
NOINLINE bool v_sethR(Scope* pscs[], B s, B x) {
|
||||
assert(!isExt(s));
|
||||
VTY(s, t_harr);
|
||||
B* sp = harr_ptr(s);
|
||||
usz ia = a(s)->ia;
|
||||
if (isAtm(x) || !eqShape(s, x)) {
|
||||
if (!isNsp(x)) return false;
|
||||
for (u64 i = 0; i < ia; i++) {
|
||||
B c = sp[i];
|
||||
if (isVar(c)) {
|
||||
Scope* sc = pscs[(u16)(c.u>>32)];
|
||||
i32 nameID = sc->body->varIDs[(u32)c.u];
|
||||
if (!v_seth(pscs, c, ns_getU(x, sc->body->nsDesc->nameList, nameID))) return false;
|
||||
} else if (isObj(c)) {
|
||||
assert(v(c)->type == t_fldAlias);
|
||||
Scope* sc = pscs[0];
|
||||
FldAlias* cf = c(FldAlias,c);
|
||||
if (!v_seth(pscs, cf->obj, ns_getU(x, sc->body->nsDesc->nameList, cf->p))) return false;
|
||||
} else return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
BS2B xgetU = TI(x,getU);
|
||||
for (u64 i = 0; i < ia; i++) if (!v_seth(pscs, sp[i], xgetU(x,i))) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -637,6 +661,11 @@ B evalBC(Block* bl, Body* b, Scope* sc) { // doesn't consume
|
||||
ADD(r);
|
||||
break;
|
||||
}
|
||||
case SETH: { P(s) P(x) GS_UPD; POS_UPD;
|
||||
bool ok = v_seth(pscs, s, x);
|
||||
if (!ok) thrM("VM: Header fallback NYI");
|
||||
break;
|
||||
}
|
||||
case FLDO: { P(ns) GS_UPD; u32 p = *bc++; POS_UPD;
|
||||
if (!isNsp(ns)) thrM("Trying to read a field from non-namespace");
|
||||
ADD(inc(ns_getU(ns, sc->body->nsDesc->nameList, p)));
|
||||
|
||||
11
src/vm.h
11
src/vm.h
@ -195,6 +195,7 @@ static inline B v_get(Scope* pscs[], B s) { // get value representing s, replaci
|
||||
}
|
||||
|
||||
NOINLINE void v_setR(Scope* pscs[], B s, B x, bool upd); // doesn't consume
|
||||
NOINLINE bool v_sethR(Scope* pscs[], B s, B x); // doesn't consume
|
||||
static inline void v_setI(Scope* sc, u32 p, B x, bool upd) { // consumes x
|
||||
B prev = sc->vars[p];
|
||||
if (upd) {
|
||||
@ -207,3 +208,13 @@ static inline void v_set(Scope* pscs[], B s, B x, bool upd) { // doesn't consume
|
||||
if (RARE(!isVar(s))) v_setR(pscs, s, x, upd);
|
||||
else v_setI(pscs[(u16)(s.u>>32)], (u32)s.u, inc(x), upd);
|
||||
}
|
||||
|
||||
static inline bool v_seth(Scope* pscs[], B s, B x) { // consumes both; s cannot contain extended variables
|
||||
if (RARE(!isVar(s))) {
|
||||
bool r = v_sethR(pscs, s, x);
|
||||
dec(s); dec(x);
|
||||
return r;
|
||||
}
|
||||
v_setI(pscs[(u16)(s.u>>32)], (u32)s.u, x, false);
|
||||
return true;
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user