@chrispsn there should be a 0 1\ or 0 1\: for splitting the whole and fractional parts (depending on dialect and atw's mood). is it common enough to deserve a single-char primitive?
@ngn not yet, i am still going through the parser and bytecode complier, where i usually got stuck at the meaning of some internal verbs, e.g. au_xxx, bm and beyond in the bytecode enum. and it's not that easy to spot cheaper alternative in this part of codebase i geuss. maybe there is a little chance when it comes to the implementation of verbs.
@ksi i use "u" for unary verb, "v" for binary verb, and "w" for adverb. "au_" stands for "array of type unary verb" (or "allocate.." but there's no allocation really - all the information is encoded in the tagged pointer)
au_out is a pseudo-verb corresponding to the new syntax i borrowed from k7 and k9: expr1 \expr2
this prints the result from expr2 before evaluating further - convenient for debugging
au_cmd is for \syscmds
au_plc is a placeholder for missing args in projections, similar to one of the uses of :: in k5-6
av_com builds compositions, like '[f;g] in k5-6
av_mkl is "make list". i think the real k somehow reuses ,: (enlist) for that but i ended up needing a separate verb
bm bM - local&global modified assignment (a[i]+:b) bl bL - make list and destroy list, the latter used for (a;b):c ba - apply n-adically bP - make projection bz - branch if zero (i.e. if falsey) bj bp br - jump pop return bc - load constant (128 such instructions)
@ksi i fear i might forget to update them next time i decide to rename everything. maybe a comment in b.c (the bytecode compiler&vm) would be better if i can compress it well enough
that's fair, i can remind you if i am still closely look at ngn/k at that time:)
Also, i did try to modify some small pieces of code when i think i got the meaning of a function, e.g. in memcmp@m.c, F(n,I d=*p++-*q++;P(d,d))0) seems to able to replace by F(n,P(*p++-*q++,1))0). would you mind small suggestion like that, though i could misunderstand its meaning since i only gauge the equivalence based on your test cases only:) @ngn
@ksi you're right. in general memcmp() is supposed to discern beween negative and positive results, depending on how the first mismatched bytes differ, but i use it only to implement x~y so here it doesn't matter. thanks
lol, i can imagine why people don't like it. i find it acceptable except for the ultra short name of vars and funs.
i do a lot coding in q/kdb at work. i am always interested in making q code faster. someimes, i got to a point that i need modify the language to be able to do it. ofc, i wouldn't do that at work, but as a hobby, it's fun to implement my own version of k. but i know little about how to write a fast interpreter. it couldn't be better to have this open source implementation, so thanks @ngn
@ngn Also, why do you chose A to be L, rather than UL, and have it converted to UL for getting and setting the tagged info. i am not sure which is faster though.
@ksi i can't think of a single link to recommend. i've gathered information from various places - blogs, stackoverflow, random web searches..
basically, the x86_64 calling convention is very similar to the calling convention for functions (integer args go into rdi,rsi,.. and the result is in rax) except that one of the args uses a different register - r10 instead of rcx
i've no idea why it was designed that way
to make the call itself, there's a "syscall" instruction
so, very straightforward, if it wasn't for the weird asm() syntax..
if you look at kparc.com/b/A.S - arthur has taken the simplest possible way out of this. he declares functions that act as wrappers around the syscalls, taking care only of the rcx/r10 oddity
the drawback is that there's the function call overhead, but that's probably dwarfed but the cost of a syscall anyway
i fought this problem to the end and i made my syscalls inline (no wrapper functions), but now i have much more than 3 lines of code dedicated to this and not much advantage performancewise, so.. not sure if it was worth it
@chrispsn still, i expect it to be much slower than a built-in flip, because mine has to enlist each individual element of the matrix before it starts concatenating them
@ktye what does x[;!n] mean in k9? i suppose it just means flip, right? i.e. take the columns out of a matrix. @ngn ngn/k works as i expected, it's slow though.