IRC channel logs

2013-08-16.log

back to list of logs

<mark_weaver>the RTL compiler in wip-cps-bis is now capable of compiling my implementation of tarjan's strongly connected components algorithm. yeah!
<mark_weaver>the scc code is here: http://www.netris.org/~mhw/strongly-connected.scm
<mark_weaver>(note that wip-cps-bis doesn't use RTL by default.. you have to manually do the compilation)
<mark_weaver>okay, now to get multiple values working right.
<amk9>I just received the root passwd of my server by... mail.
<mark_weaver>Ugh. I've jumped down people's throats for that kind of stupidity before.
<mark_weaver>amk9: from whom?
<amk9>ovh
*mark_weaver seems to be one of the few holdouts that still run my server on my own hardware.
<amk9>that's what I was thinking about too
<amk9>but I can't do it right now
<mark_weaver>*nod*
<mark_weaver>I tend to worry about things like: just a handful of companies have root access to most of the servers in the world. not good.
<mark_weaver>s/servers/computers/
<amk9>what do you mean? like it's oligarchy ?
<amk9>or something else ?
<amk9>this root passwd by mail ruined my day :(
<mark_weaver>I don't think anyone should have that much power.
<mark_weaver>and it seems that it's fairly easy for governments nowadays to get almost any company to give them the keys to any server they want.
<amk9>yes
<amk9>of course it's not good
<mark_weaver>all they have to do is cry "national security" and all is theirs.
<amk9>not only national security
<amk9>it's also for our own security
<mark_weaver>heh, right :)
<mark_weaver>in related news, did you hear about how the US govt has been demanding that web companies surrender copies of their private SSL/TLS keys to the govt?
<amk9>yeah crazy
<mark_weaver>and of course, also demanding that they don't tell anyone about this.
<amk9>^^
<amk9>I was thinking that tor and the like to use to create a fork of the web
<amk9>but I don't want to be a «child porn facilitor»
<amk9>basicly I'm stuck
<amk9>forking the web to be more decentralized
<amk9>without relying on big entities to get things done
<mark_weaver>here's that article btw, for the record: http://news.cnet.com/8301-13578_3-57595202-38/feds-put-heat-on-web-firms-for-master-encryption-keys/
<mark_weaver>yeah, more decentralization would be good, IMO.
<nalaginrut>sneek: later amk9 there's 2 kinds of template in Artanis
<nalaginrut>sneek: later amk9 I think embedded-template maybe popular, but for lispers, SXML would be better ;-)
<nalaginrut>and morning guilers~
<nalaginrut>mark_weaver: any reference for our current continuation implementation?
<mark_weaver>nalaginrut: that's a question for wingo
<nalaginrut>sneek: later wingo any reference for our current continuation implementation?
<nalaginrut>sneek: later tell wingo any reference for our current continuation implementation?
<sneek>Got it.
<nalaginrut>sneek: later amk9 there's 2 kinds of template in Artanis. I think embedded-template maybe popular, but for lispers, SXML would be better ;-)
<nalaginrut>sneek: later tell amk9 there's 2 kinds of template in Artanis. I think embedded-template maybe popular, but for lispers, SXML would be better ;-)
<sneek>Got it.
*amk9 is crazy today
<amk9>well I'm investigating templating via sxml
<sneek>Welcome back amk9, you have 1 message.
<sneek>amk9, nalaginrut says: there's 2 kinds of template in Artanis. I think embedded-template maybe popular, but for lispers, SXML would be better ;-)
<amk9>doesn't sound easy thing, especially with skribeguile-reader
***chaos_ is now known as Chaos`Eternal
<nalaginrut>amk9: so what's the problem? ;-)
<mark_weaver>wingo: good morning!
<wingo>mark_weaver: morning :)
<sneek>Welcome back wingo, you have 1 message.
<sneek>wingo, nalaginrut says: any reference for our current continuation implementation?
<mark_weaver>I've had a productive hack session. the RTL compiler is now able to run my strongly connected components code: http://www.netris.org/~mhw/strongly-connected.scm
<mark_weaver>I've got multiple values working too, but I haven't yet pushed that.
<mark_weaver>I also successfully compiled my (unfinished and unpublished) implementation of continued fractions.
<mark_weaver>but it doesn't run correctly.
<mark_weaver>continued fractions arithmetic, that is. (computing streams of digits of pi and e and square roots and things like that)
<wingo>nice!
<wingo>sounds like we're getting closer
<wingo>i have a few hours to spend on that today
<mark_weaver>wingo: actually, I had a question about the stuff I've not yet pushed
<wingo>shoot
<mark_weaver>so, in the RTL VM currently, there seems to be no way to do a multiple valued return unless the number of values is a compile-time constant.
<wingo>at one point my thought was that we should do a tail call to `values'
<mark_weaver>so that left no way to fix rtl_values_code, so I removed it.
<mark_weaver>and I reimplemented RETURN_VALUE_LIST to do a little loop to unpack the values.
<mark_weaver>but I suppose the other solution would be to add a VM instruction that can do a variable number of values, and then fix rtl_values.
<wingo>that might be a good change
<mark_weaver>(the rtl_values_code you had set the number of values to 0, so it always dumped all of them)
<wingo>but we still need something that can implement `values'
<mark_weaver>yeah, it would be nice to avoid calling into C and allocating a values struct, for something so primitive and simple.
<wingo>how about we add a return-all-values op
<wingo>same as return-values but without resetting the frame
<wingo>perhaps we could change return-values to require the caller to reset the frame beforehand
<wingo>that would be the other option
<wingo>in fact that's probably the better option
<mark_weaver>how would the values be passed to return-all-values?
<wingo>they aren't passed
<wingo>well
<mark_weaver>oh, nevermind, I see.
<wingo>ok :)
<mark_weaver>but can the program set the SP manually?
<wingo>yes, via reset-frame
<mark_weaver>ah, okay.
<nalaginrut>wingo: any reference for our current continuation implementation?
<wingo>nalaginrut: nope, other than that kennedy paper i keep quoting :)
<wingo>"compiling with continuations, continued"
<wingo>mark_weaver: how did you like that paper btw?
<mark_weaver>wingo: actually, I still haven't ready. too busy debugging :)
<wingo>tsk tsk :)
<mark_weaver>s/ready/read it/
<mark_weaver>yeah, I know. too impatient perhaps.
<mark_weaver>:)
<nalaginrut>wingo: well, it seems the paper is about how to build backend with continuation, not the way to implement the continuation
<nalaginrut>I'd like to know our current implementation of continuation
<nalaginrut>first
<wingo>nalaginrut: continuations are just labels -- they are the same as basic blocks in other compilers
<mark_weaver>wingo: I see that reset-frame takes a constant NLOCALS value. How could this be used to implement 'values' ?
<wingo>mark_weaver: remove the NLOCALS arg
<wingo>remove the RESET_FRAME() inside
<wingo>require callers to have reset the stack frame appropriately beforehand
<wingo>ah
<wingo>sorry
<mark_weaver>no, I mean that the 'reset-frame' op also takes a constant NLOCALS.
<wingo>right, so for `values'
<wingo>you just don't reset the frame :)
<wingo>the caller will have set it beforehand
<mark_weaver>it might be interesting to allow the possibility of a more general manipulation of the SP and arbitrary slots within.
<wingo>the body of `values' is just return-values
<wingo>nothing else
<mark_weaver>oh, I see.
<mark_weaver>that's nice.
<mark_weaver>you're basically reusing the 'apply' machinery to do the job.
<wingo>yep
<mark_weaver>it's nice to see the symmetry between returns and calls there.
<wingo>indeed
<mark_weaver>okay, time to rework my patch :)
<mark_weaver>wingo: fyi, I added code to the tree-il->cps compiler to handle list primcalls specially: it converts it to chain of conses. does that seem reasonable to you?
<wingo>mark_weaver: i saw that
<wingo>i would rather do that kind of thing in an early pass, but i guess it doesn't really matter
<wingo>for example the arity conversion pass seems perfect for that kind of thing
<wingo>dunno tho
<mark_weaver>I did it earlier than that.
<wingo>yes, but it mixes concerns -- cps conversion really has nothign to do with the list primcall
<wingo>but anyway, it does not matter much
<mark_weaver>yeah, I see what you mean.
<wingo>and it's a good transformation, whereever we put it :)
<mark_weaver>'cons*' could also be made a useful primitive with the RTL VM.
*nalaginrut is reading the basic blocks on textbook...
<wingo>o
<wingo>i'd rather just do cons
<mark_weaver>okay
<wingo>it's not variadic ;) -- and it is more amenable to cse
<wingo>and the kind of "projection" optimizations that kennedy does in that paper
<mark_weaver>would the same arguments apply to 'list' ?
<wingo>yep
<mark_weaver>if so, maybe 'list' should be converted even earlier, within the tree-il primitives passes?
<wingo>indeed!
<mark_weaver>though maybe we can't do that until we dump the stack VM.
<wingo>dunno, i think we could do it now
<wingo>the perf impact is not too much i don't think, and it makes rtl/cps easier
<mark_weaver>and just not use the 'list' instruction (except for loading literals) ?
<wingo>yep
<mark_weaver>I guess that would be fine for master anyway, since the stack VM won't be around much longer :)
<wingo>we hope, yes ;)
<wingo>maybe within a month, who knows
<wingo>i'm going to be busy with work until mid-september, then comparably free thereafter
<mark_weaver>*nod* and in the meantime, we'll see how long my hyper-motivated state lasts, and how far I can go with it :)
<wingo>:-)))
<nalaginrut>nice, got it
<mark_weaver>wingo: one more thing: the 'apply' instruction is causing trouble with the logic in cps/primitives.scm. it gets the arity wrong, and defeats the needed conversion of 'apply' primcalls to normal calls.
<mark_weaver>wingo: one solution is to specially remove it from the computed hash table. another is to rename the VM instruction. any preference how to solve it?
<wingo>rename the VM op I guess?
<wingo>wdyt?
<mark_weaver>yeah, I think that's probably best.
<mark_weaver>how about 'tail-apply' ?
<wingo>sgtm :)
*wingo loves the wdyt / lgtm / sgtm abbreviations, as you can tell ;-)
<wingo>perhaps it's too much :)
<mark_weaver>saves typing :)
<mark_weaver>for that matter, I wonder why we bother with all these special cases and aliasing tables and so on. why not just name the VM instructions to match the primitive names?
<mark_weaver>well, we can talk about that later.
<wingo>in cases like this it's that the arity requirements of the VM ops and the Scheme primitives are different...
<wingo>some ops are more functional, like cons and add and such things (though add could be called +, you are right)
<nalaginrut>for a simplest toy AOT compiler, just write a bunch of emit:rtl->asm in wip-cps-bis...
<wingo>nalaginrut: indeed; and if you did it right, you could produce a valid ELF file
<nalaginrut>but it's not clear for me that where did the register coloring done
<nalaginrut>or I have to do it in emit?
<wingo>well for a simple aot compiler, you don't allocate registers
<wingo>you assume that values live in stack slots
<nalaginrut>yes, but register allocation is important IMO
<wingo>so for emitting each individual op, you load operands from memory into whatever registers you want
<wingo>heh, yes it's important but it can be added as a second step
<nalaginrut>I want to know if registers could be allocated in rtl, or rtl level could provide some info
<nalaginrut>ah~yes
<nalaginrut>make a easier thing first
<wingo>the way that usually works is that you parse bytecode into an intermediate language, and allocate registers on that IL
<mark_weaver>I suspect that it's a lose to blindly compile everything to machine code, because the code would be so much bigger.
<wingo>but that's pointless if you're compiling from scheme, because cps is already a good IL
<nalaginrut>IIRC, wingo told me there're some things dwells in runtime, like libguile
<mark_weaver>better to compile only the hot code, IMO.
<wingo>so you should go directly CPS->asm
<nalaginrut>I don't think we throw everything into native code
<wingo>dunno, i think it's fine to compile everything aot
<wingo>i guess we'll have to see :)
<mark_weaver>oh, compiling everything to machine code is great for benchmarks.
<mark_weaver>but everything becomes more bloated too.
<nalaginrut>well, I said no because I think it's hard(impossible?) to put all of the into native code, no?
<nalaginrut>s/the/the things
<mark_weaver>no, it's not hard.
<nalaginrut>ah~excellent to hear that~
<Chaos`Eternal>but memory is cheap...
<mark_weaver>memory is cheap, but cache behavior is extremely important for performance on modern machines.
<wingo> http://webyrd.net/scheme-2013/
<mark_weaver>whether you can keep your active set entirely in the cache can make a huge difference.
<nalaginrut>I recalled the old joke
<nalaginrut>there're only two real hard problem in computer science, name, and cache hit rate (something like that)
<wingo>heh
<nalaginrut>emm..so we'd better try hard to make them all-in-native
*nalaginrut is trying a (+ 1 1) to powerful AOT~
<nalaginrut>mark_weaver: could you give me a hint again how to enable rlt?
<nalaginrut>rtl?
<nalaginrut>I'm in wip-cps
<nalaginrut>I'm in wip-cps-bis
<mark_weaver>(use-modules (system vm assembler) (system base compile) (language cps))
<mark_weaver>(define* (my-compile x #:key (env (current-module))) ((assemble-program (compile x #:env env #:to 'rtl))))
<nalaginrut>thanks
<wingo>it's really not ready for use yet though
<mark_weaver>and then you can do something like (my-compile '(define (foo x y) (+ x y)))
<wingo>you are welcome to hack on it but you shouldn't expect it to work :)
<mark_weaver>yeah, only simple things work right now. a lot of stuff is still broken, and even the stuff that works is slower than the stack VM right now.
<mark_weaver>because the compiler is missing some important passes.
<nalaginrut>at least (+ 1 1) could generate reasonable rtl-bytecode
<wingo>that works already, yes
<nalaginrut>hmm...compiling, it's updated today
<mark_weaver>you can also load a whole file like this: (my-compile '(include "/home/mhw/src/continued-fractions/continued-fractions.scm"))
<nalaginrut>OK
<nalaginrut>well, it's a nice hint I never thought
<wingo>me neither, neat trick :)
<nalaginrut>alas~(+ 1 1) is not the case since it's reduced to 2 in partial-evaluation...
<mark_weaver>normally I'd just use 'load', but that will use the stack VM right now.
<mark_weaver>nalaginrut: and then of course you can use ,x to look at the code.
<mark_weaver>right now there are a lot of unnecessary moves, and loops are compiled into proper loops but rather closure creation and tail calls.
<nalaginrut>I can't use ,x when it's a value
<mark_weaver>*are NOT compiled into proper..."
<wingo>mark_weaver: where do the unnecessary moves come from?
<nalaginrut>no problem, simple AOT just translate rtl to asm now
<nalaginrut>so let's eliminate the redundant things later
<mark_weaver>wingo: I'm not sure exactly, but I see them quite often in the disassembly.
<wingo>i probably haven't tested programs as big as the ones you are trying
<mark_weaver>things like constants or toplevel variables loaded into one register and them immediately moved somewhere else to do a call or something.
<nalaginrut>well, I can't try (+ 1 1), maybe another better way?
<wingo>yes, calls are an issue
<wingo>nalaginrut: pass #:opts '(#:partial-eval? #f) to the compile invocation
<nalaginrut>oh~nice
<nalaginrut>it's cool to disable it
<wingo>and if you want the compiled thunk, remove the extra set of parens from around assemble-program
<mark_weaver>the register allocator should be smart about cases where some value needs to go into a fixed register slot.
<mark_weaver>but then you get the loading instructions.
<wingo>mark_weaver: indeed, it could be quite a bit smarter -- not sure how to do that exactly; would be nice to express some of these aspects in cps somehow
<mark_weaver>better to wrap your inner expression in (lambda () ...)
<nalaginrut>seems there's no #:partial-eval? in compile?
<wingo>nalaginrut: but there is #:opts :)
<mark_weaver>even one the lambda papers talks about register allocators that take into account when values are constrained to be in a certain register. it's very old tech.
<nalaginrut>(define* (my-compile x #:key (env (current-module))) ((assemble-program (compile x #:env env #:to 'rtl '(#:partial-eval? #f)))))
<nalaginrut>;;; <stdin>:9:0: warning: possibly wrong number of arguments to `compile'
<mark_weaver>or maybe I'm thinking of the rabbit thesis... anyway, quite old.
<wingo>nalaginrut: you are missing the #:opts
<mark_weaver>I don't remember the details of the algorithms though. I'll have to read up.
<nalaginrut>oops
<nalaginrut>mark_weaver: register coloring?
<mark_weaver>no, that's different.
<mark_weaver>well, I think it is. maybe I'm forgetting.
<mark_weaver>It's been a while since I looked into register allocators, and it's mostly down the memory hole.
<nalaginrut>no, it's reduced to 2 anyway
<nalaginrut>Guile2 loves optimization
<mark_weaver>nalaginrut: just make a procedure that does math on its arguments. the optimizer can't assume anything about the arguments then.
<mark_weaver>e.g. (define (foo x y) (+ x y))
<nalaginrut>ok
<wingo>(define* (compile-via-rtl exp #:key peval? cse?)
<wingo> (assemble-program
<wingo> (compile exp #:to 'rtl #:opts `(#:partial-eval? ,peval? #:cse? ,cse?))))
<mark_weaver>I'd turn peval back on.
<nalaginrut>ok I get it
<nalaginrut>(add 1 1 2) (return 1)
<nalaginrut>easy emit ;-D
<mark_weaver>wingo: fwiw, I find it much more convenient to compile within the current module, for testing.
<wingo>yep
<nalaginrut>wait, I could get the rtl code with ',x', but I need it to be a s-expr, then I could parse it then emit
<mark_weaver>if you want to rtl code, then pass #:to 'rtl to 'compile', as wingo suggested above.
<mark_weaver>but that will be much longer, which things like labels and macro instructions and so on.
<nalaginrut>I passed #:to 'rtl
<nalaginrut>but it's a procedure as a result
<mark_weaver>it gives you a much less clear picture of how long the program is in the machine.
<nalaginrut>I can use ,x on it
<nalaginrut>is there any way to get the rtl code as s-expr?
<mark_weaver>don't run it through 'assemble-program'.
<nalaginrut>nice
<nalaginrut>the result is not as clear as ,x
<nalaginrut>how to fix it?
<wingo>nalaginrut: there is no fix
<wingo>i don't think the compiler is ready for what you want to do
<wingo>and we should probably spend time making it work before documenting it
<mark_weaver>+1
<nalaginrut>yes, it's just a try
<wingo>so i would suggest waiting
<wingo>and if you can't wait, then read a lot of code and see if you can figure it out
<nalaginrut>anyway, we don't have a mature rtl now
<wingo>i'm happy to answer questions about hacking on it, but it is not ready for users
<wingo>and in this case you would be a user :)
<mark_weaver>yes, keep in mind that the more time we spend answering questions, the less time we have to work on improving it :)
<nalaginrut>ok, so my question is how can I get the most useful info from the rtl-assembly code?
<nalaginrut>it provides too much now
<wingo>that s-expression is input to assemble-program
<wingo>look at rtl.test and assembler.scm to understand it.
*nalaginrut is reading
<mark_weaver>hmm. something is going wrong in 'receive-values'. not sure yet whether the bug is in the VM code or the compiler.
<mark_weaver>it thinks it's not getting enough values, but it should be.
<wingo>mark_weaver: the first value is in slot 0 fwiw
<wingo>er
<wingo>slot 1
<nalaginrut>why not include all the instructions to begin-program?
<nalaginrut>then I could get all of this 'begin-program with assoc-ref
<nalaginrut>but now I have to check&fetch each s-expr
<mark_weaver>the first argument to receive-values (PROC). should that be the same slot that was used as PROC in the immediately preceding 'call' instruction? because it's off by one.
<wingo>nalaginrut: i'm very sorry, but i just don't have time to help you with your use case
<wingo>mark_weaver: ah, receive-values, not return-values. sorry got confused
<mark_weaver>so what I'm compiling here is simply (receive (q r) (floor/ n d) (list q r))
<nalaginrut>never mind, but is it proper to raise a request for that? or patch?
<wingo>nalaginrut: no, it's not
<wingo>that's just not how the new vm works
<nalaginrut>ok
<wingo>sorry :/
<mark_weaver>and the generated code is: (mov 7 3) ;floor/ (mov 8 1) ;n (move 9 2) ;d (call 7 3) (recieve-values 8 2)
<mark_weaver>does that look right?
<wingo>mark_weaver: looks like that should be (receive-values 7 2)
<mark_weaver>yeah, that was my thought also.
<mark_weaver>thanks!
<wingo>np :)
<mark_weaver>heh, the code is: (emit `(receive-values ,(1+ proc-slot) ,nreq))
<mark_weaver>a very deliberate off-by-one error :)
<mark_weaver>I guess the design changed along the way, as it often does :)
<wingo>yes indeed
<wingo>sorry about that!
<wingo>the calling convention was one of the last things to fall into place
<mark_weaver>don't apologize, I'm extremely grateful for all you've done here :)
<wingo>as you have seen it wasn't a soft landing ;)
<mark_weaver>code this complicated naturally has a difficult birth. I'm glad to be able to help with some of this debugging drudgery.
<wingo>:)
<mark_weaver>I just want to see the RTL compiler+VM generate 1000 digits of pi before I go to sleep. that's all I ask :)
<wingo>hehehe ;-)))
<mark_weaver>well, it generates 1000 digits of 1/7 now. that's progress.
<wingo>!
<mark_weaver>and sqrt(2) :)
<mark_weaver>and phi
<mark_weaver>and e
<mark_weaver>but still not pi. hmm.
<wingo>that's funny
<mark_weaver>something is trying to apply 1 as a procedure. where oh where is this bug.
<mark_weaver>yes, 1000 digits of pi !! :)
<mark_weaver>oh no.. that was the wrong window.
<wingo>drama!
<mark_weaver>nevermind, it still can't.. oh well.
<mark_weaver>hehe
<taylanub>BTW do you work with C-like structs a lot while working on the compiler ? ISTR someone mentioning that the "bytestructures" module I was working on could be useful there; it got some improvements since it's conception, if you're interested: https://github.com/taylanub/scheme-bytestructures
<wingo>taylanub: i did work with that a lot when i was working on the linker, but the linker is done now i think
<taylanub>Aw, I was too slow. :P
<wingo>why do you say that?
<taylanub>Maybe it would've been useful to you.
<wingo>you can still submit patches to make the linker nicer to read :)
<taylanub>Hrm, will check.
<wingo>(system vm linker) and (system vm elf)
<taylanub>BTW I'm planning to make a tool that reads .h files and spits out bytestructure descriptors; that should make for some neat automated C library integration.
<wingo>neat
<mark_weaver>that would be great!
<nalaginrut>I realized that current rtl is valid for anonymous function, not a regular function
<nalaginrut>but never mind
<nalaginrut>for regular function, it seems emit stackVM code
<nalaginrut>s/code/instruction
<mark_weaver>(my-compile '(define (foo x y) (+ x y))) makes foo into RTL code for me.
<nalaginrut>(use-modules (system base compile) (system vm assembler)) (define* (my-compile x #:key (env (current-module))) ((assemble-program (compile x #:env env #:to 'rtl))))
<nalaginrut>scheme@(guile-user)> (define (add x y) (+ x y))
<nalaginrut>scheme@(guile-user)> (my-compile 'add)
<nalaginrut>$1 = #<procedure add (x y)>
<nalaginrut>scheme@(guile-user)> ,x $1
<nalaginrut>Disassembly of #<procedure add (x y)>:
<nalaginrut> 0 (assert-nargs-ee/locals 2) ;; 2 args, 0 locals
<nalaginrut> 2 (local-ref 0) ;; `x'
<nalaginrut> 4 (local-ref 1) ;; `y'
<nalaginrut> 6 (add)
<nalaginrut> 7 (return)
<nalaginrut>but it's OK for anonymous function
<mark_weaver>the define has to be done within the quoted part passed to my-compile.
<nalaginrut>ah~no, I should define the function in the expr passed into my-compile
<nalaginrut>yes, I realized it
<nalaginrut>sorry for bad question
<mark_weaver>wingo: I think the bug is in the parallel moves solver. it's doing the moves in the wrong order, and botching one of the things being moved.
<wingo>bummer!
<wingo>you should be able to print out the source and destination regs and the tmp var and compare that to the solution
<mark_weaver>it needs to swap 1 and 3, and it's doing (mov 1 3) (mov 5 3) (mov 3 1)
<wingo>strance
<wingo>*strange
<wingo>it should be (mov 5 3) (mov 3 1) (mov 1 5)
<wleslie>strance: what you find yourself in when strace is too verbose
<wingo>or (mov 5 1) (mov 1 3) (mov 3 5)
<wingo>wleslie: :-)
<mark_weaver>right
<mark_weaver>haha
<wingo>val aurora had a nice article on that in lwn a while back
<mark_weaver>and indeed, (solve-parallel-move '(1 3) '(3 1) 5) => ((3 . 1) (3 . 5) (1 . 3))
<wingo>broke as a jok!
<wingo>joke!
<mark_weaver>wingo: did you base this on any documented algorithm?
<wingo>mark_weaver: no i didn't
<wingo>i had had a few in mind but didn't base it on a paper
<mark_weaver>my strongly-connected-components code (which performs very well even on large sets) might help here.
<mark_weaver>I've never thought about this problem though.
<wingo>could be, yes -- but probably in this case it's best to just fix this bug
<mark_weaver>*nod*
<wingo>swap the first two args to cons* on line 164
<wingo>they are in the wrong order, as the list is being built backwards
<mark_weaver>ah, thanks!
<nalaginrut>almost done, but add/mov could only support immediate number
<mark_weaver>now it outputs ((3 . 5) (3 . 1) (1 . 3))
<wingo>so that's broke still ;)
<wingo>instead of (cut . dst) it should be (src . cut)
<mark_weaver>ah, that looks better now!
<mark_weaver>((1 . 5) (3 . 1) (5 . 3))
<wingo>whew ;)
<mark_weaver>okay, but will this get me 1000 digits of pi or not? let's see..
<mark_weaver>3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095505822317253594081284811174502841027019385211055596446229489549303819644288109756659334461284756482337867831652712019091456485669234603486104543266482133936072602491412737245870066063155881748815209209628292540917153643678925903600113305305488204665213841469519415116094330572703657595919530
<mark_weaver>yeah!!!
<wingo>sweet!!
<wingo>pastebin the source and disassembly? i guess if there are a bunch of closures the disassembly will be terrible
<wingo>in that case i guess we can wait for contification :)
<wingo>i'd like to see if i can do that today
<mark_weaver>it's a pretty big program
<wingo>ok, nm then :)
<mark_weaver>I'm willing, but how do I disassemble such a large number of procedures?
<wingo>yeah the disassembler doesn't recursively traverse referenced procedures
<wingo>would be nice to run it on an entire elf image too
<wingo>anyway, thoughts for later i guess
<mark_weaver>of course, this code is currently using some of the hacks that we decided not to go with..
<mark_weaver>so maybe I shouldn't check all this in yet.
<mark_weaver>well, hacks is a strong word.
<mark_weaver>the loop within RETURN_VALUE_LIST is the main thing
<mark_weaver>also, for now I just removed 'apply' from the cps/primitives hash table.
<wingo>i don't mind having a loop there, fwiw; doesn't matter much to me
<mark_weaver>well, it's up to you. I can push this stuff if you like.
<mark_weaver>I'll pastebin my current patch.
<wingo>push to a branch perhaps?
<mark_weaver>sure, how do I do that again?
<mark_weaver>will git push just work in my new branch?
<wingo>git push origin the-name-of-the-branch-i-am-on
<mark_weaver>okay
<mark_weaver>I'll push the obvious fixes to wip-cps-bis though.
<wingo>great
<nalaginrut>well, I don't know how to get the value from rtl register, so it's just a toy
<nalaginrut>but looks like it work ;-P
<nalaginrut> https://gist.github.com/NalaGinrut/6248540
<wingo>heh, neat ;)
<nalaginrut>and it can't be assembled ;-(
<nalaginrut>but it's trivial ;-D
<nalaginrut>anyway, I think some fundamental infrastructures(framework) could be done in advance
<nalaginrut>say, x86 asm mapper
<mark_weaver>wingo: okay, it's all pushed. some to wip-cps-bis, and the fixes that should probably be done differently are in wip-cps-mhw.
<wingo>mark_weaver: super, thank you!
<mark_weaver>and now I must sleep. happy hacking!
*mark_weaver --> zzz
<wingo>happy zzz!
<taylanub>I wonder what the best approach to the tool I have in mind would be; a GCC plugin (Guile has bindings), or a from-scratch parser for the CPP and C grammars, or something else ?.. Glancing over the plugin API, it looks like I won't be able to work on #defines with that .. ideally the tool should also see #define constants and such.
<taylanub>In fact the order of e.g. #define directives and typedefs should be kept the same in the resulting .scm, so I probably want something that parses and partially interprets both languages at one go.
<wleslie>taylanub: is it doing what this is doing (see the examples): http://cffi.readthedocs.org/en/release-0.7/
<wingo>taylanub: i would use guile-dlhacks
<wingo>otherwise do what civodul does and run the c compiler at macro expansion time
<mark_weaver>taylanub: you can run cpp to just do the macro expansion.
<mark_weaver>the C preprocessor, that is.
<taylanub>wleslie: Not exactly, from what I see. We already have an FFI, with pointers and bytevectors and stuff; now I have a module that basically implements C's type-system in a dynamic manner, to be used on bytevectors, and the goal now is to automatically read types in an .h and output Scheme code that creates the equivalent types in the Scheme module. But I now realize that it would be most neat if I also translated #define and such
<taylanub>things at the same pass, making a full translation of a .h file.
<taylanub>mark_weaver: That way I'll lose the order of #define directives vs. typedefs in the .h ...
<mark_weaver>is this just for aesthetics?
<taylanub>I guess so.
<wleslie>taylanub: this does allow doing things like using C macros from within python
<mark_weaver>in the general case, the C preprocessor can do quite a bit. for example, you could have one macro that expands into a typedef, and is then used multiple times.
<mark_weaver>you can even (awkwardly) do loops and recursions.
<taylanub>Hrm, I'll look into this later, need to go now. And sleep well. :)
<mark_weaver>okay, happy hacking!
<mark_weaver>and now, to sleep, really this time :)
<taylanub>wingo: dlhacks is rather for run-time FFI things, isn't it ? I'm thinking of a static .h -> .scm translator, although maybe that isn't the best approach.
<wingo>you could do a static debuginfo -> scm translator
<taylanub>That will miss #define constants and such though, won't it ?
<wingo>not necessarily
<wingo>depends on your toolchain
<wingo>if the #define constants are not actually constants but C expressions, then you could lose
<wingo>but that's life...
<taylanub>I'm inclined to write a CPP+C parser from scratch, parsing .h files in one go as if they had a single grammar instead of a two-layered one, fine-tuned to view the files as an abstract API declaration, so to say; will incorporate reinventing parts of the wheel but it feels like the most correct approach.
<wingo>have fun; sounds like a waste of time to me, but whatever floats your boat :)
<amk9>héllo again
<amk9>can a sexpr «expand» to the content of another file ?
<taylanub>amk9: AFAIK `include' is a macro that expands to the contents of another file.
<amk9>indeed
<amk9>thx
<amk9>I should have guessed it
<amk9>:)
<taylanub>np :)
<amk9>so I got something that I think can be used as template language
<amk9>I mean
<amk9>I think we need to mind meld or something about this templating things
<amk9>taylanub: your message was not clear, there is a sxml template language or not in artanis ?
<taylanub>I don't know anything about artanis .. did you mean to ask nalaginrut ?
<amk9>sorry :)
<amk9>I'm looking at the code it will less disturbing
<amk9>sneek: sorry are you the bot ?
<sneek>I'll keep that in mind.
<amk9>sneek: help
<taylanub>I wonder why it replied to the question that way. :P
<add^_>the are
<add^_>"are"
<taylanub>Oh .. I think it interpreted it as '"sorry" are "you the bot"' :D
<add^_>sneek: sorry?
<sneek>Someone once said sorry is you the bot ?
<taylanub>LOL
<taylanub>That's hilarious.
<amk9>sneek: are?
<amk9>sneek: sorry?
<sneek>Last time I checked sorry is you the bot ?
<taylanub>sneek: forget sorry
<sneek>Okay.
<taylanub>sneek: sorry?
<add^_>heh
<add^_>poor sneek
<taylanub>sneek: botsnack :)
<sneek>:)
<add^_>:-D
<amk9>sneek: later tell nalaginrut I came to the same point as you in artanis regarding templating, there is probably the django template style way, but I think tpl->html is more powerful. The only thing I would have liked is to be able to use brackets to delimit strings like in skribilo because it is more readable see my enlightenment here http://lists.nongnu.org/archive/html/skribilo-users/2013-08/msg00004.html
<sneek>Okay.
<add^_>sneek: karma?
<add^_>Hmmmm ;-)
<add^_>sneek: botsnack
<sneek>:)
<amk9>sneek: later ask nalaginrut what do you think ?
<sneek>Okay.
<amk9> http://www.gnu.org/software/guile/manual/html_node/Web-Examples.html
<taylanub>How do we generally handle C extensions that compile to significantly different code between platforms, when we want to use them for FFI ?
<taylanub>Hrm, well, I guess an FFI just relies on whatever stable ABI a C library provides, if any.
<dsmith-work>Happy Friday, Guilers!!
<taylanub>Happy Friday!
<mark_weaver>taylanub: all we depend on is the C calling conventions, which are generally standardized for each platform (or at least there are a small number of ABIs per platform).
<mark_weaver>the aspects of structure layout that are not fixed by the C standards are also part of the platform ABI.
<mark_weaver>taylanub: btw, if you write your own C preprocessor from scratch, you'll have to include tables of the predefined preprocessor symbols for each platform.
<mark_weaver>taylanub: for example, on 32-bit x86, there are bunch of symbols like __i386__ that are predefined. for 64-bit, it's something like __X86_64__. For ARM, there are on the order of a couple dozen such symbols, depending on which revision of ARM you're compiling for.
<mark_weaver>taylanub: and I suspect that if you actually go that route, you will find that in the general case, there's no way to match the order of the definitions in the source file.
<mark_weaver>IMO, for years you'd be dealing with obscure bugs popping up due to incompatibilities between your CPP and the standardized ones.
<mark_weaver>having said all that, there are probably some simple hacks you could do that would *try* to match the order of the source file in common cases, while still using standard CPP.
<mark_weaver>e.g. use the output of CPP to generate your actual values and types, and then use a crude scan through the original source file to try to mostly sort the definitions in the best order.
<stis>hmm , is this correct?, ... (... ...) ((... ...) (... ...))
<stis>eg. quoting ... on different levels.
<mark_weaver>heh, yeah, I think so.
<stis>shuldn't the last level be (... ... ...) ?
<mark_weaver>that might work too, I forget.
<stis>it own't work
<mark_weaver>I've never done that more than one level deep.
<stis>"^x complecity in depth :-)
<stis>2^x complecity in depth :-)
<mark_weaver>maybe (... (... ...)) ?
<mark_weaver>(untested)
*stis looks in the manual
<mark_weaver>R7RS has a way to specify which ellipsis symbol will be used for each level, so you can avoid this mess.
<mark_weaver>(we haven't yet implemented it in guile yet though)
<mark_weaver>well, you can specify for each instance of syntax-rules, I mean.
<stis>that would be a perfect solution!
<mark_weaver>yeah. I started to work on a patch for that once.
<mark_weaver>I think it ended up being more of a pain than I thought, and I got distracted by something else. but I'd definitely like to add that feature to guile.
<stis>I will wait with my 4 level macros until this materilizes :-)
<mark_weaver>or maybe it was that it would change our ABI in a subtle way.
<mark_weaver>(by changing the representation of syntax objects)
<mark_weaver>I don't remember.
<mark_weaver>something to look into for guile-master, at least.
<stis>yeah
<mark_weaver>ah, I just looked it up. so here's the rule: (... <template>) is treated exactly like <template> except that within <template>, the ... has no special meaning.
<mark_weaver>so the common thing is to do (... ...) to escape just a single ellipsis.
<mark_weaver>so (... (... ...)) should work.
<mark_weaver>... (... ...) (... (... ...)) (... (... (... ...)))
<mark_weaver>that's not so bad I think
<mark_weaver>beware that this (... ...) thing, while widely implemented, is not in the R5RS.
<stis>I guess this is acceptable!
<stis>thx
<mark_weaver>in R7RS, the syntax is (syntax-rules <ellipsis> (<literal> ...) <rule> ...)
<mark_weaver>where the optional <ellipsis> datum can be whatever you want.
<mark_weaver>(well, any symbol)
<stis>that would ease on the eyes indeed
***Guest77236 is now known as jao
<taylanub>mark_weaver: I see; implementing a CPP for this seems nowhere as simple as I imagined. I also just noticed system/base/target.scm which seems to do the job (e.g. in system/vm/{elf,linker}.scm) which predefined CPP macros do in .h files, but in a radically different way; this further complicates translation from .h to .scm. I guess I'll just implement a 90% solution and expect human intervention on the resulting .scm.
<amk9>I'm trying to unescape some html while using sxml->xml, but I fail
<amk9>can you recommand something please ?
<amk9>I read somewhere that I should use SRV:send-reply but it's low level, and I can't understand how it works
<amk9>SRV: send-reply from (sxml transform)
<amk9>or maybe I should implement sxml->xml on top of pre-post-order
<taylanub>What exactly is the problem ? What do you mean with "unescape HTML" ? Are you trying to insert some literal XHTML into the XML file that is otherwise generated via sxml->xml ?
<amk9>yes
<davexunit>b
<davexunit>oops
<amk9>according to Chicken doc I must use pre-post-order
<taylanub>amk9: Then I guess you'd either turn the XHTML string into an SXML structure and concatenate it with your SXML structure, or concatenate your XML string with the XHTML string.
<amk9>good idea thx
<taylanub>Turning it into SXML would be cleaner I guess.
<mark_weaver>amk9: you cannot insert raw XML as a string into SXML. instead, the idea is that you list structure.
<mark_weaver>*you use
<amk9>I use pygmentize to get highlighted code
<mario-goulart>amk9: maybe the colorize chicken egg can be handy. It's a port of some CL library. Maybe you can port it to guile.
<mark_weaver>if you want to highlight something, it might make sense to work with a procedure that takes an SXML subtree to highlight, and then transforms it.
<mark_weaver>e.g. something like (define (highlight x) `(i ,x))
<mark_weaver>(which would wrap it in <i> and </i>
<mark_weaver>and then you can apply highlight to whatever bits you want.
<mark_weaver>note that there's also xml->sxml, that goes in the other direction. so you could convert the output of pygmentize into sxml.
<mark_weaver>and then insert it into a larger tree, or transform it, or whatever.
<mark_weaver>that's likely to be more robust than concatenating XML together as strings.
<mark_weaver>(which is prone to security flaws)
<mark_weaver>xml->sxml and sxml>xml are quite robust.
<mark_weaver>going offline for a bit. biab!
<taylanub>Hrm, this is a shame: in C one has "partial types" such that one can e.g. use "struct bar" for a field of a first-defined struct, and only later define the contents of struct bar; in my bytestructures this isn't possible because they're just first-class objects so one must create struct bar fully before being able to use it in the consturction of struct foo.
<taylanub>I suppose a partial solution would be a general-purpose `reverse-let': (reverse-let expression ((var val) ...)) but that doesn't help when one wants multiple top-level bindings of which a former uses a latter one.
<taylanub>This is quite a fundamental difference; it also means that the descriptors in my system cannot cyclically refer to each other, although it can be hacked in terms of a special descriptor type whose instances merely hold a mutable object which will later be filled with the actually desired descriptor.
<taylanub>But that's problematic because the size won't be known in advance. Ouch, quite the issue.
<taylanub>Wait, can C have cyclic structs or not ? *pulls out K&R*
<dsmith-work>taylanub: Using pointers, yes.
<dsmith-work>You can have a potiner to a struct foo; without knowing it's size.
<taylanub>Aaaah, what a relief, indeed.
<taylanub>(BTW K&R doesn't cover structs, does it ? :\\)
<dsmith-work>And for good C interface designs, you do NOT let the user see the contents of your structures.
<dsmith-work>Sure it does.
<taylanub>Oh right, it does, don't know where I got the idea from. ISTR there was some major topic that it never touched and I thought it was structs.
<dsmith-work>They even had structs way back in pre-ansi C.
<dsmith-work>taylanub: It's common do do lists like struct foo { struct foo *next; ...; };
<taylanub>Yeah, I just worried for a moment because I thought it allows that without a pointer, then noticed I can't implement it in my system, not realizing that it's fundamentally senseless due to size ambiguity. :P
<dsmith-work>Yeah. You can do it with pointers because they are always the same size. Or at least they are on sane archetectures anyway.
*dsmith-work shudders remembering "near" and "far" pointers...
<taylanub>I suppose I should be glad that I have no idea what the heck those are ? :P
<dsmith-work>Be very very thankful you do not know.
<turbofail>ha. i saw a little bit of that doing embedded development
<mark_weaver>taylanub: a struct can include a *pointer* to another struct that has not yet been defined, but it can't include another struct (inline) that has not yet been defined.
<mark_weaver>iirc, the relevant term is "incomplete type"
<mark_weaver>"near" and "far" pointers. what an unpleasant memory. I almost forgot about those :)
<mark_weaver>taylanub: that kind of thing is needed, e.g. to have mutual recursions where struct A contains a pointer to struct B, and vice versa. (or more complex graphs)
<mark_weaver>it's also useful for enforcing abstraction barriers. sometimes, a compilation unit will deal with pointers to struct B, but *never* see the definition of struct B. it just deals with the pointers.