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.