beneroth changed the topic of #picolisp to: PicoLisp language | The scalpel of software development | Channel Log: https://libera.irclog.whitequark.org/picolisp | Check www.picolisp.com for more information
geri has joined #picolisp
<geri> hey, i think im finally getting the symbol data structure graph :D
<geri> in NIL, all cells except first one (that has its name) are pointers to NIL itself?
<geri> symbols pointing directly to their values is neat too cause no need to shift to get the value, just a simple pointer lookup
<geri> oh wait, i think nil might have clicked
<geri> as a symbol, it points to itself and with 8 bit offset you can get its name
<geri> cons cells get pointed to their car, so it reads second and 3rd segment of the NIL structure
<geri> and fourth is there just to not mess with alignment?
<geri> ie not used otherwise
<abu[7]> Hi geri!
<abu[7]> All correct 👍
<abu[7]> "8 bit offset" should be "8 bytes"
<geri> honestly all of these are so smart
<geri> its amazing
<geri> also symbol names just being bignums/numbers interpreted slightly differently
<geri> it's all coming together nicely
<abu[7]> ☺
neuroevolutus has joined #picolisp
rob_w has joined #picolisp
<geri> if i have a 2^60 number (that should be stored in the pointer), what happens when i add 1 to it?
<abu[7]> It will overflow to a bignum
<geri> well yeah, im more wondering how this overflow to a bignum works
<abu[7]> Just creates a new bignum
<abu[7]> Bignum arithmetics create new nums
<abu[7]> ie. consing
<geri> so i got 1111111111111111111111111111111111111111111111111111111111111010 + pointer to nil, right?
<geri> before adding 1
<abu[7]> almost
<geri> does original data get scrapped completely in favour of using a "digit" representation?
<abu[7]> ...0010
<geri> ah, 1 is minus? okay
<abu[7]> T
<abu[7]> The original always remains
<abu[7]> just a pointer here
<abu[7]> but may still be hold somewhere
<abu[7]> thus arithmetics need to be non-destructive internally
<geri> hmm
<geri> so it's 1111111111111111111111111111111111111111111111111111111111110010 + pointer to shortnum 1?
<geri> digit represenation is still a bit confusing
<abu[7]> No, the tag bits are not needed
<abu[7]> Can use the full 64 bits
<abu[7]> DIG
<geri> hmmmmmm
<abu[7]> the CDR is short zero iirc
<geri> oh wait
<geri> so it's 1111111111111111111111111111111111111111111111111111111111111010 + pointer to 0011111111111111111111111111111111111111111111111111111111111111?
<abu[7]> no, it is 2**60 in the CAR and ZERO in the CDR
<geri> but how do you know that the object is a bignum if you use all bits?
<geri> oh wait nvm
<abu[7]> The pointer encodes it
<geri> tags are in place, you just shifted the number
<abu[7]> No
<abu[7]> the data have no tags
<abu[7]> only the pointers *to* the data
<abu[7]> data means cells
<geri> it's not 1111111111111111111111111111111111111111111111111111111111111010 + 0?
<abu[7]> no
<geri> same as 111 + 1 = 1000, but first bits stay in place
<geri> and you grow into the cell in heap instead of growing "to the left"
<abu[7]> exactly
<abu[7]> In all cases
<abu[7]> also if adding 2 bimnums etc.
<abu[7]> big*
<abu[7]> So we just use the available space
<abu[7]> 60 bits in a short, or 64 in a big
<abu[7]> (in a big *cell*)
<geri> how are arithmetic operations implemented on bignums?
<abu[7]> like on paper
<abu[7]> just bigger digits
<geri> dont you need to start from end on paper?
<abu[7]> yes
<abu[7]> so the lowest digit is the first
<abu[7]> only comparisons need to start from the highest digit
taleon has quit [Remote host closed the connection]
<geri> okay wait, need to rethink bignums' structure again xd
<abu[7]> no hurry
<geri> do shortnums grow left to right or right to left?
<geri> 111 + 1 => 1000 or 0001
<abu[7]> 1000
<abu[7]> just hardware
<abu[7]> bit representation
<geri> okay...
taleon has joined #picolisp
<geri> then 60**2 + 1 should be 0000000000000000000000000000000000000000000000000000000000000100 + pointer to short 1?
<abu[7]> no, 10....00 + pointer to short zero
<abu[7]> (vi 'llvm~ZERO)
<abu[7]> ie. 000..010
<geri> but you said it bignums go "in reverse"...
<abu[7]> on the cell level
<geri> oh
<geri> hm
<geri> but bits go as usual?
neuroevolutus has quit [Quit: Client closed]
<abu[7]> little or big endian
<abu[7]> hardware
<geri> okay..
<geri> so if i grow a number 2**(66+64) + 2, then itll be 10...100 followed by pointer to short 1, followed by a pointer to zero short?
<abu[7]> You can direcly inspect the bignums
<abu[7]> with 'adr'
<abu[7]> (struct (- (adr Nun) 4) 'N)
<abu[7]> gives the digit in the first cell
<abu[7]> hmm
<geri> (let Nun (** 2 (+ 60 64)) (struct (- (adr Nun) 4) 'N))
<geri> cries about Number being expected
<abu[7]> "Nun"
<abu[7]> but wait, I get unexpectet result
<abu[7]> sorry
<abu[7]> I'm wrong
<abu[7]> can't get adr of a number
<abu[7]> must use the val of the sym
<abu[7]> tedious
<abu[7]> needs 2 struct calls
<geri> okay lets just say we have a bignum that occupies 3 cells - which cell holds which part of the number? xd
<geri> normally in memory it'd be let's say 1 followed by like 100ish 0's
<abu[7]> The first cell (pointed to by the Lisp pointer) holds the lowest
<abu[7]> if "100ish 0's" is binary, it holds just zeroes
<abu[7]> (not if decimal)
<geri> yeah, its about binary
<abu[7]> so the 64 bits in the first cell are all 0
<geri> but if first cell holds lowest bits, why is it not 0...100 + *1 but 10...100 + *0?
<abu[7]> the 0 in the CDR is a pointer
<abu[7]> CDRs of bignum cells are pointers
<abu[7]> not digits
<geri> oh yeah, yeah
<geri> *1 means "pointer to a short 1"
<geri> was getting lazy :D
<abu[7]> T, shorts are pseudo pointers
<abu[7]> ah, I forgot
<abu[7]> the last CDR is not a pointer
<abu[7]> it is also num data
<abu[7]> that's why it is ZERO and not a null pointer
<abu[7]> the last CDR holds the highest bits of the number
<abu[7]> in a short num
<abu[7]> CNT in doc/structures
<abu[7]> A single-cell bignum can hold 64+60 bits
<geri> CNT is bit tagged?
<abu[7]> it means 'cnt'
<abu[7]> just a short num
<abu[7]> 60 bits plus 0010
<geri> then single cell bignum should be able to hold 120 bits, no?
<geri> cause car is tagged as bignum and cdr as shortnum
<abu[7]> A single-cell bignum can hold 64+60 bits
<abu[7]> CAR is not tagged
<abu[7]> full 64 bits
<geri> pain
<abu[7]> each CDR is either a bignum or a short
<abu[7]> | DIG | CNT |
<abu[7]> the last cell
<abu[7]> DIG is 64 bits
<geri> CNT 60 bits?
<abu[7]> T
<geri> okay, i think i was confused cause i didnt realize you're talking about some >1 cell bignum and that's only the last cell
<geri> abcdefghijklmno => |'hgfedcba'|'onmlkji'|
<geri> i feel like truth about how bignums are stored is secretly somewhere in this line :D
<abu[7]> kind of, but reversed
<geri> oh no
<abu[7]> wait :)
<abu[7]> abcd... is in the first cell
<abu[7]> so you are correct
<abu[7]> |'cba'|'fed'|
<geri> the fact that its so inverted is pretty funny
<abu[7]> It is to access the first char(s) easily
<geri> oki
<geri> how are bignums printed? :D
<abu[7]> They are converted do decimal
<abu[7]> in a buffer on the stack
<abu[7]> also needed by 'format'
<abu[7]> (vi 'llvm~fmtNum)
<abu[7]> Nasty stuff
<geri> ah, you do walk the tree twice
<geri> to get buffer size and then to fill it
<abu[7]> not a tree, just a list
<geri> just a very imbalanced tree
<geri> )
<abu[7]> yeah
<abu[7]> For printing, short nums are handled directly though
<abu[7]> llvm~outNum
<geri> what's a BCD?
<abu[7]> binary coded digit
<abu[7]> a decimal digit in every 4 bits
<geri> okay
<abu[7]> some processors even have that as hardware instructions
<abu[7]> BCD arithmetics
<geri> oh wait, that code is indeed horrifying
<geri> :D
<abu[7]> yeah, nightmare
<abu[7]> but a lot faster than dividing the bignum by 10 for each decimal digit
<abu[7]> It avoids division completely
<abu[7]> division is the most expensive operation
<abu[7]> so it uses only bit tests, shifts and add
<geri> well at least that is nice
rob_w has quit [Remote host closed the connection]
switchy has quit [Ping timeout: 272 seconds]
switchy has joined #picolisp