Thanks for the tip, I think multimethods may be what i need in this case (perhaps which checks the current architecture in the dispatch function so i can disable some). I want to avoid having to pass an object around and extract methods (simply because it clutters my code). Dynamically binding methods may be another solution.
On Tuesday, April 15, 2014 11:59:17 AM UTC+12, Reid McKenzie wrote: > > Hey Andrew, I actually built something very much along these lines a few > months ago if you care to cheat off of it: > > http://github.com/arrdem/toothpick is an assembler generator system that > works more or less along these lines. Label support is still a problem I > haven't completely solved and I never did build a compiler backed targeting > Toothpick, but the idea is there. > > One approach, and the one that I took, is to make everything in your API > parametric on some representation of the target architecture. In Toothpick, > I build a monolithic map representing the target, and all the utility > functions are built in terms of operating on an arbitrary instruction > sequence in conjunction with this target description. This is probably the > easiest thing to do, as in your (accesses-memory?) you can simply enquire > of the target description structure rather than relying on the user to have > provided a multimethod implementation or anything else. > > Hope this helps, > Reid > > On Monday, April 14, 2014 6:52:36 PM UTC-5, Andrew Chambers wrote: >> >> Hi everyone, >> >> I'm new to clojure and in order to learn I'm working on making some >> compiler tools which converts a lightweight IR code into assembly. >> >> My data model for an IR function is along the lines of >> (def code >> { >> :entry >> [[:loadaddr :x "global_label"] >> [:loadconst 1 :y] >> [:add :x :y :z] >> [:jmp :exit]] >> :exit >> [[:ret :z]] >> }) >> >> This, when translated to assembly and after register allocation would >> turn into something like (ignoring calling conventions etc): >> (def assembly-code >> { >> :entry >> [[:x86.lea :eax "global_label"] >> [:x86.loadimm 1, :eax] >> [:x86.add32 :ebx :eax] >> [:jmp :exit]] >> :exit >> [[:ret]] >> }) >> >> The problem arises when I have to query the IR code for things like >> accesses-memory? or get-output-vars in an >> extensible way so that multiple target architectures can be supported. >> e.g. (get-output-vars [:add :a :b :c]) -> :c >> (get-output-vars [:x86.add :a :b]) -> :b ;; the input and output >> positions are opcode specific >> (get-output-vars [:x86.add :a :b]) -> :b >> (get-output-vars [:divmod :a :b :c :d]) -> :c :d >> (accesses-memory? :x86.add) -> false >> (accesses-memory? :x86.load) -> true >> (accesses-memory? :loadconst) ->false >> I have to be able to write these functions in a way that knows about the >> format of the basic IR opcodes, but can also be extended >> to handle opcodes of architectures that don't exist in my code yet, the >> extensions would exist within the namespaces of that specific architecture >> and shouldn't need to modify the code for the built in opcodes. >> >> What is the most seamless and efficient way to achieve this sort of >> function extension in clojure? Also, how would I allow sharing >> of implementations where instructions have similar layouts. >> >> e.g. >> (get-output-vars [:add :a :b :c]) -> :c >> (get-output-vars [:sub :a :b :c]) -> :c >> >> >> >> -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.