Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Note: I completely forgot about committing all of this.

  • Loading branch information...
commit 9f2a67b60fc461c3fb4b1a6f5af5c4e2ac5f1e2b 0 parents
@ayardley authored
Showing with 4,929 additions and 0 deletions.
  1. +3 −0  .gitignore
  2. +12 −0 ChangeLog
  3. +201 −0 LICENSE
  4. +199 −0 NOTE
  5. +22 −0 README.pod
  6. +1 −0  VERSION
  7. +12 −0 docs/How_to_create_dynpmc.txt
  8. +14 −0 include/cons.h
  9. +14 −0 src/c/cons.c
  10. +20 −0 src/c/cons.h
  11. +540 −0 src/c/lisp/microlisp/2010-08-24-a-micro-manual-for-lisp-implemented-in-c.org
  12. +552 −0 src/c/lisp/microlisp/A micro-manual for LISP Implemented in C (by Nurullah Akkaya).html
  13. BIN  ...olisp/A micro-manual for LISP Implemented in C (by Nurullah Akkaya)_files/Joshva_twitter_profile_normal.gif
  14. BIN  ...lisp/microlisp/A micro-manual for LISP Implemented in C (by Nurullah Akkaya)_files/Karendirmatch_normal.JPG
  15. +30 −0 src/c/lisp/microlisp/A micro-manual for LISP Implemented in C (by Nurullah Akkaya)_files/MathJax.js
  16. +90 −0 src/c/lisp/microlisp/A micro-manual for LISP Implemented in C (by Nurullah Akkaya)_files/all.js
  17. BIN  src/c/lisp/microlisp/A micro-manual for LISP Implemented in C (by Nurullah Akkaya)_files/avatar32.jpg
  18. BIN  src/c/lisp/microlisp/A micro-manual for LISP Implemented in C (by Nurullah Akkaya)_files/avatar32_002.jpg
  19. BIN  src/c/lisp/microlisp/A micro-manual for LISP Implemented in C (by Nurullah Akkaya)_files/baguface_normal.png
  20. +124 −0 src/c/lisp/microlisp/A micro-manual for LISP Implemented in C (by Nurullah Akkaya)_files/def.html
  21. +7 −0 src/c/lisp/microlisp/A micro-manual for LISP Implemented in C (by Nurullah Akkaya)_files/def_data/beacon.js
  22. +28 −0 src/c/lisp/microlisp/A micro-manual for LISP Implemented in C (by Nurullah Akkaya)_files/def_data/quant.js
  23. +387 −0 src/c/lisp/microlisp/A micro-manual for LISP Implemented in C (by Nurullah Akkaya)_files/default.bin
  24. BIN  .../microlisp/A micro-manual for LISP Implemented in C (by Nurullah Akkaya)_files/default_profile_2_normal.png
  25. +1 −0  src/c/lisp/microlisp/A micro-manual for LISP Implemented in C (by Nurullah Akkaya)_files/defaults.css
  26. BIN  ...isp/microlisp/A micro-manual for LISP Implemented in C (by Nurullah Akkaya)_files/delicious_logo_normal.png
  27. +327 −0 src/c/lisp/microlisp/A micro-manual for LISP Implemented in C (by Nurullah Akkaya)_files/disqus.js
  28. +1 −0  ...A micro-manual for LISP Implemented in C (by Nurullah Akkaya)_files/dsq7884a9652e94555c70f96b6be63be216.css
  29. +66 −0 .../A micro-manual for LISP Implemented in C (by Nurullah Akkaya)_files/dsq7884a9652e94555c70f96b6be63be216.js
  30. BIN  src/c/lisp/microlisp/A micro-manual for LISP Implemented in C (by Nurullah Akkaya)_files/elep_normal.png
  31. +76 −0 src/c/lisp/microlisp/A micro-manual for LISP Implemented in C (by Nurullah Akkaya)_files/embed.js
  32. +51 −0 src/c/lisp/microlisp/A micro-manual for LISP Implemented in C (by Nurullah Akkaya)_files/ga.js
  33. +79 −0 src/c/lisp/microlisp/A micro-manual for LISP Implemented in C (by Nurullah Akkaya)_files/get_num_replies.js
  34. BIN  src/c/lisp/microlisp/A micro-manual for LISP Implemented in C (by Nurullah Akkaya)_files/glider_normal.png
  35. +1 −0  src/c/lisp/microlisp/A micro-manual for LISP Implemented in C (by Nurullah Akkaya)_files/highlight.bin
  36. BIN  src/c/lisp/microlisp/A micro-manual for LISP Implemented in C (by Nurullah Akkaya)_files/icon2_normal.jpg
  37. +167 −0 src/c/lisp/microlisp/A micro-manual for LISP Implemented in C (by Nurullah Akkaya)_files/jquery.bin
  38. BIN  src/c/lisp/microlisp/A micro-manual for LISP Implemented in C (by Nurullah Akkaya)_files/noavatar32.png
  39. +5 −0 src/c/lisp/microlisp/A micro-manual for LISP Implemented in C (by Nurullah Akkaya)_files/oauth.html
  40. +160 −0 src/c/lisp/microlisp/A micro-manual for LISP Implemented in C (by Nurullah Akkaya)_files/reply.html
  41. +212 −0 src/c/lisp/microlisp/A micro-manual for LISP Implemented in C (by Nurullah Akkaya)_files/reply_data/lib.js
  42. BIN  src/c/lisp/microlisp/A micro-manual for LISP Implemented in C (by Nurullah Akkaya)_files/tfc_normal.png
  43. +128 −0 src/c/lisp/microlisp/A micro-manual for LISP Implemented in C (by Nurullah Akkaya)_files/thread.js
  44. +90 −0 src/c/lisp/microlisp/A micro-manual for LISP Implemented in C (by Nurullah Akkaya)_files/upload.html
  45. +2 −0  src/c/lisp/microlisp/A micro-manual for LISP Implemented in C (by Nurullah Akkaya)_files/upload_data/a.html
  46. BIN  src/c/lisp/microlisp/A micro-manual for LISP Implemented in C (by Nurullah Akkaya)_files/zikannai_normal.png
  47. +298 −0 src/c/lisp/microlisp/A_MICRO-MANUAL_FOR_LISP-NOT_THE_WHOLE_TRUTH.pod
  48. BIN  src/c/lisp/microlisp/lisp
  49. +580 −0 src/c/lisp/microlisp/lisp.c
  50. +168 −0 src/c/lisp/microlisp/lisp_c_startup.snips
  51. +14 −0 src/c/lisp/microlisp/test.lisp
  52. +15 −0 src/c/lisp/microlisp/test.lisp.expected_output
  53. +60 −0 src/winxed/#crazy_idea.winxed#
  54. +60 −0 src/winxed/crazy_idea.winxed
  55. +112 −0 src/winxed/lisp/lisp.winxed
3  .gitignore
@@ -0,0 +1,3 @@
+# Ignore backup files
+*~
+*.bak
12 ChangeLog
@@ -0,0 +1,12 @@
+ChangeLog - A history of the changes made to the ClojurePVM distribution.
+
+2011-11-17 12:45 acy
+ * LICENSE: Added Artistic 2.0 license file.
+ * NOTE: Modified.
+ * README.pod: Modified.
+
+2011-11-16 10:45 acy
+ * ChangeLog: This log file.
+ * VERSION: File to track the current distribution version.
+ * NOTE: File to note my justifications for certain design decisions.
+ * README.pod: Readme file.
201 LICENSE
@@ -0,0 +1,201 @@
+ The Artistic License 2.0
+
+ Copyright (c) 2000-2006, The Perl Foundation.
+
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+Preamble
+
+This license establishes the terms under which a given free software
+Package may be copied, modified, distributed, and/or redistributed.
+The intent is that the Copyright Holder maintains some artistic
+control over the development of that Package while still keeping the
+Package available as open source and free software.
+
+You are always permitted to make arrangements wholly outside of this
+license directly with the Copyright Holder of a given Package. If the
+terms of this license do not permit the full use that you propose to
+make of the Package, you should contact the Copyright Holder and seek
+a different licensing arrangement.
+
+Definitions
+
+ "Copyright Holder" means the individual(s) or organization(s)
+ named in the copyright notice for the entire Package.
+
+ "Contributor" means any party that has contributed code or other
+ material to the Package, in accordance with the Copyright Holder's
+ procedures.
+
+ "You" and "your" means any person who would like to copy,
+ distribute, or modify the Package.
+
+ "Package" means the collection of files distributed by the
+ Copyright Holder, and derivatives of that collection and/or of
+ those files. A given Package may consist of either the Standard
+ Version, or a Modified Version.
+
+ "Distribute" means providing a copy of the Package or making it
+ accessible to anyone else, or in the case of a company or
+ organization, to others outside of your company or organization.
+
+ "Distributor Fee" means any fee that you charge for Distributing
+ this Package or providing support for this Package to another
+ party. It does not mean licensing fees.
+
+ "Standard Version" refers to the Package if it has not been
+ modified, or has been modified only in ways explicitly requested
+ by the Copyright Holder.
+
+ "Modified Version" means the Package, if it has been changed, and
+ such changes were not explicitly requested by the Copyright
+ Holder.
+
+ "Original License" means this Artistic License as Distributed with
+ the Standard Version of the Package, in its current version or as
+ it may be modified by The Perl Foundation in the future.
+
+ "Source" form means the source code, documentation source, and
+ configuration files for the Package.
+
+ "Compiled" form means the compiled bytecode, object code, binary,
+ or any other form resulting from mechanical transformation or
+ translation of the Source form.
+
+
+Permission for Use and Modification Without Distribution
+
+(1) You are permitted to use the Standard Version and create and use
+Modified Versions for any purpose without restriction, provided that
+you do not Distribute the Modified Version.
+
+
+Permissions for Redistribution of the Standard Version
+
+(2) You may Distribute verbatim copies of the Source form of the
+Standard Version of this Package in any medium without restriction,
+either gratis or for a Distributor Fee, provided that you duplicate
+all of the original copyright notices and associated disclaimers. At
+your discretion, such verbatim copies may or may not include a
+Compiled form of the Package.
+
+(3) You may apply any bug fixes, portability changes, and other
+modifications made available from the Copyright Holder. The resulting
+Package will still be considered the Standard Version, and as such
+will be subject to the Original License.
+
+
+Distribution of Modified Versions of the Package as Source
+
+(4) You may Distribute your Modified Version as Source (either gratis
+or for a Distributor Fee, and with or without a Compiled form of the
+Modified Version) provided that you clearly document how it differs
+from the Standard Version, including, but not limited to, documenting
+any non-standard features, executables, or modules, and provided that
+you do at least ONE of the following:
+
+ (a) make the Modified Version available to the Copyright Holder
+ of the Standard Version, under the Original License, so that the
+ Copyright Holder may include your modifications in the Standard
+ Version.
+
+ (b) ensure that installation of your Modified Version does not
+ prevent the user installing or running the Standard Version. In
+ addition, the Modified Version must bear a name that is different
+ from the name of the Standard Version.
+
+ (c) allow anyone who receives a copy of the Modified Version to
+ make the Source form of the Modified Version available to others
+ under
+
+ (i) the Original License or
+
+ (ii) a license that permits the licensee to freely copy,
+ modify and redistribute the Modified Version using the same
+ licensing terms that apply to the copy that the licensee
+ received, and requires that the Source form of the Modified
+ Version, and of any works derived from it, be made freely
+ available in that license fees are prohibited but Distributor
+ Fees are allowed.
+
+
+Distribution of Compiled Forms of the Standard Version
+or Modified Versions without the Source
+
+(5) You may Distribute Compiled forms of the Standard Version without
+the Source, provided that you include complete instructions on how to
+get the Source of the Standard Version. Such instructions must be
+valid at the time of your distribution. If these instructions, at any
+time while you are carrying out such distribution, become invalid, you
+must provide new instructions on demand or cease further distribution.
+If you provide valid instructions or cease distribution within thirty
+days after you become aware that the instructions are invalid, then
+you do not forfeit any of your rights under this license.
+
+(6) You may Distribute a Modified Version in Compiled form without
+the Source, provided that you comply with Section 4 with respect to
+the Source of the Modified Version.
+
+
+Aggregating or Linking the Package
+
+(7) You may aggregate the Package (either the Standard Version or
+Modified Version) with other packages and Distribute the resulting
+aggregation provided that you do not charge a licensing fee for the
+Package. Distributor Fees are permitted, and licensing fees for other
+components in the aggregation are permitted. The terms of this license
+apply to the use and Distribution of the Standard or Modified Versions
+as included in the aggregation.
+
+(8) You are permitted to link Modified and Standard Versions with
+other works, to embed the Package in a larger work of your own, or to
+build stand-alone binary or bytecode versions of applications that
+include the Package, and Distribute the result without restriction,
+provided the result does not expose a direct interface to the Package.
+
+
+Items That are Not Considered Part of a Modified Version
+
+(9) Works (including, but not limited to, modules and scripts) that
+merely extend or make use of the Package, do not, by themselves, cause
+the Package to be a Modified Version. In addition, such works are not
+considered parts of the Package itself, and are not subject to the
+terms of this license.
+
+
+General Provisions
+
+(10) Any use, modification, and distribution of the Standard or
+Modified Versions is governed by this Artistic License. By using,
+modifying or distributing the Package, you accept this license. Do not
+use, modify, or distribute the Package, if you do not accept this
+license.
+
+(11) If your Modified Version has been derived from a Modified
+Version made by someone other than you, you are nevertheless required
+to ensure that your Modified Version complies with the requirements of
+this license.
+
+(12) This license does not grant you the right to use any trademark,
+service mark, tradename, or logo of the Copyright Holder.
+
+(13) This license includes the non-exclusive, worldwide,
+free-of-charge patent license to make, have made, use, offer to sell,
+sell, import and otherwise transfer the Package with respect to any
+patent claims licensable by the Copyright Holder that are necessarily
+infringed by the Package. If you institute patent litigation
+(including a cross-claim or counterclaim) against any party alleging
+that the Package constitutes direct or contributory patent
+infringement, then this Artistic License to you shall terminate on the
+date that such litigation is filed.
+
+(14) Disclaimer of Warranty:
+THE PACKAGE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS "AS
+IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES. THE IMPLIED
+WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
+NON-INFRINGEMENT ARE DISCLAIMED TO THE EXTENT PERMITTED BY YOUR LOCAL
+LAW. UNLESS REQUIRED BY LAW, NO COPYRIGHT HOLDER OR CONTRIBUTOR WILL
+BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
+DAMAGES ARISING IN ANY WAY OUT OF THE USE OF THE PACKAGE, EVEN IF
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
199 NOTE
@@ -0,0 +1,199 @@
+NOTE - Note to log (and track) the justifications for various design decisions.
+
+The purpose of this file is to log and to track the reasons, the "whys," if-you-
+will, for the various design decisions or trade-offs I make throughout the life
+of this project. Hopefully, this will prove useful.
+
+I. To begin, I lay out certain of my personal biases and foundational premises
+for the ClojurePVM project:
+
+ 1. Let's keep it positive: I really dislike Java.[1]
+
+ 2. While I don't loathe the JVM, which, to be frank, is a rather,
+ sophisticated piece of technology, it is, nonetheless,
+
+ (a) controlled, in the main, by whichever corporation holds the
+ copyright;[2]
+ (b) lacks tail-call optimization, which, though is not a deal-breaker,
+ significantly reduces certain optimizations;
+ (c) is a stack-based virtual machine and, consequently, is,
+
+ (1) a'bit slow;
+ (2) does not easily allow for coroutines; and
+ (3) does not easily allow for continuations.
+
+ 3. I, on the other-hand, like Perl.[3]
+
+ 4. I also like, and am a fair-hand at, C.
+
+ 5. I have, over the past coupl'a years, really come to love Lisp, especially
+ Common Lisp. Unfortunately, it just isn't all that accessible to a'whole peck
+ o'folks and, truth-be-told, it has some real crufty bits.[4]
+
+All of which brings me to Clojure:
+
+ 6. Clojure is a Lisp! And it, largely,
+
+ (a) overcomes some of the more crufy bits of earlier Lisps and
+
+ (b) "Clojure gets data-structures right." Puzzler, "Thoughts on
+ Programming: Racket vs. Clojure" (Tuesday, August 10, 2010)
+ (http://programming-puzzler.blogspot.com/2010/08/racket-vs-clojure.html).
+ This simple statement belies the, alomst revolutionary, nature of the
+ statement. Why? Because, really, trully, no-kidding-'round here, it is all
+ 'bout the data structures. See id. To further quote the article,
+
+ * Clojure provides a full complement of (immutable!) data structures you
+ need for everyday programming and a bit of syntactic support for making
+ those manipulations more concise and pleasant.
+
+ * All of the collections are manipulated by a small number of polymorphic
+ functions that are easy to remember and use.
+
+ * Traversals over all collections are uniformly accomplished by a
+ sequence abstraction that works like a lazy list, which means that
+ Clojure's higher order sequence functions also apply to all collections.
+
+ This, coupled with the persistence -- which is NOT serialization -- of its
+ data structures makes Clojure ... a very powerful programming language.[5]
+
+ 7. Unfortunately, all of the goodness of (6) above is seriously undermined
+ because Clojure is, primarily,[6] implemented in Java on the JVM.
+
+Taking all of the above items into account, this project seems ... inevitable.
+The only "real" obstacles have been and, to some extent, still are (1) the
+relatively high barrier, presently, in-place just to "figure things out" in
+Parrot enough to get oneself on the correct[7] development track[8]; (2) the
+prior lack[9] of a high-level language [hereinafter HLL] with which to write
+something like ClojurePVM;[10] and the lack of any "real"
+HLL-interoperability.[11]
+
+Hence ..., this project.
+
+ NOTE: I will, at some point, revision, somewhat, some of the above. For
+ example, I need to draw a closer connection between the relavence of items (3)
+ and (4) above -- though it is fairly obvious -- to Parrot and ClojurePVM.
+
+
+II. I have decided, after a great deal of reflection, to write the initial
+intepreter in winxed. I will, perhaps, also write a version in PCT and, then,
+benchmark the two approaches to discover which, of the two, I prefer. Also, at
+this time, I will defer writing a stage0 compiler -- which I would write in C --
+with which to bootstrap ClojurePVM.
+
+ Why not write a stage0 compiler? Well, because to do so, would require
+writing a compiler to emit PIR code, which I could do, but, honestly, I want to
+move forward.[12] If, however, writing the interpreter in winxed or PCT proves
+too slow, I will re-write everything using a stage0 compiler.
+
+
+
+
+
+
+
+
+--------------------
+[1] I could go, on-and-on about the things I dislike about Java -- and, in the
+first draft of the text accompanying this footnote, I did! -- But, since I'm
+trying to keep things "relatively" positive, I'll just sum up my objections with
+this brief observation: Java is a quintessential "blub" language, see Paul
+Graham, "Beating the Averages" (specifically, the section entitled, "The Blub
+Paradox" at http://www.paulgraham.com/avg.html); see also "A Conversation with
+Alan Kay: Big talk with the creator of Smalltalk—and much more" (specifically,
+Alan Kay's comments on Java at http://queue.acm.org/detail.cfm?id=1039523), and
+leave it at that.
+
+[2] The consequence of which is, development is wholly contingent upon the
+mercies (read, bottom-line) of the copyright-holder.
+
+[3] I liked it much more before the OOP-demiurgos gotta hold of it, but, with
+Perl, its at least understandable, honest even. It was all sort'a cobbled onto
+it. And, it was all sort'a ... inevitable. (Not even Larry was immune
+to the siren-song of objects! encapsulation! polymorphism! code reuse!)
+
+ I guess I should point out, I'm not opposed to OOP languages. I just think
+they are highly over-rated and can almost always be better -- as in more cleanly
+and more clearly -- implemented in a functional language. Consequently, OOP is,
+largely, unnecessary. Yet, I also understand there are folks, very smart folks,
+who'd rather chew a foot off as mess with Lisp-like languages or Haskell, so
+... we get what we got.
+
+[4] See, e.g., Miles Egan, "[E]volving Lisp," (20 May 2001 at
+http://lib.store.yahoo.net/lib/paulgraham/miles.txt). I would also lump into
+this Common Lisp's lack of a uniform syntax across arrays, hashmaps, vectors,
+etc. That is to say, Common Lisp, as most Lisps, these data structures are not
+first-class citizens, as compared to lists.
+
+[5] I say, "primarily," because, during in the early implementation of Clojure,
+Rich Hickey, the designer and author of Clojure, wrote Clojure in both Java for
+the JVM and C# for the CLI. He, later, was forced to abandon the C#/CLI
+implementation -- (mostly, as I understand it, because he was unable to devote
+an equivalent amount of time and attention to both implementations -- though
+there is, evidently, an ongoing effort to re-vitalize Clojure for the CLI in
+C#.
+
+[6] I, fwiw, agree with Rich Hickey. "We are doing it wrong!" In a world
+in which multi-core processors and gigantic caches are the norm, immutable,
+persistent data structures in a gc-able system within a functional-like
+programming language is ... the future.
+
+[7] The primary problem, imo, is the documentation. It is not, precisely, that
+there is a lack of adequate documentation, much of it is quite excellent. It
+is, instead, that much of it is obsolete, incomplete, scattered about
+here-and-yonder or just down-right wrong and confusing. Hence, my agreement to
+aid in the Parrot Documentation Revision project. (But, also, in-all-honesty, to
+help me to better understand Parrot. After-all, I figure I'm going to have to do
+some serious work on Parrot's internals in order to get an implementation of
+Clojure on Parrot!)
+
+[8] Figuring out just what to do in order to write a compiler targeting the
+ParrotVM is an almost insuperable barrier, something to which most developers,
+who are not also committed, for whatever reasons, to Parrot's success, will not
+subject themselves. For example, does one write their compiler in PIR? Or nqp?
+Or is it nqp-rx? (And just how does a new developer know or learn of the
+difference between nqp and nqp-rx, which is also 'parrot-nqp' in the Parrot
+distribution.) Or the PCT? Or is it PACT? Or, now, winxed? Or, if you don't
+want to do that, how do you bootstrap your own C implementation onto Parrot? Do
+you use NCI? Or is it better to embed Parrot? Or do you extend Parrot?
+
+ There is just a long list of hurdles one must overcome just to figure out
+the basic mechanism to write a compiler targeting Parrot. What is more, those
+tools you come to relying on over the past twenty years, you know, lex/yacc or
+flex/bison, just forget 'em, they've been replaced by a slow, poorly documented,
+poorly understood, outside of a handful of developers within the Parrot
+Community, Grammar Engine model!
+
+[9] This is, presently, undergoing significant correction due to the efforts of
+Julian Albo "NotFound", and his implementation of the 'winxed' programming
+language. And, I must add, the substantive efforts of Andrew Whitworth
+"Whiteknight".
+
+[10] No-one, seriously, I think wants to write a compiler in a low-level language
+like PIR. I certainly don't! Even the thought is painful. The real-world
+consequence is, the many, many false starts and, almost as many, failures to
+target, successfully, the ParrotVM.
+
+ This said, I am seriously considering, if time and occassion permits,
+writing stage0 compiler which will emit PIR (or, in the future, m0) with which
+to bootstrip ClojurePVM. I just really, really like the idea of having only
+seven primitives and two functions with which to implement the and interpreter,
+which I can then use to implement the reset of ClojurePVM!
+
+[11] That is to say, I want/need access to Perl5 and Perl5 modules. I also
+want/need access to Perl6 and Perl6 modules. But I also want/need access to
+other implementations and their moduels, e.g., TCL/Tk (or, at least, a Perl5
+module access to TCL/Tk, if I can't get direct access).
+
+ This is one of the major reasons driving Clojure's success. That is,
+direct -- not through a FFI or some other underlying mechanism -- calls
+to Java's slew of libraries.
+
+ Perl5 (and, soon, Perl6) has its own slew of libraries, and I want/need
+ClojurePVM to be able to directly call those implementations. In short,
+HLL-interoperability on the Parrot VM is an absolute MUST HAVE, and I'm willing
+to write it myself if I have to, to get it!
+
+[12] Another reason not to write a stage0 compiler is, cotto, dukeleto, and
+others are writing the backend of Parrot, something they are calling m0, and,
+so, I want to wait a'bit to see what will result from this.
22 README.pod
@@ -0,0 +1,22 @@
+=head1 NAME
+
+README.pod - Readme file for ClojurePVM.
+
+=head1 DESCRIPTION
+
+This README sets out a brief overview of ClojurePVM, version 0.0.1. Clojure is a dialect of Lisp which runs on the JVM. Unlike other lisps which run on the JVM, I<see, e.g.,> C<Armed Bear Common Lisp (ABCL)>, L<http://common-lisp.net/project/armedbear/>, Clojure breaks with ANSI Common Lisp in order to offer a "better lisp," but also to correct certain, rather important defects, of Common Lisp: Most importantly "Clojure gets data structures right." I<Puzzler, "Thoughts on Programming: Racket vs. Clojure" (Tuesday, August 10, 2010)> (L<http://programming-puzzler.blogspot.com/2010/08/racket-vs-clojure.html>). I<See also> I<NOTE> accompanying this distribution. The sheer productive power of immutable, persistent data structures coupled with an efficient garbage collection system executing on multi-core processors with large inlined caches simply cannot be overstated. The capability to treat data as values, that is, variables which are never rebound, alone, virtually I<frees> the applications developer from the challenge, dare I say, "nightmare," of concurrency programming.
+
+For more information on this, I encourage the interested reader to take a look at the many, excellent videos out on the web about Clojure. Specifically, I strongly encourage the reader to pay particular attention to Rich Hickey's presentation. They are I<truly> excellent. He has put a tremendous amount of effort, thought, and hard work into getting both the design and the implementation of Clojure right. And. as far as I can see, the only "real" liability of Clojure is, it lives on the JVM. It's understandable, Rich Hickey's decision to target the JVM (if for no other reason than the plethora of Java libraries), but it is a liability nonetheless.
+
+In short, this project is an effort to correct this deficiency and bring this exceptionally well-designed language that is Clojure to Parrot/Perl Community.
+
+=head2 LICENSE INFORMATION
+
+This code is distributed under the terms of the Artistic License 2.0. For more information about this license, I<see> the LICENSE file, accompanying this distribution.
+
+=head1 COPYRIGHT
+
+Copyright (C) 2011, Alvis Yardley.
+
+=cut
+
1  VERSION
@@ -0,0 +1 @@
+0.0.1
12 docs/How_to_create_dynpmc.txt
@@ -0,0 +1,12 @@
+For information on dynpmcs, see parrot/src/dynpmc/README.pod
+For details on creating PMCs, see tools/dev/gen_class.pl
+For details on adding a new PMC to Parrot, see docs/vtables.pod
+
+Note: To see what a minimal PMC looks like, create a PMC template and compile it
+to C with,
+
+ % perl tools/dev/gen_class.pl Foo > src/pmc/foo.pmc
+ % perl tools/build/pmc2c.pl --dump src/pmc/foo.pmc
+ % perl tools/build/pmc2c.pl -c src/pmc/foo.pmc
+
+See also tools/build/pmc2c.pl
14 include/cons.h
@@ -0,0 +1,14 @@
+/*
+Copyright (C) 2011, Alvis Yardley.
+
+=head1 NAME
+
+include/cons.h - The header file of ClojurePVM's cons cells.
+
+=head1 DESCRIPTION
+
+This code is the header file ClojurePVM's cons cells.
+
+=cut
+
+*/
14 src/c/cons.c
@@ -0,0 +1,14 @@
+/*
+Copyright (C) 2011, Alvis Yardley.
+
+=head1 NAME
+
+src/cons.h - The implementation of ClojurePVM's cons cells.
+
+=head1 DESCRIPTION
+
+This code is the implementation file for ClojurePVM's cons cells.
+
+=cut
+
+*/
20 src/c/cons.h
@@ -0,0 +1,20 @@
+/*
+Copyright (C) 2011, Alvis Yardley.
+
+=head1 NAME
+
+src/cons.h - An implementation of cons cells.
+
+=head1 DESCRIPTION
+
+This code implements double linked list of GCable objects.
+
+=cut
+
+/*
+ * cons.h - The header file to cons.c. It implements a simple cons cell with
+ * which I "hope" to turn into an implementation of cons cells for
+ * ClojurePVM.
+ *
+ * Date: 11/24/11
+ */
540 src/c/lisp/microlisp/2010-08-24-a-micro-manual-for-lisp-implemented-in-c.org
@@ -0,0 +1,540 @@
+#+title: A micro-manual for LISP Implemented in C
+#+tags: lisp c
+#+TAGS: noexport(e)
+#+EXPORT_EXCLUDE_TAGS: noexport
+
+Recently I had to go through some code that uses the [[http://www.sics.se/~adam/uip/index.php/Main_Page][uIP]] TCP/IP stack,
+which reminded me, it has been a long time since I did something in C
+so I ended up spending the weekend implementing the 10 rules [[http://en.wikipedia.org/wiki/John_McCarthy_(computer_scientist)][John
+McCarthy]] described in his paper [[https://docs.google.com/fileview?id=0B0ZnV_0C-Q7IOTRkNzVjZjMtMWE1NC00YzQ3LTgzMWEtM2UwY2I1YzdmNmM5&hl=en][A Micro-Manual for Lisp - not the
+whole Truth]].
+
+This is a literate program, the code in this document is the
+executable source, in order to extract it, open this [[https://github.com/nakkaya/nakkaya.com/tree/master/resources/posts/2010-08-24-a-micro-manual-for-lisp-implemented-in-c.org][raw file]] with
+emacs and run,
+
+#+begin_example
+ M-x org-babel-tangle
+#+end_example
+
+#+srcname: lisp-objects
+#+begin_src c
+ enum type {CONS, ATOM, FUNC, LAMBDA};
+
+ typedef struct{
+ enum type type;
+ } object;
+
+ typedef struct {
+ enum type type;
+ char *name;
+ } atom_object;
+
+ typedef struct {
+ enum type type;
+ object *car;
+ object *cdr;
+ } cons_object;
+
+ typedef struct {
+ enum type type;
+ object* (*fn)(object*,object*);
+ } func_object;
+
+ typedef struct {
+ enum type type;
+ object* args;
+ object* sexp;
+ } lambda_object;
+#+end_src
+
+We begin by defining four types of objects we will be using. CONS is
+what we use to hold lists, ATOMs are letters or digits anything that is
+not used by LISP, a FUNC holds a reference to a C function and a LAMBDA
+holds a lambda expression.
+
+#+srcname: lisp-read
+#+begin_src c
+ object *read_tail(FILE *in) {
+ object *token = next_token(in);
+
+ if(strcmp(name(token),")") == 0)
+ return NULL;
+ else if(strcmp(name(token),"(") == 0) {
+ object *first = read_tail(in);
+ object *second = read_tail(in);
+ return cons(first, second);
+ }else{
+ object *first = token;
+ object *second = read_tail(in);
+ return cons(first, second);
+ }
+ }
+
+ object *read(FILE *in) {
+ object *token = next_token(in);
+
+ if(strcmp(name(token),"(") == 0)
+ return read_tail(in);
+
+ return token;
+ }
+#+end_src
+
+/read/ gets the next token from the file, if it is a left parentheses it
+calls /read_tail/ to parse the rest of the list, otherwise returns the
+token read. A list (LIST e1 ... en) is defined for each n to be (CONS
+e1 (CONS ... (CONS en NIL))) so *read_tail* will keep calling itself
+concatenating cons cells until it hits a right parentheses.
+
+#+srcname: lisp-env
+#+begin_src c
+ object* init_env(){
+ object *env = cons(cons(atom("QUOTE"),cons(func(&fn_quote),NULL)),NULL);
+ append(env,cons(atom("CAR"),cons(func(&fn_car),NULL)));
+ append(env,cons(atom("CDR"),cons(func(&fn_cdr),NULL)));
+ append(env,cons(atom("CONS"),cons(func(&fn_cons),NULL)));
+ append(env,cons(atom("EQUAL"),cons(func(&fn_equal),NULL)));
+ append(env,cons(atom("ATOM"),cons(func(&fn_atom),NULL)));
+ append(env,cons(atom("COND"),cons(func(&fn_cond),NULL)));
+ append(env,cons(atom("LAMBDA"),cons(func(&fn_lambda),NULL)));
+ append(env,cons(atom("LABEL"),cons(func(&fn_label),NULL)));
+
+ tee = atom("#T");
+ nil = cons(NULL,NULL);
+
+ return env;
+ }
+#+end_src
+
+Now that we have a list to execute, we need to define the environment we
+will be evaluating the expressions in. Environment is a list of pairs
+during evaluation we replace those atoms with their values, we also
+define tee to be the atom *#T* and nil to be the empty list.
+
+#+srcname: lisp-eval
+#+begin_src c
+ object *eval_fn (object *sexp, object *env){
+ object *symbol = car(sexp);
+ object *args = cdr(sexp);
+
+ if(symbol->type == LAMBDA)
+ return fn_lambda(sexp,env);
+ else if(symbol->type == FUNC)
+ return (((func_object *) (symbol))->fn)(args, env);
+ else
+ return sexp;
+ }
+
+ object *eval (object *sexp, object *env) {
+ if(sexp == NULL)
+ return nil;
+
+ if(sexp->type == CONS){
+ if(car(sexp)->type == ATOM && strcmp(name(car(sexp)), "LAMBDA") == 0){
+ object* largs = car(cdr(sexp));
+ object* lsexp = car(cdr(cdr(sexp)));
+
+ return lambda(largs,lsexp);
+ }else{
+ object *accum = cons(eval(car(sexp),env),NULL);
+ sexp = cdr(sexp);
+
+ while (sexp != NULL && sexp->type == CONS){
+ append(accum,eval(car(sexp),env));
+ sexp = cdr(sexp);
+ }
+
+ return eval_fn(accum,env);
+ }
+ }else{
+ object *val = lookup(name(sexp),env);
+ if(val == NULL)
+ return sexp;
+ else
+ return val;
+ }
+ }
+#+end_src
+
+When we pass an S-Expression to eval, first we need to check if it is a
+lambda expression if it is we don't evaluate it we just return a lambda
+object, if it is a list we call eval for each cell, this allows us to
+iterate through all the atoms in the list when we hit an atom we lookup
+its value in the environment if it has a value associated with it we
+return that otherwise we return the atom, at this point,
+
+#+begin_example
+ (QUOTE A)
+#+end_example
+
+is transformed into,
+
+#+begin_example
+ (func-obj atom-obj)
+#+end_example
+
+all eval\_fn has to do is check the type of the car of the list, if it is
+a function\_object it will call the function pointed by the
+function\_object passing cdr of the list as argument, if it is a
+lambda\_object we call the fn\_lambda which executes the lambda
+expression else we return the S-Expression.
+
+Each function_object holds a pointer to a function that takes two
+arguments, arguments to the function and the environment we are executing
+it in and returns an object.
+
+#+srcname: lisp-lambda
+#+begin_src c
+ object *fn_lambda (object *args, object *env) {
+ object *lambda = car(args);
+ args = cdr(args);
+
+ object *list = interleave((((lambda_object *) (lambda))->args),args);
+ object* sexp = replace_atom((((lambda_object *) (lambda))->sexp),list);
+ return eval(sexp,env);
+ }
+#+end_src
+
+A lambda_object holds two lists,
+
+#+begin_example
+ (LAMBDA (X Y) (CONS (CAR X) Y))
+ args -> (X Y)
+ sexp -> (CONS (CAR X) Y))
+#+end_example
+
+to execute it first thing we do is interleave the args list with the
+arguments passed so while executing following,
+
+#+begin_example
+ ((LAMBDA (X Y) (CONS (CAR X) Y)) (QUOTE (A B)) (CDR (QUOTE (C D))))
+#+end_example
+
+list will be,
+
+#+begin_example
+ ((X (A B)) (Y (D)))
+#+end_example
+
+then we iterate over the sexp and replace every occurrence of X with (A
+B) and every occurrence of Y with (D) then call eval on the resulting
+expression.
+
+This covers everything we need to interpret the LISP defined in the
+paper passing a file containing the following,
+
+#+begin_example
+ (QUOTE A)
+ (QUOTE (A B C))
+ (CAR (QUOTE (A B C)))
+ (CDR (QUOTE (A B C)))
+ (CONS (QUOTE A) (QUOTE (B C)))
+ (EQUAL (CAR (QUOTE (A B))) (QUOTE A))
+ (EQUAL (CAR (CDR (QUOTE (A B)))) (QUOTE A))
+ (ATOM (QUOTE A))
+ (COND ((ATOM (QUOTE A)) (QUOTE B)) ((QUOTE T) (QUOTE C)))
+ ((LAMBDA (X Y) (CONS (CAR X) Y)) (QUOTE (A B)) (CDR (QUOTE (C D))))
+ (LABEL FF (LAMBDA (X Y) (CONS (CAR X) Y)))
+ (FF (QUOTE (A B)) (CDR (QUOTE (C D))))
+ (LABEL XX (QUOTE (A B)))
+ (CAR XX)
+#+end_example
+
+should produce,
+
+#+begin_example
+ lisp/ $ gcc -Wall lisp.c && ./a.out test.lisp
+ > A
+ > (A B C)
+ > A
+ > (B C)
+ > (A B C)
+ > #T
+ > ()
+ > #T
+ > B
+ > (A D)
+ > #T
+ > (A D)
+ > #T
+ > A
+#+end_example
+
+* Files :noexport:
+
+#+begin_src c :exports none :tangle lisp.c :noweb yes
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <ctype.h>
+ #include <string.h>
+
+ <<lisp-objects>>
+
+ #define car(X) (((cons_object *) (X))->car)
+ #define cdr(X) (((cons_object *) (X))->cdr)
+
+ char *name(object *o){
+ if(o->type != ATOM) exit(1);
+ return ((atom_object*)o)->name;
+ }
+
+ object *atom (char *n) {
+ atom_object *ptr = (atom_object *) malloc (sizeof (atom_object));
+ ptr->type = ATOM;
+ char *name;
+ name = malloc(strlen(n) + 1);
+ strcpy(name, n);
+ ptr->name = name;
+ return (object *) ptr;
+ }
+
+ object *cons (object *first, object *second) {
+ cons_object *ptr = (cons_object *) malloc (sizeof (cons_object));
+ ptr->type = CONS;
+ ptr->car = first;
+ ptr->cdr = second;
+ return (object *) ptr;
+ }
+
+ object *func (object* (*fn)(object*, object*)) {
+ func_object *ptr = (func_object *) malloc (sizeof (func_object));
+ ptr->type = FUNC;
+ ptr->fn = fn;
+ return (object *) ptr;
+ }
+
+ void append (object *list, object *obj) {
+ object *ptr;
+ for (ptr = list; cdr(ptr) != NULL; ptr = cdr(ptr));
+ cdr(ptr) = cons(obj, NULL);
+ }
+
+ object *lambda (object *args, object *sexp) {
+ lambda_object *ptr = (lambda_object *) malloc (sizeof (lambda_object));
+ ptr->type = LAMBDA;
+ ptr->args = args;
+ ptr->sexp = sexp;
+ return (object *) ptr;
+ }
+
+ object *tee,*nil;
+
+ //
+ //
+ //
+ //
+
+ object *eval (object *sexp, object *env);
+
+ object *fn_car (object *args, object *env) {
+ return car(car(args));
+ }
+
+ object *fn_cdr (object *args, object *env) {
+ return cdr(car(args));
+ }
+
+ object *fn_quote (object *args, object *env) {
+ return car(args);
+ }
+
+ object *fn_cons (object *args, object *env) {
+ object *list = cons(car(args),NULL);
+ args = car(cdr(args));
+
+ while (args != NULL && args->type == CONS){
+ append(list,car(args));
+ args = cdr(args);
+ }
+
+ return list;
+ }
+
+ object *fn_equal (object *args, object *env) {
+ object *first = car(args);
+ object *second = car(cdr(args));
+ if(strcmp(name(first),name(second)) == 0)
+ return tee;
+ else
+ return nil;
+ }
+
+ object *fn_atom (object *args, object *env) {
+ if(car(args)->type == ATOM)
+ return tee;
+ else
+ return nil;
+ }
+
+ object *fn_cond (object *args, object *env) {
+
+ while (args != NULL && args->type == CONS){
+ object *list = car(args);
+ object *pred = nil;
+
+ if (car(list) != nil)
+ pred = eval(car(list), env);
+
+ object *ret = car(cdr(list));
+
+ if(pred != nil)
+ return eval(ret,env);
+
+ args = cdr(args);
+ }
+
+ return nil;
+ }
+
+ object *interleave (object *c1, object *c2) {
+ object *list = cons(cons(car(c1),cons(car(c2),NULL)),NULL);
+ c1 = cdr(c1);
+ c2 = cdr(c2);
+
+ while (c1 != NULL && c1->type == CONS){
+ append(list,cons(car(c1),cons(car(c2),NULL)));
+ c1 = cdr(c1);
+ c2 = cdr(c2);
+ }
+
+ return list;
+ }
+
+ object *replace_atom (object *sexp, object *with) {
+
+ if(sexp->type == CONS){
+
+ object *list = cons(replace_atom(car(sexp), with),NULL);
+ sexp = cdr(sexp);
+
+ while (sexp != NULL && sexp->type == CONS){
+ append(list,replace_atom(car(sexp), with));
+ sexp = cdr(sexp);
+ }
+
+ return list;
+ }else{
+ object* tmp = with;
+
+ while (tmp != NULL && tmp->type == CONS) {
+ object *item = car(tmp);
+ object *atom = car(item);
+ object *replacement = car(cdr(item));
+
+ if(strcmp(name(atom),name(sexp)) == 0)
+ return replacement;
+
+ tmp = cdr(tmp);
+ }
+
+ return sexp;
+ }
+ }
+
+ <<lisp-lambda>>
+
+ object *fn_label (object *args, object *env) {
+ append(env,cons(atom(name(car(args))),cons(car(cdr(args)),NULL)));
+ return tee;
+ }
+
+ object* lookup(char* n, object *env){
+ object *tmp = env;
+
+ while (tmp != NULL && tmp->type == CONS) {
+ object *item = car(tmp);
+ object *nm = car(item);
+ object *val = car(cdr(item));
+
+ if(strcmp(name(nm),n) == 0)
+ return val;
+ tmp = cdr(tmp);
+ }
+ return NULL;
+ }
+
+ <<lisp-env>>
+
+ <<lisp-eval>>
+
+ //
+ // I/O
+ //
+ void print(object *sexp){
+ if(sexp == NULL)
+ return;
+
+ if(sexp->type == CONS){
+ printf ("(");
+ print(car(sexp));
+ sexp = cdr(sexp);
+ while (sexp != NULL && sexp->type == CONS) {
+ printf (" ");
+ print(car(sexp));
+ sexp = cdr(sexp);
+ }
+ printf ( ")");
+ }else if(sexp->type == ATOM){
+ printf ("%s", name(sexp));
+ }else if(sexp->type == LAMBDA){
+ printf ("#");
+ print((((lambda_object *) (sexp))->args));
+ print((((lambda_object *) (sexp))->sexp));
+ }else
+ printf ("Error.");
+ }
+
+ object *next_token(FILE *in) {
+ int ch = getc(in);
+
+ while(isspace(ch)) ch = getc(in);
+
+ if(ch == '\n')
+ ch = getc(in);
+ if(ch == EOF)
+ exit(0);
+
+ if(ch == ')')
+ return atom(")");
+ if(ch == '(')
+ return atom("(");
+
+ char buffer[128];
+ int index = 0;
+
+ while(!isspace(ch) && ch != ')'){
+ buffer[index++] = ch;
+ ch = getc (in);
+ }
+
+ buffer[index++] = '\0';
+ if (ch == ')')
+ ungetc (ch, in);
+
+ return atom(buffer);
+ }
+
+ <<lisp-read>>
+
+ //
+ // REPL
+ //
+ int main(int argc, char *argv[]){
+ object *env = init_env();
+ FILE* in;
+
+ if(argc > 1)
+ in = fopen(argv[1], "r");
+ else
+ in = stdin;
+
+ do {
+ printf ("> ");
+ print(eval(read(in), env));
+ printf ("\n");
+ } while (1);
+
+ return 0;
+ }
+#+end_src
552 src/c/lisp/microlisp/A micro-manual for LISP Implemented in C (by Nurullah Akkaya).html
@@ -0,0 +1,552 @@
+<html xml:lang="en" xmlns="http://www.w3.org/1999/xhtml" lang="en"><head><meta content="text/html; charset=UTF-8" http-equiv="content-type"><meta name="description"><meta content="lisp c" name="keywords"><meta content="Nurullah Akkaya" name="author"><link href="http://nakkaya.com/images/favicon.ico" rel="icon" type="image/x-icon"><link href="http://nakkaya.com/images/favicon.ico" rel="shortcut icon" type="image/x-icon"><link href="A%20micro-manual%20for%20LISP%20Implemented%20in%20C%20%28by%20Nurullah%20Akkaya%29_files/default.bin" rel="stylesheet" type="text/css"><link href="http://nakkaya.com/rss-feed" rel="alternate" title="An explorer's log" type="application/rss+xml"><link href="http://nakkaya.com/2010/08/24/a-micro-manual-for-lisp-implemented-in-c/" rel="canonical"><script src="A%20micro-manual%20for%20LISP%20Implemented%20in%20C%20%28by%20Nurullah%20Akkaya%29_files/MathJax.js" type="text/javascript"></script><script src="A%20micro-manual%20for%20LISP%20Implemented%20in%20C%20%28by%20Nurullah%20Akkaya%29_files/highlight.bin" type="text/javascript"></script><script src="A%20micro-manual%20for%20LISP%20Implemented%20in%20C%20%28by%20Nurullah%20Akkaya%29_files/jquery.bin" type="text/javascript"></script><script type="text/javascript">$(document).ready(function() {
+ $('pre code').each(function(i, e) {hljs.highlightBlock(e, ' ')});
+ hljs.initHighlightingOnLoad();
+ });</script><title>A micro-manual for LISP Implemented in C (by Nurullah Akkaya)</title><script src="A%20micro-manual%20for%20LISP%20Implemented%20in%20C%20%28by%20Nurullah%20Akkaya%29_files/ga.js" async="" type="text/javascript"></script><style type="text/css">#MathJax_Zoom {position: absolute; background-color: #F0F0F0; overflow: auto; display: block; z-index: 301; padding: .5em; border: 1px solid black; margin: 0; font-family: serif; font-size: 85%; font-weight: normal; font-style: normal; text-align: left; text-indent: 0; text-transform: none; line-height: normal; letter-spacing: normal; word-spacing: normal; word-wrap: normal; white-space: nowrap; float: none; box-shadow: 5px 5px 15px #AAAAAA; -webkit-box-shadow: 5px 5px 15px #AAAAAA; -moz-box-shadow: 5px 5px 15px #AAAAAA; -khtml-box-shadow: 5px 5px 15px #AAAAAA; filter: progid:DXImageTransform.Microsoft.dropshadow(OffX=2, OffY=2, Color='gray', Positive='true')}
+#MathJax_ZoomOverlay {position: absolute; left: 0; top: 0; z-index: 300; display: inline-block; width: 100%; height: 100%; border: 0; padding: 0; margin: 0; background-color: white; opacity: 0; filter: alpha(opacity=0)}
+</style><style type="text/css">#MathJax_About {position: fixed; left: 50%; width: auto; text-align: center; border: 3px outset; padding: 1em 2em; background-color: #DDDDDD; color: black; cursor: default; font-family: message-box; font-size: 120%; font-style: normal; text-indent: 0; text-transform: none; line-height: normal; letter-spacing: normal; word-spacing: normal; word-wrap: normal; white-space: nowrap; float: none; z-index: 201; border-radius: 15px; -webkit-border-radius: 15px; -moz-border-radius: 15px; -khtml-border-radius: 15px; box-shadow: 0px 10px 20px #808080; -webkit-box-shadow: 0px 10px 20px #808080; -moz-box-shadow: 0px 10px 20px #808080; -khtml-box-shadow: 0px 10px 20px #808080; filter: progid:DXImageTransform.Microsoft.dropshadow(OffX=2, OffY=2, Color='gray', Positive='true')}
+.MathJax_Menu {position: absolute; background-color: white; color: black; width: auto; padding: 5px 0px; border: 1px solid #CCCCCC; margin: 0; cursor: default; font: menu; text-align: left; text-indent: 0; text-transform: none; line-height: normal; letter-spacing: normal; word-spacing: normal; word-wrap: normal; white-space: nowrap; float: none; z-index: 201; border-radius: 5px; -webkit-border-radius: 5px; -moz-border-radius: 5px; -khtml-border-radius: 5px; box-shadow: 0px 10px 20px #808080; -webkit-box-shadow: 0px 10px 20px #808080; -moz-box-shadow: 0px 10px 20px #808080; -khtml-box-shadow: 0px 10px 20px #808080; filter: progid:DXImageTransform.Microsoft.dropshadow(OffX=2, OffY=2, Color='gray', Positive='true')}
+.MathJax_MenuItem {padding: 1px 2em; background: transparent}
+.MathJax_MenuTitle {background-color: #CCCCCC; margin: -5px 0 0 0; text-align: center; font-style: italic; font-size: 80%; color: #444444; padding: 2px 0; overflow: hidden}
+.MathJax_MenuArrow {position: absolute; right: .5em; color: #666666}
+.MathJax_MenuActive .MathJax_MenuArrow {color: white}
+.MathJax_MenuCheck {position: absolute; left: .7em}
+.MathJax_MenuRadioCheck {position: absolute; left: .7em}
+.MathJax_MenuLabel {padding: 1px 2em 3px 1.33em; font-style: italic}
+.MathJax_MenuRule {border-top: 1px solid #DDDDDD; margin: 4px 3px}
+.MathJax_MenuDisabled {color: GrayText}
+.MathJax_MenuActive {background-color: #606872; color: white}
+</style><style type="text/css">#MathJax_Message {position: fixed; left: 1px; bottom: 2px; background-color: #E6E6E6; border: 1px solid #959595; margin: 0px; padding: 2px 8px; z-index: 102; color: black; font-size: 80%; width: auto; white-space: nowrap}
+#MathJax_MSIE_Frame {position: absolute; top: 0; left: 0; width: 0px; z-index: 101; border: 0px; margin: 0px; padding: 0px}
+.MathJax_Error {color: #CC0000; font-style: italic}
+</style><script charset="UTF-8" async="" src="A%20micro-manual%20for%20LISP%20Implemented%20in%20C%20%28by%20Nurullah%20Akkaya%29_files/thread.js"></script><link href="A%20micro-manual%20for%20LISP%20Implemented%20in%20C%20%28by%20Nurullah%20Akkaya%29_files/defaults.css" type="text/css" rel="stylesheet"><script charset="UTF-8" async="" src="A%20micro-manual%20for%20LISP%20Implemented%20in%20C%20%28by%20Nurullah%20Akkaya%29_files/disqus.js"></script><link href="A%20micro-manual%20for%20LISP%20Implemented%20in%20C%20%28by%20Nurullah%20Akkaya%29_files/dsq7884a9652e94555c70f96b6be63be216.css" type="text/css" rel="stylesheet"><script charset="UTF-8" async="" src="A%20micro-manual%20for%20LISP%20Implemented%20in%20C%20%28by%20Nurullah%20Akkaya%29_files/dsq7884a9652e94555c70f96b6be63be216.js"></script><script charset="UTF-8" async="" src="A%20micro-manual%20for%20LISP%20Implemented%20in%20C%20%28by%20Nurullah%20Akkaya%29_files/all.js"></script><style type="text/css">.fb_hidden{position:absolute;top:-10000px;z-index:10001}
+.fb_invisible{display:none}
+.fb_reset{background:none;border-spacing:0;border:0;color:#000;cursor:auto;direction:ltr;font-family:"lucida grande", tahoma, verdana, arial, sans-serif;font-size: 11px;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;line-height:1;margin:0;overflow:visible;padding:0;text-align:left;text-decoration:none;text-indent:0;text-shadow:none;text-transform:none;visibility:visible;white-space:normal;word-spacing:normal}
+.fb_link img{border:none}
+.fb_dialog{background:rgba(82, 82, 82, .7);position:absolute;top:-10000px;z-index:10001}
+.fb_dialog_advanced{padding:10px;-moz-border-radius:8px;-webkit-border-radius:8px}
+.fb_dialog_content{background:#fff;color:#333}
+.fb_dialog_close_icon{background:url(http://static.ak.fbcdn.net/rsrc.php/v1/yq/r/IE9JII6Z1Ys.png) no-repeat scroll 0 0 transparent;_background-image:url(http://static.ak.fbcdn.net/rsrc.php/v1/yL/r/s816eWC-2sl.gif);cursor:pointer;display:block;height:15px;position:absolute;right:18px;top:17px;width:15px;top:8px\9;right:7px\9}
+.fb_dialog_mobile .fb_dialog_close_icon{top:5px;left:5px;right:auto}
+.fb_dialog_padding{background-color:transparent;position:absolute;width:1px;z-index:-1}
+.fb_dialog_close_icon:hover{background:url(http://static.ak.fbcdn.net/rsrc.php/v1/yq/r/IE9JII6Z1Ys.png) no-repeat scroll 0 -15px transparent;_background-image:url(http://static.ak.fbcdn.net/rsrc.php/v1/yL/r/s816eWC-2sl.gif)}
+.fb_dialog_close_icon:active{background:url(http://static.ak.fbcdn.net/rsrc.php/v1/yq/r/IE9JII6Z1Ys.png) no-repeat scroll 0 -30px transparent;_background-image:url(http://static.ak.fbcdn.net/rsrc.php/v1/yL/r/s816eWC-2sl.gif)}
+.fb_dialog_loader{background-color:#f2f2f2;border:1px solid #606060;font-size: 24px;padding:20px}
+.fb_dialog_top_left,
+.fb_dialog_top_right,
+.fb_dialog_bottom_left,
+.fb_dialog_bottom_right{height:10px;width:10px;overflow:hidden;position:absolute}
+.fb_dialog_top_left{background:url(http://static.ak.fbcdn.net/rsrc.php/v1/ye/r/8YeTNIlTZjm.png) no-repeat 0 0;left:-10px;top:-10px}
+.fb_dialog_top_right{background:url(http://static.ak.fbcdn.net/rsrc.php/v1/ye/r/8YeTNIlTZjm.png) no-repeat 0 -10px;right:-10px;top:-10px}
+.fb_dialog_bottom_left{background:url(http://static.ak.fbcdn.net/rsrc.php/v1/ye/r/8YeTNIlTZjm.png) no-repeat 0 -20px;bottom:-10px;left:-10px}
+.fb_dialog_bottom_right{background:url(http://static.ak.fbcdn.net/rsrc.php/v1/ye/r/8YeTNIlTZjm.png) no-repeat 0 -30px;right:-10px;bottom:-10px}
+.fb_dialog_vert_left,
+.fb_dialog_vert_right,
+.fb_dialog_horiz_top,
+.fb_dialog_horiz_bottom{position:absolute;background:#525252;filter:alpha(opacity=70);opacity:.7}
+.fb_dialog_vert_left,
+.fb_dialog_vert_right{width:10px;height:100%}
+.fb_dialog_vert_left{margin-left:-10px}
+.fb_dialog_vert_right{right:0;margin-right:-10px}
+.fb_dialog_horiz_top,
+.fb_dialog_horiz_bottom{width:100%;height:10px}
+.fb_dialog_horiz_top{margin-top:-10px}
+.fb_dialog_horiz_bottom{bottom:0;margin-bottom:-10px}
+.fb_dialog_iframe{line-height:0}
+.fb_dialog_content .dialog_title{background:#6d84b4;border:1px solid #3b5998;color:#fff;font-size: 14px;font-weight:bold;margin:0}
+.fb_dialog_content .dialog_title > span{background:url(http://static.ak.fbcdn.net/rsrc.php/v1/yd/r/Cou7n-nqK52.gif)
+no-repeat 5px 50%;float:left;padding:5px 0 7px 26px}
+body.fb_hidden{-webkit-transform:none;height:100%;margin:0;left:-10000px;overflow:visible;position:absolute;top:-10000px;width:100%
+}
+.fb_dialog.fb_dialog_mobile.loading{background:url(http://static.ak.fbcdn.net/rsrc.php/v1/yO/r/_j03izEX40U.gif)
+white no-repeat 50% 50%;min-height:100%;min-width:100%;overflow:hidden;position:absolute;top:0;z-index:10001}
+.fb_dialog.fb_dialog_mobile.loading.centered{max-height:590px;min-height:590px;max-width:500px;min-width:500px}
+#fb-root #fb_dialog_ipad_overlay{background:rgba(0, 0, 0, .45);position:absolute;left:0;top:0;width:100%;min-height:100%;z-index:10000}
+#fb-root #fb_dialog_ipad_overlay.hidden{display:none}
+.fb_dialog.fb_dialog_mobile.loading iframe{visibility:hidden}
+.fb_dialog_content .dialog_header{-webkit-box-shadow:white 0 1px 1px -1px inset;background:-webkit-gradient(linear, 0 0, 0 100%, from(#738ABA), to(#2C4987));border-bottom:1px solid;border-color:#1d4088;color:#fff;font:14px Helvetica, sans-serif;font-weight:bold;text-overflow:ellipsis;text-shadow:rgba(0, 30, 84, .296875) 0 -1px 0;vertical-align:middle;white-space:nowrap}
+.fb_dialog_content .dialog_header table{-webkit-font-smoothing:subpixel-antialiased;height:43px;width:100%
+}
+.fb_dialog_content .dialog_header td.header_left{font-size: 12px;padding-left:5px;vertical-align:middle;width:60px
+}
+.fb_dialog_content .dialog_header td.header_right{font-size: 12px;padding-right:5px;vertical-align:middle;width:60px
+}
+.fb_dialog_content .touchable_button{background:-webkit-gradient(linear, 0 0, 0 100%, from(#4966A6),
+color-stop(0.5, #355492), to(#2A4887));border:1px solid #29447e;-webkit-background-clip:padding-box;-webkit-border-radius:3px;-webkit-box-shadow:rgba(0, 0, 0, .117188) 0 1px 1px inset,
+rgba(255, 255, 255, .167969) 0 1px 0;display:inline-block;margin-top:3px;max-width:85px;line-height:18px;padding:4px 12px;position:relative}
+.fb_dialog_content .dialog_header .touchable_button input{border:none;background:none;color:#fff;font:12px Helvetica, sans-serif;font-weight:bold;margin:2px -12px;padding:2px 6px 3px 6px;text-shadow:rgba(0, 30, 84, .296875) 0 -1px 0}
+.fb_dialog_content .dialog_header .header_center{color:#fff;font-size: 16px;font-weight:bold;line-height:18px;text-align:center;vertical-align:middle}
+.fb_dialog_content .dialog_content{background:url(http://static.ak.fbcdn.net/rsrc.php/v1/y9/r/jKEcVPZFk-2.gif) no-repeat 50% 50%;border:1px solid #555;border-bottom:0;border-top:0;height:150px}
+.fb_dialog_content .dialog_footer{background:#f2f2f2;border:1px solid #555;border-top-color:#ccc;height:40px}
+#fb_dialog_loader_close{float:left}
+.fb_dialog.fb_dialog_mobile .fb_dialog_close_button{text-shadow:rgba(0, 30, 84, .296875) 0 -1px 0}
+.fb_dialog.fb_dialog_mobile .fb_dialog_close_icon{visibility:hidden}
+.fb_iframe_widget{position:relative;display:-moz-inline-block;display:inline-block}
+.fb_iframe_widget iframe{position:relative;vertical-align:text-bottom}
+.fb_iframe_widget span{position:relative}
+.fb_hide_iframes iframe{position:relative;left:-10000px}
+.fb_iframe_widget_loader{position:relative;display:inline-block}
+.fb_iframe_widget_loader iframe{min-height:32px;z-index:2;zoom:1}
+.fb_iframe_widget_loader .FB_Loader{background:url(http://static.ak.fbcdn.net/rsrc.php/v1/y9/r/jKEcVPZFk-2.gif) no-repeat;height:32px;width:32px;margin-left:-16px;position:absolute;left:50%;z-index:4}
+.fb_button_simple,
+.fb_button_simple_rtl{background-image:url(http://static.ak.fbcdn.net/rsrc.php/v1/yH/r/eIpbnVKI9lR.png);background-repeat:no-repeat;cursor:pointer;outline:none;text-decoration:none}
+.fb_button_simple_rtl{background-position:right 0}
+.fb_button_simple .fb_button_text{margin:0 0 0 20px;padding-bottom:1px}
+.fb_button_simple_rtl .fb_button_text{margin:0 10px 0 0}
+a.fb_button_simple:hover .fb_button_text,
+a.fb_button_simple_rtl:hover .fb_button_text,
+.fb_button_simple:hover .fb_button_text,
+.fb_button_simple_rtl:hover .fb_button_text{text-decoration:underline}
+.fb_button,
+.fb_button_rtl{background:#29447e url(http://static.ak.fbcdn.net/rsrc.php/v1/yL/r/FGFbc80dUKj.png);background-repeat:no-repeat;cursor:pointer;display:inline-block;padding:0 0 0 1px;text-decoration:none;outline:none}
+.fb_button .fb_button_text,
+.fb_button_rtl .fb_button_text{background:#5f78ab url(http://static.ak.fbcdn.net/rsrc.php/v1/yL/r/FGFbc80dUKj.png);border-top:solid 1px #879ac0;border-bottom:solid 1px #1a356e;color:#fff;display:block;font-family:"lucida grande",tahoma,verdana,arial,sans-serif;font-weight:bold;padding:2px 6px 3px 6px;margin:1px 1px 0 21px;text-shadow:none}
+a.fb_button,
+a.fb_button_rtl,
+.fb_button,
+.fb_button_rtl{text-decoration:none}
+a.fb_button:active .fb_button_text,
+a.fb_button_rtl:active .fb_button_text,
+.fb_button:active .fb_button_text,
+.fb_button_rtl:active .fb_button_text{border-bottom:solid 1px #29447e;border-top:solid 1px #45619d;background:#4f6aa3;text-shadow:none}
+.fb_button_xlarge,
+.fb_button_xlarge_rtl{background-position:left -60px;font-size: 24px;line-height:30px}
+.fb_button_xlarge .fb_button_text{padding:3px 8px 3px 12px;margin-left:38px}
+a.fb_button_xlarge:active{background-position:left -99px}
+.fb_button_xlarge_rtl{background-position:right -268px}
+.fb_button_xlarge_rtl .fb_button_text{padding:3px 8px 3px 12px;margin-right:39px}
+a.fb_button_xlarge_rtl:active{background-position:right -307px}
+.fb_button_large,
+.fb_button_large_rtl{background-position:left -138px;font-size: 13px;line-height:16px}
+.fb_button_large .fb_button_text{margin-left:24px;padding:2px 6px 4px 6px}
+a.fb_button_large:active{background-position:left -163px}
+.fb_button_large_rtl{background-position:right -346px}
+.fb_button_large_rtl .fb_button_text{margin-right:25px}
+a.fb_button_large_rtl:active{background-position:right -371px}
+.fb_button_medium,
+.fb_button_medium_rtl{background-position:left -188px;font-size: 11px;line-height:14px}
+a.fb_button_medium:active{background-position:left -210px}
+.fb_button_medium_rtl{background-position:right -396px}
+.fb_button_text_rtl,
+.fb_button_medium_rtl .fb_button_text{padding:2px 6px 3px 6px;margin-right:22px}
+a.fb_button_medium_rtl:active{background-position:right -418px}
+.fb_button_small,
+.fb_button_small_rtl{background-position:left -232px;font-size: 10px;line-height:10px}
+.fb_button_small .fb_button_text{padding:2px 6px 3px;margin-left:17px}
+a.fb_button_small:active,
+.fb_button_small:active{background-position:left -250px}
+.fb_button_small_rtl{background-position:right -440px}
+.fb_button_small_rtl .fb_button_text{padding:2px 6px;margin-right:18px}
+a.fb_button_small_rtl:active{background-position:right -458px}
+.fb_share_count_wrapper{position:relative;float:left}
+.fb_share_count{background:#b0b9ec none repeat scroll 0 0;color:#333;font-family:"lucida grande", tahoma, verdana, arial, sans-serif;text-align:center}
+.fb_share_count_inner{background:#e8ebf2;display:block}
+.fb_share_count_right{margin-left:-1px;display:inline-block}
+.fb_share_count_right .fb_share_count_inner{border-top:solid 1px #e8ebf2;border-bottom:solid 1px #b0b9ec;margin:1px 1px 0 1px;font-size: 10px;line-height:10px;padding:2px 6px 3px;font-weight:bold}
+.fb_share_count_top{display:block;letter-spacing:-1px;line-height:34px;margin-bottom:7px;font-size: 22px;border:solid 1px #b0b9ec}
+.fb_share_count_nub_top{border:none;display:block;position:absolute;left:7px;top:35px;margin:0;padding:0;width:6px;height:7px;background-repeat:no-repeat;background-image:url(http://static.ak.fbcdn.net/rsrc.php/v1/yU/r/bSOHtKbCGYI.png)}
+.fb_share_count_nub_right{border:none;display:inline-block;padding:0;width:5px;height:10px;background-repeat:no-repeat;background-image:url(http://static.ak.fbcdn.net/rsrc.php/v1/yX/r/i_oIVTKMYsL.png);vertical-align:top;background-position:right 5px;z-index:10;left:2px;margin:0 2px 0 0;position:relative}
+.fb_share_no_count{display:none}
+.fb_share_size_Small .fb_share_count_right .fb_share_count_inner{font-size: 10px}
+.fb_share_size_Medium .fb_share_count_right .fb_share_count_inner{font-size: 11px;padding:2px 6px 3px;letter-spacing:-1px;line-height:14px}
+.fb_share_size_Large .fb_share_count_right .fb_share_count_inner{font-size: 13px;line-height:16px;padding:2px 6px 4px;font-weight:normal;letter-spacing:-1px}
+.fb_share_count_hidden .fb_share_count_nub_top,
+.fb_share_count_hidden .fb_share_count_top,
+.fb_share_count_hidden .fb_share_count_nub_right,
+.fb_share_count_hidden .fb_share_count_right{visibility:hidden}
+.fb_connect_bar_container div,
+.fb_connect_bar_container span,
+.fb_connect_bar_container a,
+.fb_connect_bar_container img,
+.fb_connect_bar_container strong{background:none;border-spacing:0;border:0;direction:ltr;font-style:normal;font-variant:normal;letter-spacing:normal;line-height:1;margin:0;overflow:visible;padding:0;text-align:left;text-decoration:none;text-indent:0;text-shadow:none;text-transform:none;visibility:visible;white-space:normal;word-spacing:normal;vertical-align:baseline}
+.fb_connect_bar_container{position:fixed;left:0 !important;right:0 !important;height:42px !important;padding:0 25px !important;margin:0 !important;vertical-align:middle !important;border-bottom:1px solid #333 !important;background:#3b5998 !important;z-index:99999999 !important;overflow:hidden !important}
+.fb_connect_bar_container_ie6{position:absolute;top:expression(document.compatMode=="CSS1Compat"? document.documentElement.scrollTop+"px":body.scrollTop+"px")}
+.fb_connect_bar{position:relative;margin:auto;height:100%;width:100%;padding:6px 0 0 0 !important;background:none;color:#fff !important;font-family:"lucida grande", tahoma, verdana, arial, sans-serif !important;font-size: 13px !important;font-style:normal !important;font-variant:normal !important;font-weight:normal !important;letter-spacing:normal !important;line-height:1 !important;text-decoration:none !important;text-indent:0 !important;text-shadow:none !important;text-transform:none !important;white-space:normal !important;word-spacing:normal !important}
+.fb_connect_bar a:hover{color:#fff}
+.fb_connect_bar .fb_profile img{height:30px;width:30px;vertical-align:middle;margin:0 6px 5px 0}
+.fb_connect_bar div a,
+.fb_connect_bar span,
+.fb_connect_bar span a{color:#bac6da;font-size: 11px;text-decoration:none}
+.fb_connect_bar .fb_buttons{float:right;margin-top:7px}
+.fb_edge_widget_with_comment{position:relative;*z-index:1000}
+.fb_edge_widget_with_comment span.fb_edge_comment_widget{position:absolute}
+.fb_edge_widget_with_comment span.fb_edge_comment_widget iframe.fb_ltr{left:-4px}
+.fb_edge_widget_with_comment span.fb_edge_comment_widget iframe.fb_rtl{left:2px}
+.fb_edge_widget_with_comment span.fb_send_button_form_widget{left:0;z-index:1}
+.fb_edge_widget_with_comment span.fb_send_button_form_widget .FB_Loader{left:0;top:1px;margin-top:6px;margin-left:0;background-position:50% 50%;background-color:#fff;height:150px;width:394px;border:1px #666 solid;border-bottom:2px solid #283e6c;z-index:1}
+.fb_edge_widget_with_comment span.fb_send_button_form_widget.dark .FB_Loader{background-color:#000;border-bottom:2px solid #ccc}
+.fb_edge_widget_with_comment span.fb_send_button_form_widget.siderender
+.FB_Loader{margin-top:0}
+.fbpluginrecommendationsbarleft,
+.fbpluginrecommendationsbarright{position:fixed !important;bottom:0;z-index:999}
+/* @noflip */
+.fbpluginrecommendationsbarleft{left:10px}
+/* @noflip */
+.fbpluginrecommendationsbarright{right:10px}
+</style></head><body><div style="display: none;" id="MathJax_Message"></div><script type="text/javascript">
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-87333-8']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(ga);
+ })();
+
+</script><div id="wrap"><div id="header"><h1><a href="http://nakkaya.com/">nakkaya<span class="fade-small">dot</span><span class="fade">com</span></a></h1><div class="pages"><a class="page" href="http://nakkaya.com/">Home</a> | <a class="page" href="http://nakkaya.com/projects.html">Projects</a> | <a class="page" href="http://nakkaya.com/archives/">Archives</a> | <a class="page" href="http://nakkaya.com/tags/">Tags</a> | <a class="page" href="http://nakkaya.com/contact.html">About</a><form action="http://www.google.com/search" id="searchform" method="get"><div><input class="box" id="s" name="q" type="text"><input name="sitesearch" value="nakkaya.com" type="hidden"></div></form></div></div><div id="content"><div id="post"><h2>A micro-manual for LISP Implemented in C</h2>
+<p>Recently I had to go through some code that uses the <a href="http://www.sics.se/%7Eadam/uip/index.php/Main_Page">uIP</a> TCP/IP stack,
+which reminded me, it has been a long time since I did something in C
+so I ended up spending the weekend implementing the 10 rules <a href="http://en.wikipedia.org/wiki/John_McCarthy_%28computer_scientist%29">John McCarthy</a> described in his paper <a href="https://docs.google.com/fileview?id=0B0ZnV_0C-Q7IOTRkNzVjZjMtMWE1NC00YzQ3LTgzMWEtM2UwY2I1YzdmNmM5&amp;hl=en">A Micro-Manual for Lisp - not the whole Truth</a>.
+</p>
+<p>
+This is a literate program, the code in this document is the
+executable source, in order to extract it, open this <a href="https://github.com/nakkaya/nakkaya.com/tree/master/resources/posts/2010-08-24-a-micro-manual-for-lisp-implemented-in-c.org">raw file</a> with
+emacs and run,
+</p>
+
+
+
+<pre class="example">M-x org-babel-tangle
+</pre>
+
+
+
+
+
+<pre class="src src-c"><span style="color: #ff5f00; font-weight: bold;">enum</span> <span style="font-weight: bold; text-decoration: underline;">type</span> {<span style="font-weight: bold; font-style: italic;">CONS</span>, <span style="font-weight: bold; font-style: italic;">ATOM</span>, <span style="font-weight: bold; font-style: italic;">FUNC</span>, <span style="font-weight: bold; font-style: italic;">LAMBDA</span>};
+
+<span style="color: #ff5f00; font-weight: bold;">typedef</span> <span style="color: #ff5f00; font-weight: bold;">struct</span>{
+ <span style="color: #ff5f00; font-weight: bold;">enum</span> <span style="font-weight: bold; text-decoration: underline;">type</span> <span style="font-weight: bold; font-style: italic;">type</span>;
+} <span style="font-weight: bold; font-style: italic;">object</span>;
+
+<span style="color: #ff5f00; font-weight: bold;">typedef</span> <span style="color: #ff5f00; font-weight: bold;">struct</span> {
+ <span style="color: #ff5f00; font-weight: bold;">enum</span> <span style="font-weight: bold; text-decoration: underline;">type</span> <span style="font-weight: bold; font-style: italic;">type</span>;
+ <span style="font-weight: bold; text-decoration: underline;">char</span> *<span style="font-weight: bold; font-style: italic;">name</span>;
+} <span style="font-weight: bold; font-style: italic;">atom_object</span>;
+
+<span style="color: #ff5f00; font-weight: bold;">typedef</span> <span style="color: #ff5f00; font-weight: bold;">struct</span> {
+ <span style="color: #ff5f00; font-weight: bold;">enum</span> <span style="font-weight: bold; text-decoration: underline;">type</span> <span style="font-weight: bold; font-style: italic;">type</span>;
+ <span style="font-weight: bold; text-decoration: underline;">object</span> *<span style="font-weight: bold; font-style: italic;">car</span>;
+ <span style="font-weight: bold; text-decoration: underline;">object</span> *<span style="font-weight: bold; font-style: italic;">cdr</span>;
+} <span style="font-weight: bold; font-style: italic;">cons_object</span>;
+
+<span style="color: #ff5f00; font-weight: bold;">typedef</span> <span style="color: #ff5f00; font-weight: bold;">struct</span> {
+ <span style="color: #ff5f00; font-weight: bold;">enum</span> <span style="font-weight: bold; text-decoration: underline;">type</span> <span style="font-weight: bold; font-style: italic;">type</span>;
+ <span style="font-weight: bold; text-decoration: underline;">object</span>* (*<span style="color: #d7af00; font-weight: bold;">fn</span>)(<span style="font-weight: bold; text-decoration: underline;">object</span>*,<span style="font-weight: bold; text-decoration: underline;">object</span>*);
+} <span style="font-weight: bold; font-style: italic;">func_object</span>;
+
+<span style="color: #ff5f00; font-weight: bold;">typedef</span> <span style="color: #ff5f00; font-weight: bold;">struct</span> {
+ <span style="color: #ff5f00; font-weight: bold;">enum</span> <span style="font-weight: bold; text-decoration: underline;">type</span> <span style="font-weight: bold; font-style: italic;">type</span>;
+ <span style="font-weight: bold; text-decoration: underline;">object</span>* <span style="font-weight: bold; font-style: italic;">args</span>;
+ <span style="font-weight: bold; text-decoration: underline;">object</span>* <span style="font-weight: bold; font-style: italic;">sexp</span>;
+} <span style="font-weight: bold; font-style: italic;">lambda_object</span>;
+</pre>
+
+
+
+
+<p>
+We begin by defining four types of objects we will be using. CONS is
+what we use to hold lists, ATOMs are letters or digits anything that is
+not used by LISP, a FUNC holds a reference to a C function and a LAMBDA
+holds a lambda expression.
+</p>
+
+
+
+<pre class="src src-c"><span style="font-weight: bold; text-decoration: underline;">object</span> *<span style="color: #d7af00; font-weight: bold;">read_tail</span>(<span style="font-weight: bold; text-decoration: underline;">FILE</span> *<span style="font-weight: bold; font-style: italic;">in</span>) {
+ <span style="font-weight: bold; text-decoration: underline;">object</span> *<span style="font-weight: bold; font-style: italic;">token</span> = next_token(in);
+
+ <span style="color: #ff5f00; font-weight: bold;">if</span>(strcmp(name(token),<span style="color: #afafff; font-style: italic;">")"</span>) == 0)
+ <span style="color: #ff5f00; font-weight: bold;">return</span> <span style="font-weight: bold; text-decoration: underline;">NULL</span>;
+ <span style="color: #ff5f00; font-weight: bold;">else</span> <span style="color: #ff5f00; font-weight: bold;">if</span>(strcmp(name(token),<span style="color: #afafff; font-style: italic;">"("</span>) == 0) {
+ <span style="font-weight: bold; text-decoration: underline;">object</span> *<span style="font-weight: bold; font-style: italic;">first</span> = read_tail(in);
+ <span style="font-weight: bold; text-decoration: underline;">object</span> *<span style="font-weight: bold; font-style: italic;">second</span> = read_tail(in);
+ <span style="color: #ff5f00; font-weight: bold;">return</span> cons(first, second);
+ }<span style="color: #ff5f00; font-weight: bold;">else</span>{
+ <span style="font-weight: bold; text-decoration: underline;">object</span> *<span style="font-weight: bold; font-style: italic;">first</span> = token;
+ <span style="font-weight: bold; text-decoration: underline;">object</span> *<span style="font-weight: bold; font-style: italic;">second</span> = read_tail(in);
+ <span style="color: #ff5f00; font-weight: bold;">return</span> cons(first, second);
+ }
+}
+
+<span style="font-weight: bold; text-decoration: underline;">object</span> *<span style="color: #d7af00; font-weight: bold;">read</span>(<span style="font-weight: bold; text-decoration: underline;">FILE</span> *<span style="font-weight: bold; font-style: italic;">in</span>) {
+ <span style="font-weight: bold; text-decoration: underline;">object</span> *<span style="font-weight: bold; font-style: italic;">token</span> = next_token(in);
+
+ <span style="color: #ff5f00; font-weight: bold;">if</span>(strcmp(name(token),<span style="color: #afafff; font-style: italic;">"("</span>) == 0)
+ <span style="color: #ff5f00; font-weight: bold;">return</span> read_tail(in);
+
+ <span style="color: #ff5f00; font-weight: bold;">return</span> token;
+}
+</pre>
+
+
+
+
+<p>
+<i>read</i> gets the next token from the file, if it is a left parentheses it
+calls <i>read<sub>tail</sub></i> to parse the rest of the list, otherwise returns the
+token read. A list (LIST e1 … en) is defined for each n to be (CONS
+e1 (CONS … (CONS en NIL))) so <b>read<sub>tail</sub></b> will keep calling itself
+concatenating cons cells until it hits a right parentheses.
+</p>
+
+
+
+<pre class="src src-c"><span style="font-weight: bold; text-decoration: underline;">object</span>* <span style="color: #d7af00; font-weight: bold;">init_env</span>(){
+ <span style="font-weight: bold; text-decoration: underline;">object</span> *<span style="font-weight: bold; font-style: italic;">env</span> = cons(cons(atom(<span style="color: #afafff; font-style: italic;">"QUOTE"</span>),cons(func(&amp;fn_quote),<span style="font-weight: bold; text-decoration: underline;">NULL</span>)),<span style="font-weight: bold; text-decoration: underline;">NULL</span>);
+ append(env,cons(atom(<span style="color: #afafff; font-style: italic;">"CAR"</span>),cons(func(&amp;fn_car),<span style="font-weight: bold; text-decoration: underline;">NULL</span>)));
+ append(env,cons(atom(<span style="color: #afafff; font-style: italic;">"CDR"</span>),cons(func(&amp;fn_cdr),<span style="font-weight: bold; text-decoration: underline;">NULL</span>)));
+ append(env,cons(atom(<span style="color: #afafff; font-style: italic;">"CONS"</span>),cons(func(&amp;fn_cons),<span style="font-weight: bold; text-decoration: underline;">NULL</span>)));
+ append(env,cons(atom(<span style="color: #afafff; font-style: italic;">"EQUAL"</span>),cons(func(&amp;fn_equal),<span style="font-weight: bold; text-decoration: underline;">NULL</span>)));
+ append(env,cons(atom(<span style="color: #afafff; font-style: italic;">"ATOM"</span>),cons(func(&amp;fn_atom),<span style="font-weight: bold; text-decoration: underline;">NULL</span>)));
+ append(env,cons(atom(<span style="color: #afafff; font-style: italic;">"COND"</span>),cons(func(&amp;fn_cond),<span style="font-weight: bold; text-decoration: underline;">NULL</span>)));
+ append(env,cons(atom(<span style="color: #afafff; font-style: italic;">"LAMBDA"</span>),cons(func(&amp;fn_lambda),<span style="font-weight: bold; text-decoration: underline;">NULL</span>)));
+ append(env,cons(atom(<span style="color: #afafff; font-style: italic;">"LABEL"</span>),cons(func(&amp;fn_label),<span style="font-weight: bold; text-decoration: underline;">NULL</span>)));
+
+ tee = atom(<span style="color: #afafff; font-style: italic;">"#T"</span>);
+ nil = cons(<span style="font-weight: bold; text-decoration: underline;">NULL</span>,<span style="font-weight: bold; text-decoration: underline;">NULL</span>);
+
+ <span style="color: #ff5f00; font-weight: bold;">return</span> env;
+}
+</pre>
+
+
+
+
+<p>
+Now that we have a list to execute, we need to define the environment we
+will be evaluating the expressions in. Environment is a list of pairs
+during evaluation we replace those atoms with their values, we also
+define tee to be the atom <b>#T</b> and nil to be the empty list.
+</p>
+
+
+
+<pre class="src src-c"><span style="font-weight: bold; text-decoration: underline;">object</span> *<span style="color: #d7af00; font-weight: bold;">eval_fn</span> (<span style="font-weight: bold; text-decoration: underline;">object</span> *<span style="font-weight: bold; font-style: italic;">sexp</span>, <span style="font-weight: bold; text-decoration: underline;">object</span> *<span style="font-weight: bold; font-style: italic;">env</span>){
+ <span style="font-weight: bold; text-decoration: underline;">object</span> *<span style="font-weight: bold; font-style: italic;">symbol</span> = car(sexp);
+ <span style="font-weight: bold; text-decoration: underline;">object</span> *<span style="font-weight: bold; font-style: italic;">args</span> = cdr(sexp);
+
+ <span style="color: #ff5f00; font-weight: bold;">if</span>(symbol-&gt;type == LAMBDA)
+ <span style="color: #ff5f00; font-weight: bold;">return</span> fn_lambda(sexp,env);
+ <span style="color: #ff5f00; font-weight: bold;">else</span> <span style="color: #ff5f00; font-weight: bold;">if</span>(symbol-&gt;type == FUNC)
+ <span style="color: #ff5f00; font-weight: bold;">return</span> (((<span style="font-weight: bold; text-decoration: underline;">func_object</span> *) (symbol))-&gt;fn)(args, env);
+ <span style="color: #ff5f00; font-weight: bold;">else</span>
+ <span style="color: #ff5f00; font-weight: bold;">return</span> sexp;
+}
+
+<span style="font-weight: bold; text-decoration: underline;">object</span> *<span style="color: #d7af00; font-weight: bold;">eval</span> (<span style="font-weight: bold; text-decoration: underline;">object</span> *<span style="font-weight: bold; font-style: italic;">sexp</span>, <span style="font-weight: bold; text-decoration: underline;">object</span> *<span style="font-weight: bold; font-style: italic;">env</span>) {
+ <span style="color: #ff5f00; font-weight: bold;">if</span>(sexp == <span style="font-weight: bold; text-decoration: underline;">NULL</span>)
+ <span style="color: #ff5f00; font-weight: bold;">return</span> nil;
+
+ <span style="color: #ff5f00; font-weight: bold;">if</span>(sexp-&gt;type == CONS){
+ <span style="color: #ff5f00; font-weight: bold;">if</span>(car(sexp)-&gt;type == ATOM &amp;&amp; strcmp(name(car(sexp)), <span style="color: #afafff; font-style: italic;">"LAMBDA"</span>) == 0){
+ <span style="font-weight: bold; text-decoration: underline;">object</span>* <span style="font-weight: bold; font-style: italic;">largs</span> = car(cdr(sexp));
+ <span style="font-weight: bold; text-decoration: underline;">object</span>* <span style="font-weight: bold; font-style: italic;">lsexp</span> = car(cdr(cdr(sexp)));
+
+ <span style="color: #ff5f00; font-weight: bold;">return</span> lambda(largs,lsexp);
+ }<span style="color: #ff5f00; font-weight: bold;">else</span>{
+ <span style="font-weight: bold; text-decoration: underline;">object</span> *<span style="font-weight: bold; font-style: italic;">accum</span> = cons(eval(car(sexp),env),<span style="font-weight: bold; text-decoration: underline;">NULL</span>);
+ sexp = cdr(sexp);
+
+ <span style="color: #ff5f00; font-weight: bold;">while</span> (sexp != <span style="font-weight: bold; text-decoration: underline;">NULL</span> &amp;&amp; sexp-&gt;type == CONS){
+ append(accum,eval(car(sexp),env));
+ sexp = cdr(sexp);
+ }
+
+ <span style="color: #ff5f00; font-weight: bold;">return</span> eval_fn(accum,env);
+ }
+ }<span style="color: #ff5f00; font-weight: bold;">else</span>{
+ <span style="font-weight: bold; text-decoration: underline;">object</span> *<span style="font-weight: bold; font-style: italic;">val</span> = lookup(name(sexp),env);
+ <span style="color: #ff5f00; font-weight: bold;">if</span>(val == <span style="font-weight: bold; text-decoration: underline;">NULL</span>)
+ <span style="color: #ff5f00; font-weight: bold;">return</span> sexp;
+ <span style="color: #ff5f00; font-weight: bold;">else</span>
+ <span style="color: #ff5f00; font-weight: bold;">return</span> val;
+ }
+}
+</pre>
+
+
+
+
+<p>
+When we pass an S-Expression to eval, first we need to check if it is a
+lambda expression if it is we don't evaluate it we just return a lambda
+object, if it is a list we call eval for each cell, this allows us to
+iterate through all the atoms in the list when we hit an atom we lookup
+its value in the environment if it has a value associated with it we
+return that otherwise we return the atom, at this point,
+</p>
+
+
+
+<pre class="example">(QUOTE A)
+</pre>
+
+
+
+
+<p>
+is transformed into,
+</p>
+
+
+
+<pre class="example">(func-obj atom-obj)
+</pre>
+
+
+
+
+<p>
+all eval_fn has to do is check the type of the car of the list, if it is
+a function_object it will call the function pointed by the
+function_object passing cdr of the list as argument, if it is a
+lambda_object we call the fn_lambda which executes the lambda
+expression else we return the S-Expression.
+</p>
+<p>
+Each function<sub>object</sub> holds a pointer to a function that takes two
+arguments, arguments to the function and the environment we are executing
+it in and returns an object.
+</p>
+
+
+
+<pre class="src src-c"><span style="font-weight: bold; text-decoration: underline;">object</span> *<span style="color: #d7af00; font-weight: bold;">fn_lambda</span> (<span style="font-weight: bold; text-decoration: underline;">object</span> *<span style="font-weight: bold; font-style: italic;">args</span>, <span style="font-weight: bold; text-decoration: underline;">object</span> *<span style="font-weight: bold; font-style: italic;">env</span>) {
+ <span style="font-weight: bold; text-decoration: underline;">object</span> *<span style="font-weight: bold; font-style: italic;">lambda</span> = car(args);
+ args = cdr(args);
+
+ <span style="font-weight: bold; text-decoration: underline;">object</span> *<span style="font-weight: bold; font-style: italic;">list</span> = interleave((((<span style="font-weight: bold; text-decoration: underline;">lambda_object</span> *) (lambda))-&gt;args),args);
+ <span style="font-weight: bold; text-decoration: underline;">object</span>* <span style="font-weight: bold; font-style: italic;">sexp</span> = replace_atom((((<span style="font-weight: bold; text-decoration: underline;">lambda_object</span> *) (lambda))-&gt;sexp),list);
+ <span style="color: #ff5f00; font-weight: bold;">return</span> eval(sexp,env);
+}
+</pre>
+
+
+
+
+<p>
+A lambda<sub>object</sub> holds two lists,
+</p>
+
+
+
+<pre class="example">(LAMBDA (X Y) (CONS (CAR X) Y))
+args -&gt; (X Y)
+sexp -&gt; (CONS (CAR X) Y))
+</pre>
+
+
+
+
+<p>
+to execute it first thing we do is interleave the args list with the
+arguments passed so while executing following,
+</p>
+
+
+
+<pre class="example">((LAMBDA (X Y) (CONS (CAR X) Y)) (QUOTE (A B)) (CDR (QUOTE (C D))))
+</pre>
+
+
+
+
+<p>
+list will be,
+</p>
+
+
+
+<pre class="example">((X (A B)) (Y (D)))
+</pre>
+
+
+
+
+<p>
+then we iterate over the sexp and replace every occurrence of X with (A
+B) and every occurrence of Y with (D) then call eval on the resulting
+expression.
+</p>
+<p>
+This covers everything we need to interpret the LISP defined in the
+paper passing a file containing the following,
+</p>
+
+
+
+<pre class="example">(QUOTE A)
+(QUOTE (A B C))
+(CAR (QUOTE (A B C)))
+(CDR (QUOTE (A B C)))
+(CONS (QUOTE A) (QUOTE (B C)))
+(EQUAL (CAR (QUOTE (A B))) (QUOTE A))
+(EQUAL (CAR (CDR (QUOTE (A B)))) (QUOTE A))
+(ATOM (QUOTE A))
+(COND ((ATOM (QUOTE A)) (QUOTE B)) ((QUOTE T) (QUOTE C)))
+((LAMBDA (X Y) (CONS (CAR X) Y)) (QUOTE (A B)) (CDR (QUOTE (C D))))
+(LABEL FF (LAMBDA (X Y) (CONS (CAR X) Y)))
+(FF (QUOTE (A B)) (CDR (QUOTE (C D))))
+(LABEL XX (QUOTE (A B)))
+(CAR XX)
+</pre>
+
+
+
+
+<p>
+should produce,
+</p>
+
+
+
+<pre class="example">lisp/ $ gcc -Wall lisp.c &amp;&amp; ./a.out test.lisp
+&gt; A
+&gt; (A B C)
+&gt; A
+&gt; (B C)
+&gt; (A B C)
+&gt; #T
+&gt; ()
+&gt; #T
+&gt; B
+&gt; (A D)
+&gt; #T
+&gt; (A D)
+&gt; #T
+&gt; A
+</pre>
+
+
+
+
+<div class="post-tags">Tags: <a href="http://nakkaya.com/tags/#lisp">lisp </a><a href="http://nakkaya.com/tags/#c">c </a></div></div><div id="related"><h3>Random Posts</h3><ul class="posts"><li><span>24 Sep 2009</span><a href="http://nakkaya.com/2009/09/24/git-delete-last-commit/">Git Delete Last Commit</a></li><li><span>02 Sep 2010</span><a href="http://nakkaya.com/2010/09/02/eval-with-local-bindings/">Eval with Local Bindings</a></li><li><span>30 Nov 2009</span><a href="http://nakkaya.com/2009/11/30/running-compojure-as-a-service/">Running Compojure as a Service</a></li><li><span>28 Oct 2009</span><a href="http://nakkaya.com/2009/10/28/connecting-mysql-client-to-a-remote-mysql-server/">Connecting MySQL Client to a Remote MySQL Server</a></li><li><span>06 Dec 2009</span><a href="http://nakkaya.com/2009/12/06/java-taskbar-icon-on-windows-7/">Java Taskbar Icon on Windows 7</a></li></ul></div><div id="disqus"><div id="disqus_thread"><div style="display: none;" id="dsq-content-stub"><img alt="DISQUS" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEcAAAARCAYAAAH4YIFjAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAABwdJREFUeNpi/P//PwMhwAIiGBkZGeK6V8JVh9rqdfrc0ixnEDb+wPD2rAAjMSYBBBBRisDWwKxCthIE/q8Q+A8yhCiTAAIIrCi+ZxVMZSAQr19UGs4IMxWd/X8Rw3/GOKDhW43fgzwF1hX7n5EJ2dSp2QFNUKcZwJ31/78CkvPBGkGGMXidSUTWCxBAxAUAEQAcJzCvIXsDBPwsNBU2nbj+AMpdsFA8PAHsLZj3QC5D9hrIAEtN+RMwAzRkxcB0iK3eQ6iQIRAnoMTE//8CyHwmWHQdv/7QAiZ44/ErMP383acsqNB5iMnPlsFdsUZ6IU3CCCCA4AYBw8kBJgj06gGkmHJAFgPyQV4ExeQEoNgHJHUBQMoAWRzoerBeYHgeQOJ/APIvQPkNUP4EuIdADBAGBRMQOABxQcakdSipHZldNGvL2zWHL8kD1d0HieVN33QYqnc/EAfULNwJVw8KTniQwvjAdPz/SEwKmL1KfC5QjwEQr4e5AyVdA3P4ASCe8O3nb1whmtib6r3IXlfpATBEFbpWH9ygJSdmBtXrOHPbyZWPXn1AqOZRwDSBS+YHo82SOQwiZnYMoS+EGC42nGdYzBiAnKpgGAbeA3ECkjwYQNnzH758///6o5cgofVIagy+/vgFF//y/ecHJLn1/18AA+/teZBcPZL4eSTxBJg7AAKIaomRmpkeV2IG5UcDpMSsAM2zF4BiG9DUFaCLQxPwBWCC/QBkg/QqoCVuEN4ASuDIaWc/DIMSItBxH0GCrkaqCVBxWO4BJWBQcK/PmrL+I1S8H0i9h4mjFfX7GTRyIdEuHzIfZtb/Zdw3oGyQnvP/d9pNgRc+MLCwJMxxWk7AI6Ar+YCWVSLLyYkJzIYlZqC6RGBhbg/lFwDlQHoDgfgALLfhjY8/X9XhpWPs/wWM7odyMBwDylU8nOzyILYIH3cZslxBgM0cKHM+MOTAGCZnri7XCdS7ASgGLsc/fPlug9cxlrO/wUvYxYwJwCgLwHAMcrVlqCJ9BVlchJ+7EhRyQPwAyGaAFnhgsOPMzUhQroLVAU76yp/gGp/vtQbTr45pwMWOp1oDQ6QQiGEi6+EJGLmah0YJQ6CVtu3ivecKYHIpE9b8BPqcDSnawHSSu8m3eTvPyAHlzsPkDl25/wXMYAOq+XgtBFwIfn/GwCAOSq8HYCGCsNh8+hvksgYZIJchDkjljAKoHAKVJ6ByBbnmA5XESOL1oFIZSc9/cJkC1IukPuH/z/cw8fswdwyqcgYgwAaVYwYbQEnDSI1LbGABEDcCC1lYS4yhfO42n+fvPm9GKsAZkfJDA7RcwwYmQM1CbpUUADU3AB3AjxJ7wFwAFGsAqp2A0mBDahww8Gv4Mvrf2AKXWyMzgeHbk3wwh5X/DGPkR1OoHlCmn49cGCABkL8SgZn8ANbAQQaV4ZBK6yGwgbDr3G2GNx+/gkqShMTe1V///vsnA/KYjoKECjBwMPQCW0EngOrNQWxbHQWGFA8zBlAj5eztpwwbjl9lyPG1DFOUEAIFDqxJB6ksoC1ZN2NVsDm7zt4GNUhBgdUPrXwckWtQOJB0VQE2XRF8UQt9hodrIGw+FaDcWVjAwAshhsD7kAbPO2Dr78ZEBoZfHxQYHNYbwEogvIGjKSfOiNysBpaEL/acv8MODBhuUX7u00BhVVx6DZWlxHcDAxQEDl95AMZQAGqHLlSSFIanAnZWll0/f/8Bs2OcDB+5GavJVyGZtevsrYdL9p2XQ6rZGcnKI54nZRj2uoMCAVr4K8JkQAKgJsdEYN12AbmYYSGqYGJk/NC8bO91WHKUFRXgwace6ElDIF4PjHWHc3eeMZy98xSU8mB1mwE0FSQCU8ECZiZGVpi+yw9eLIfVlUyMjIf+/f/Pu/bIlTtIdSX5hauo+RagxxMZfr2fwHB3IT/Dy4MMDI/BzTABaP2aAGzmgPpN4gQDB1pmgIA+EAfcfvoGXl/mB1hXFuBxCLDs6oc26kBJZiIoxShLCqs9e/tp+vdfv8ENB08Tdf9FwHKsMtxxTfvK/SGgbHfx3vNyoL2g7DjR30r74vqjV2yA6lXgbnI2WtoH4yhEfGF4sAISSTcm9wOzDcidoE6lPTBLwRuyDMoJ5+DZagnLJIb/f3mh5edGcKoRs+5neHUUUgZxiIrhrK2wFchc7KwMmsByANjiAZUfoGzhCEpJIDlQowOYffqRC2RQS+f1x68HNx6/ygcqY9A7RMZAc5LcTS/zcLLZwcwB1evAzs/8pfsvwDu9yOplgRECzF4M8a7Gryw05NRB+sDtiC/3HjKcKeaDpgAEADVmNIDlsX4DqFPmCOvvMNxdkAAuX95dQFUPKnv06kEBmQgNOLpV5QbQpAsrcz4QUC+AVJsgqxcgoNcBqQy5QIIdONUDALcn6c0dtMJ9AAAAAElFTkSuQmCC" height="17" width="71"><img alt="..." src="data:image/gif;base64,R0lGODlhEAALAPQAAP///z2LqeLt8dvp7u7090GNqz2LqV+fuJ/F1IW2ycrf51aatHWswaXJ14i4ys3h6FmctUCMqniuw+vz9eHs8fb5+meku+Tu8vT4+cfd5bbT3tbm7PH2+AAAAAAAAAAAACH/C05FVFNDQVBFMi4wAwEAAAAh/hpDcmVhdGVkIHdpdGggYWpheGxvYWQuaW5mbwAh+QQJCwAAACwAAAAAEAALAAAFLSAgjmRpnqSgCuLKAq5AEIM4zDVw03ve27ifDgfkEYe04kDIDC5zrtYKRa2WQgAh+QQJCwAAACwAAAAAEAALAAAFJGBhGAVgnqhpHIeRvsDawqns0qeN5+y967tYLyicBYE7EYkYAgAh+QQJCwAAACwAAAAAEAALAAAFNiAgjothLOOIJAkiGgxjpGKiKMkbz7SN6zIawJcDwIK9W/HISxGBzdHTuBNOmcJVCyoUlk7CEAAh+QQJCwAAACwAAAAAEAALAAAFNSAgjqQIRRFUAo3jNGIkSdHqPI8Tz3V55zuaDacDyIQ+YrBH+hWPzJFzOQQaeavWi7oqnVIhACH5BAkLAAAALAAAAAAQAAsAAAUyICCOZGme1rJY5kRRk7hI0mJSVUXJtF3iOl7tltsBZsNfUegjAY3I5sgFY55KqdX1GgIAIfkECQsAAAAsAAAAABAACwAABTcgII5kaZ4kcV2EqLJipmnZhWGXaOOitm2aXQ4g7P2Ct2ER4AMul00kj5g0Al8tADY2y6C+4FIIACH5BAkLAAAALAAAAAAQAAsAAAUvICCOZGme5ERRk6iy7qpyHCVStA3gNa/7txxwlwv2isSacYUc+l4tADQGQ1mvpBAAIfkECQsAAAAsAAAAABAACwAABS8gII5kaZ7kRFGTqLLuqnIcJVK0DeA1r/u3HHCXC/aKxJpxhRz6Xi0ANAZDWa+kEAA7AAAAAAAAAAAA" style="margin: 0pt 0pt 3px 5px;" height="11" width="16"></div><div class="clearfix" style="display: block;" id="dsq-content"> <div id="dsq-global-toolbar" class="dsq-clearfix"> <ul class="dsq-global-toolbar-right dsq-clearfix"> <li class="dsq-community-box"> <a href="#" class="dsq-toolbar-item dsq-tt" onclick="DISQUS.dtpl.actions.fire('community.show'); return false" title="Expand Community Box"><span class="dsq-toolbar-icon"></span></a> </li> <li class="dsq-global-toolbar-dropdown-container"> <div id="dsq-toolbar-dropdown"> <a href="#" class="dsq-toolbar-logo dsq-toolbar-item dsq-clearfix"><span class="dsq-toolbar-icon">Disqus</span></a> <div id="dsq-toolbar-dropdown-wrap" style="display: none"> <ul class="dsq-clearfix"> <li class="dsq-login-link"><a href="#" onclick="DISQUS.dtpl.actions.fire('auth.login'); return false"><span class="dsq-toolbar-icon"></span><span class="dsq-toolbar-label">Login</span></a></li> <li class="dsq-about-link"><a href="http://disqus.com/" target="_blank"><span class="dsq-toolbar-icon"></span><span class="dsq-toolbar-label">About Disqus</span></a></li> </ul> </div> </div> </li> </ul> <ul class="dsq-global-toolbar-left dsq-clearfix"> <li class="dsq-like-thread"> <a href="#" id="dsq-like-thread-button" class="dsq-toolbar-item dsq-clearfix dsq-tt" onclick="DISQUS.dtpl.actions.fire('thread.vote', 1); return false;" title="I like this page"> <span class="dsq-toolbar-icon"></span> <span class="dsq-toolbar-label">Like</span> </a> </li> <li class="dsq-dislike-thread"> <a href="#" id="dsq-dislike-thread-button" class="dsq-toolbar-item dsq-clearfix dsq-tt" onclick="DISQUS.dtpl.actions.fire('thread.vote', -1); return false" title="I don't like this page"> <span class="dsq-toolbar-icon">Dislike</span> </a> </li> <li class="dsq-like-panel"> <ul class="dsq-like-faces dsq-clearfix"> <li class="dsq-tt" title="Mark Stock"><a href="http://disqus.com/openid-33348/" onclick="return DISQUS.dtpl.actions.fire('profile.show', null, 'openid-33348', false); return false"><img src="A%20micro-manual%20for%20LISP%20Implemented%20in%20C%20%28by%20Nurullah%20Akkaya%29_files/avatar32.jpg"></a></li> <li class="dsq-like-activity"> and 8 others liked this. </li> </ul> </li> </ul> </div> <div id="dsq-like-tooltip"> <div id="dsq-share-step-1" class="dsq-share-step"> <h3>Glad you liked it. Would you like to share?</h3> <p class="dsq-tooltip-checkbox"><input id="dsq-share-thread-facebook" value="Facebook" type="checkbox"><label for="dsq-share-thread-facebook"><span class="dsq-facebook">Facebook</span></label></p> <p class="dsq-tooltip-checkbox"><input id="dsq-share-thread-twitter" value="Twitter" type="checkbox"><label for="dsq-share-thread-twitter"><span class="dsq-twitter">Twitter</span></label></p> <ul id="dsq-tooltip-actions"> <li><a href="#" onclick="DISQUS.dtpl.actions.fire('thread.share.send'); return false" class="dsq-primary-action">Share</a></li> <li><a href="#" onclick="DISQUS.dtpl.actions.fire('thread.share.cancel'); return false" class="dsq-secondary-action">No thanks</a></li> </ul> </div> <div id="dsq-share-step-2" class="dsq-share-step" style="display:none !important"> <p>Sharing this page …</p> </div> <div id="dsq-share-step-3" class="dsq-share-step" style="display:none !important"> <p>Thanks! <a href="#" class="dsq-tooltip-decline" onclick="DISQUS.dtpl.actions.fire('thread.share.cancel'); return false">Close</a></p> </div> </div> <div class="dsq-reply " id="dsq-reply"> <div id="dsq-account-dropdown"> <a href="#" onclick="DISQUS.dtpl.actions.fire('auth.login'); return false;">Login</a> </div> <h3>Add New Comment</h3> <div class="dsq-avatar"> <img src="A%20micro-manual%20for%20LISP%20Implemented%20in%20C%20%28by%20Nurullah%20Akkaya%29_files/noavatar32.png"> </div> <div class="dsq-textarea dsq-textarea-reply"> <div class="dsq-textarea-background"> <div style="height: auto;" class="dsq-textarea-wrapper"> <!-- filled dynamically --> <iframe style="height: 58px;" src="A%20micro-manual%20for%20LISP%20Implemented%20in%20C%20%28by%20Nurullah%20Akkaya%29_files/reply.html" id="easyXDM_DISQUS_net_default7968_provider" name="easyXDM_DISQUS_net_default7968_provider" frameborder="0" scrolling="no"></iframe></div> <div id="dsq-media-preview" class="dsq-media-preview" style="display:none"> </div> <div class="dsq-post-tools"> <ul> <li class="dsq-post-as"> <button type="button" class="dsq-button" onclick="DISQUS.dtpl.actions.fire('comments.validate', null, this);"> Post as … </button> </li> <li class="dsq-attach-media"> <div class="dsq-attach-media-container"> <span>Image</span> <!-- filled dynamically --> <iframe src="A%20micro-manual%20for%20LISP%20Implemented%20in%20C%20%28by%20Nurullah%20Akkaya%29_files/upload.html" id="easyXDM_DISQUS_net_default7969_provider" name="easyXDM_DISQUS_net_default7969_provider" frameborder="0" scrolling="no"></iframe></div> </li> <li class="dsq-share-on dsq-clearfix"> </li> </ul> </div> </div> </div> </div> <div id="dsq-sort-by"> <select id="dsq-sort-select" onchange="DISQUS.dtpl.actions.fire('thread.sort', this.value);"> <option value="hot" selected="selected"> Sort by popular now </option> <option value="best"> Sort by best rating </option> <option value="newest"> Sort by newest first </option> <option value="oldest"> Sort by oldest first </option> </select> </div> <h3> Showing <span id="dsq-num-posts">5</span> of <span id="dsq-total-posts">21</span> comments </h3> <ul id="dsq-comments"> <li id="dsq-comment-70948050" data-dsq-comment-id="70948050" class="dsq-comment dsq-clearfix " style="margin-left:0px;"> <div class="dsq-avatar dsq-tt" title="Expand edgargoncalves's profile"> <a href="http://disqus.com/edgargoncalves/" onclick="DISQUS.dtpl.actions.fire('profile.show', 70948050, null); return false"> <img src="A%20micro-manual%20for%20LISP%20Implemented%20in%20C%20%28by%20Nurullah%20Akkaya%29_files/avatar32_002.jpg" class="" alt=""> </a> </div> <div id="dsq-comment-body-70948050" class="dsq-comment-body"> <div class="dsq-comment-header"> <a href="http://edgar.goncalves.googlepages.com/" target="_blank" class="dsq-commenter-name" rel="nofollow">edgargoncalves</a><span class="dsq-commenter-bio">, Software Engineer, PhD Student working on offline web applications. </span> <span class="dsq-collapsed-count"> 1 comment collapsed </span> <a href="#" class="dsq-collapse-toggle dsq-collapse" title="Collapse thread" onclick="DISQUS.dtpl.actions.fire('comments.collapse', 70948050); return false;"><span>Collapse</span></a> <a href="#" class="dsq-collapse-toggle dsq-expand" title="Expand thread" onclick="DISQUS.dtpl.actions.fire('comments.expand', 70948050); return false;"><span>Expand</span></a> </div> <div class="dsq-comment-message" id="dsq-comment-message-70948050"> <div class="dsq-comment-text" id="dsq-comment-text-70948050">
+ Easy to read, easy to understand, and apparently quick to
+implement. You managed to present the simplicity that should be the
+hallmark of a LISP implementation. Kudos! </div> </div> <!-- edit box dynamically inserted here --> <div id="dsq-append-edit-70948050"></div> <div class="dsq-comment-footer"> <ul class="dsq-comment-actions"> <li id="dsq-like-70948050"> <span class="dsq-like-thumb dsq-font">A</span> <a href="#" onclick="DISQUS.dtpl.actions.fire('comments.like', this,70948050); return false">Like</a> </li> <li> <a href="#" class="dsq-comment-reply" onclick="DISQUS.dtpl.actions.fire('comments.reply',70948050, this); return false">Reply</a> </li> </ul> <ul class="dsq-comment-meta"> <li> <a href="#comment-70948050" onclick="DISQUS.dtpl.actions.fire('comments.permalink', 70948050);" title="Link to comment by edgargoncalves"> 1 year ago </a></li> <li> <a href="#" id="dsq-comment-like-count-70948050" class="dsq-comment-like-count" onclick="return DISQUS.dtpl.actions.fire('comments.showUserVotes', 70948050); return false">1 Like </a> </li> <li class="dsq-comment-flag" style="visibility: hidden"> <a href="#" class="dsq-comment-flag dsq-font" onclick="return DISQUS.dtpl.actions.fire('comments.report', 70948050, false);">F</a> </li> </ul> </div> <!-- reply box dynamically inserted here --> <div id="dsq-append-reply-70948050"></div> </div> </li> <!-- new replies dynamically inserted here --> <li id="dsq-append-post-70948050"></li> <li id="dsq-comment-229906679" data-dsq-comment-id="229906679" class="dsq-comment dsq-clearfix " style="margin-left:0px;"> <div class="dsq-avatar dsq-tt" title="Expand Alen Ribic's profile"> <a href="http://disqus.com/guest/43072573fba33595e20a82c086d6df07/" onclick="DISQUS.dtpl.actions.fire('profile.show', 229906679, null); return false"> <img src="A%20micro-manual%20for%20LISP%20Implemented%20in%20C%20%28by%20Nurullah%20Akkaya%29_files/noavatar32.png" class="dsq-deferred-avatar" data-src="http://media.disqus.com/uploads/anonusers/112/9233/avatar32.jpg" alt=""> </a> </div> <div id="dsq-comment-body-229906679" class="dsq-comment-body"> <div class="dsq-comment-header"> <span class="dsq-commenter-name">Alen Ribic</span> <span class="dsq-collapsed-count"> 1 comment collapsed </span> <a href="#" class="dsq-collapse-toggle dsq-collapse" title="Collapse thread" onclick="DISQUS.dtpl.actions.fire('comments.collapse', 229906679); return false;"><span>Collapse</span></a> <a href="#" class="dsq-collapse-toggle dsq-expand" title="Expand thread" onclick="DISQUS.dtpl.actions.fire('comments.expand', 229906679); return false;"><span>Expand</span></a> </div> <div class="dsq-comment-message" id="dsq-comment-message-229906679"> <div class="dsq-comment-text" id="dsq-comment-text-229906679"> The *eval function, as it stands, evaluates all forms in a give expression.&nbsp;<br>This is a problem of course when introducing special forms, i.e. COND (fn_cond).<br><br>I came across this problem when trying to write a recursive function (with label + lambda).<br><br>As
+ a solution, one could add a new object type called COND, it is a
+special form after all. Then in *eval function write a dedicated
+condition to handle partial evaluation of the given Cons
+structure.&nbsp;<br>Using this new type one could then use it to&nbsp;easily implement&nbsp;IF, WHEN, and other related special forms. </div> </div> <!-- edit box dynamically inserted here --> <div id="dsq-append-edit-229906679"></div> <div class="dsq-comment-footer"> <ul class="dsq-comment-actions"> <li id="dsq-like-229906679"> <span class="dsq-like-thumb dsq-font">A</span> <a href="#" onclick="DISQUS.dtpl.actions.fire('comments.like', this,229906679); return false">Like</a> </li> <li> <a href="#" class="dsq-comment-reply" onclick="DISQUS.dtpl.actions.fire('comments.reply',229906679, this); return false">Reply</a> </li> </ul> <ul class="dsq-comment-meta"> <li> <a href="#comment-229906679" onclick="DISQUS.dtpl.actions.fire('comments.permalink', 229906679);" title="Link to comment by Alen Ribic"> 5 months ago </a></li> <li style="display:none"> <a href="#" id="dsq-comment-like-count-229906679" class="dsq-comment-like-count" onclick="return DISQUS.dtpl.actions.fire('comments.showUserVotes', 229906679); return false">0 Like </a> </li> <li class="dsq-comment-flag" style="visibility: hidden"> <a href="#" class="dsq-comment-flag dsq-font" onclick="return DISQUS.dtpl.actions.fire('comments.report', 229906679, false);">F</a> </li> </ul> </div> <!-- reply box dynamically inserted here --> <div id="dsq-append-reply-229906679"></div> </div> </li> <!-- new replies dynamically inserted here --> <li id="dsq-append-post-229906679"></li> <li id="dsq-comment-229547088" data-dsq-comment-id="229547088" class="dsq-comment dsq-clearfix dsq-comment-is-parent " style="margin-left:0px;"> <div class="dsq-avatar dsq-tt" title="Expand Alen Ribic's profile"> <a href="http://disqus.com/guest/43072573fba33595e20a82c086d6df07/" onclick="DISQUS.dtpl.actions.fire('profile.show', 229547088, null); return false"> <img src="A%20micro-manual%20for%20LISP%20Implemented%20in%20C%20%28by%20Nurullah%20Akkaya%29_files/noavatar32.png" class="dsq-deferred-avatar" data-src="http://media.disqus.com/uploads/anonusers/112/9233/avatar32.jpg" alt=""> </a> </div> <div id="dsq-comment-body-229547088" class="dsq-comment-body"> <div class="dsq-comment-header"> <span class="dsq-commenter-name">Alen Ribic</span> <span class="dsq-collapsed-count"> 3 comments collapsed </span> <a href="#" class="dsq-collapse-toggle dsq-collapse" title="Collapse thread" onclick="DISQUS.dtpl.actions.fire('comments.collapse', 229547088); return false;"><span>Collapse</span></a> <a href="#" class="dsq-collapse-toggle dsq-expand" title="Expand thread" onclick="DISQUS.dtpl.actions.fire('comments.expand', 229547088); return false;"><span>Expand</span></a> </div> <div class="dsq-comment-message" id="dsq-comment-message-229547088"> <div class="dsq-comment-text" id="dsq-comment-text-229547088"> <br><br><br><br><br>p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo}<br><br><br><br>The fn_cond function causes segmentation fault when pred is nil and not #T.<br><br>An if check on the car(list) will do the trick.<br><br><br><br><br>p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo}<br>p.p2 {margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo; min-height: 13.0px}<br>p.p3 {margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo; color: #cf00a0}<br>span.s1 {color: #3c8389}<br>span.s2 {color: #cf00a0}<br>span.s3 {color: #215a5f}<br>span.s4 {color: #804623}<br>span.s5 {color: #000000}<br>span.Apple-tab-span {white-space:pre}<br><br><br><br>object *fn_cond(object *args, object *env) {<br> <br> while (args != NULL &amp;&amp; args-&gt;type == CONS) {<br> object *list = car(args);<br> object *pred = nil;<br> if (car(list) != nil)<br> pred = eval(car(list), env);<br> object *ret = car(cdr(list));<br> <br> if(pred != nil)<br> return eval(ret,env);<br> <br> args = cdr(args);<br> }<br> <br> return nil;<br>} </div> </div> <!-- edit box dynamically inserted here --> <div id="dsq-append-edit-229547088"></div> <div class="dsq-comment-footer"> <ul class="dsq-comment-actions"> <li id="dsq-like-229547088"> <span class="dsq-like-thumb dsq-font">A</span> <a href="#" onclick="DISQUS.dtpl.actions.fire('comments.like', this,229547088); return false">Like</a> </li> <li> <a href="#" class="dsq-comment-reply" onclick="DISQUS.dtpl.actions.fire('comments.reply',229547088, this); return false">Reply</a> </li> </ul> <ul class="dsq-comment-meta"> <li> <a href="#comment-229547088" onclick="DISQUS.dtpl.actions.fire('comments.permalink', 229547088);" title="Link to comment by Alen Ribic"> 5 months ago </a></li> <li style="display:none"> <a href="#" id="dsq-comment-like-count-229547088" class="dsq-comment-like-count" onclick="return DISQUS.dtpl.actions.fire('comments.showUserVotes', 229547088); return false">0 Like </a> </li> <li class="dsq-comment-flag" style="visibility: hidden"> <a href="#" class="dsq-comment-flag dsq-font" onclick="return DISQUS.dtpl.actions.fire('comments.report', 229547088, false);">F</a> </li> </ul> </div> <!-- reply box dynamically inserted here --> <div id="dsq-append-reply-229547088"></div> </div> </li> <!-- new replies dynamically inserted here --> <li id="dsq-append-post-229547088"></li> <li id="dsq-comment-229548308" data-dsq-comment-id="229548308" class="dsq-comment dsq-clearfix dsq-comment-is-parent " style="margin-left:46px;"> <div class="dsq-avatar dsq-tt" title="Expand Alen Ribic's profile"> <a href="http://disqus.com/guest/43072573fba33595e20a82c086d6df07/" onclick="DISQUS.dtpl.actions.fire('profile.show', 229548308, null); return false"> <img src="A%20micro-manual%20for%20LISP%20Implemented%20in%20C%20%28by%20Nurullah%20Akkaya%29_files/noavatar32.png" class="dsq-deferred-avatar" data-src="http://media.disqus.com/uploads/anonusers/112/9233/avatar32.jpg" alt=""> </a> </div> <div id="dsq-comment-body-229548308" class="dsq-comment-body"> <div class="dsq-comment-header"> <span class="dsq-commenter-name">Alen Ribic</span> <span class="dsq-collapsed-count"> 2 comments collapsed </span> <a href="#" class="dsq-collapse-toggle dsq-collapse" title="Collapse thread" onclick="DISQUS.dtpl.actions.fire('comments.collapse', 229548308); return false;"><span>Collapse</span></a> <a href="#" class="dsq-collapse-toggle dsq-expand" title="Expand thread" onclick="DISQUS.dtpl.actions.fire('comments.expand', 229548308); return false;"><span>Expand</span></a> </div> <div class="dsq-comment-message" id="dsq-comment-message-229548308"> <div class="dsq-comment-text" id="dsq-comment-text-229548308"> Sorry about the HTML paste.<br><br>----------------------------------------<br><br>The
+ fn_cond function causes segmentation fault when pred is nil and not
+#T.An if check on the car(list) will do the trick.object *fn_cond(object
+ *args, object *env) { while (args != NULL &amp;&amp; args-&gt;type ==
+CONS) { object *list = car(args); object *pred = nil; if (car(list)
+!= nil) pred = eval(car(list), env); object *ret = car(cdr(list));
+ if(pred != nil) return eval(ret,env); args = cdr(args); } return
+nil;}<br> </div> </div> <!-- edit box dynamically inserted here --> <div id="dsq-append-edit-229548308"></div> <div class="dsq-comment-footer"> <ul class="dsq-comment-actions"> <li id="dsq-like-229548308"> <span class="dsq-like-thumb dsq-font">A</span> <a href="#" onclick="DISQUS.dtpl.actions.fire('comments.like', this,229548308); return false">Like</a> </li> <li> <a href="#" class="dsq-comment-reply" onclick="DISQUS.dtpl.actions.fire('comments.reply',229548308, this); return false">Reply</a> </li> </ul> <ul class="dsq-comment-meta"> <li> <a href="#comment-229548308" onclick="DISQUS.dtpl.actions.fire('comments.permalink', 229548308);" title="Link to comment by Alen Ribic"> 5 months ago </a></li> <li> <a onclick="DISQUS.dtpl.actions.fire('comments.showParent', 229547088); return false" href="#comment-229547088" title="Jump to comment"> in reply to Alen Ribic </a> </li> <li style="display:none"> <a href="#" id="dsq-comment-like-count-229548308" class="dsq-comment-like-count" onclick="return DISQUS.dtpl.actions.fire('comments.showUserVotes', 229548308); return false">0 Like </a> </li> <li class="dsq-comment-flag" style="visibility: hidden"> <a href="#" class="dsq-comment-flag dsq-font" onclick="return DISQUS.dtpl.actions.fire('comments.report', 229548308, false);">F</a> </li> </ul> </div> <!-- reply box dynamically inserted here --> <div id="dsq-append-reply-229548308"></div> </div> </li> <!-- new replies dynamically inserted here --> <li id="dsq-append-post-229548308"></li> <li id="dsq-comment-230236740" data-dsq-comment-id="230236740" class="dsq-comment dsq-clearfix dsq-moderator dsq-founder" style="margin-left:92px;"> <div class="dsq-avatar dsq-tt" title="Expand nakkaya's profile"> <a href="http://disqus.com/nakkaya/" onclick="DISQUS.dtpl.actions.fire('profile.show', 230236740, null); return false"> <img src="A%20micro-manual%20for%20LISP%20Implemented%20in%20C%20%28by%20Nurullah%20Akkaya%29_files/noavatar32.png" class="dsq-deferred-avatar" data-src="http://mediacdn.disqus.com/uploads/users/85/3452/avatar32.jpg?1322006803" alt=""> </a> </div> <div id="dsq-comment-body-230236740" class="dsq-comment-body"> <div class="dsq-comment-header"> <span class="dsq-commenter-name">nakkaya</span> <span class="dsq-collapsed-count"> 1 comment collapsed </span> <a href="#" class="dsq-collapse-toggle dsq-collapse" title="Collapse thread" onclick="DISQUS.dtpl.actions.fire('comments.collapse', 230236740); return false;"><span>Collapse</span></a> <a href="#" class="dsq-collapse-toggle dsq-expand" title="Expand thread" onclick="DISQUS.dtpl.actions.fire('comments.expand', 230236740); return false;"><span>Expand</span></a> </div> <div class="dsq-comment-message" id="dsq-comment-message-230236740"> <div class="dsq-comment-text" id="dsq-comment-text-230236740"> Hi Alen,<br><br>Sorry for the late reply, I was out of town. Applied your changes. </div> </div> <!-- edit box dynamically inserted here --> <div id="dsq-append-edit-230236740"></div> <div class="dsq-comment-footer"> <ul class="dsq-comment-actions"> <li id="dsq-like-230236740"> <span class="dsq-like-thumb dsq-font">A</span> <a href="#" onclick="DISQUS.dtpl.actions.fire('comments.like', this,230236740); return false">Like</a> </li> <li> <a href="#" class="dsq-comment-reply" onclick="DISQUS.dtpl.actions.fire('comments.reply',230236740, this); return false">Reply</a> </li> </ul> <ul class="dsq-comment-meta"> <li> <a href="#comment-230236740" onclick="DISQUS.dtpl.actions.fire('comments.permalink', 230236740);" title="Link to comment by nakkaya"> 5 months ago </a></li> <li> <a onclick="DISQUS.dtpl.actions.fire('comments.showParent', 229548308); return false" href="#comment-229548308" title="Jump to comment"> in reply to Alen Ribic </a> </li> <li style="display:none"> <a href="#" id="dsq-comment-like-count-230236740" class="dsq-comment-like-count" onclick="return DISQUS.dtpl.actions.fire('comments.showUserVotes', 230236740); return false">0 Like </a> </li> <li class="dsq-comment-flag" style="visibility: hidden"> <a href="#" class="dsq-comment-flag dsq-font" onclick="return DISQUS.dtpl.actions.fire('comments.report', 230236740, false);">F</a> </li> </ul> </div> <!-- reply box dynamically inserted here --> <div id="dsq-append-reply-230236740"></div> </div> </li> <!-- new replies dynamically inserted here --> <li id="dsq-append-post-230236740"></li> </ul> <div id="dsq-pagination"> <ul id="dsq-footer" class="dsq-clearfix"> <div id="dsq-subscribe"> <li> <a href="#" class="dsq-subscribe-email" onclick="return DISQUS.dtpl.actions.fire('thread.subscribe');"> <span class="dsq-font">M</span> <em>Subscribe by email</em> </a> </li> <li> <a href="http://nakkaya.disqus.com/a_micro_manual_for_lisp_implemented_in_c/latest.rss" class="dsq-subscribe-rss"> <span class="dsq-font">S</span> <em>RSS</em> </a> </li> </div> </ul> <a class="dsq-more-button" href="#" onclick="DISQUS.dtpl.actions.fire('thread.paginate', 2, this); return false"> Load more comments </a> </div> <h3 class="dsq-h3-reactions">Reactions</h3> <ul id="dsq-reactions" class="dsq-reactions dsq-clearfix"> <li id="dsq-reaction-26163081"> <div class="dsq-reaction-avatar dsq-avatar dsq-tt" data-dsq-content-id="dsq-reaction-tooltip-26163081"> <a target="_blank" href="http://twitter.com/mizuy/status/22356175545"> <img src="A%20micro-manual%20for%20LISP%20Implemented%20in%20C%20%28by%20Nurullah%20Akkaya%29_files/elep_normal.png"> </a> </div> <div id="dsq-reaction-tooltip-26163081" class="dsq-reaction-tooltip" style="display:none"> <div class="dsq-reaction-tooltip-container"> <div class="dsq-reaction-body"><a href="http://github.com/mizuy/microlisp">http://bit.ly/dBAGua</a> 元ネタ-&gt; <a href="http://nakkaya.com/2010/08/24/a-micro-manual-for-lisp-implemented-in-c/">http://bit.ly/d2bPbh</a></div> <div class="dsq-reaction-date">1 year ago</div> <div class="dsq-reaction-user">@mizuy</div> </div> </div> </li> <li id="dsq-reaction-26163083"> <div class="dsq-reaction-avatar dsq-avatar dsq-tt" data-dsq-content-id="dsq-reaction-tooltip-26163083"> <a target="_blank" href="http://twitter.com/joshva/status/22284068231"> <img src="A%20micro-manual%20for%20LISP%20Implemented%20in%20C%20%28by%20Nurullah%20Akkaya%29_files/Joshva_twitter_profile_normal.gif"> </a> </div> <div id="dsq-reaction-tooltip-26163083" class="dsq-reaction-tooltip" style="display:none"> <div class="dsq-reaction-tooltip-container"> <div class="dsq-reaction-body">A micro-manual for LISP Implemented in C <a href="http://nakkaya.com/2010/08/24/a-micro-manual-for-lisp-implemented-in-c/">http://bit.ly/ak4jhW</a></div> <div class="dsq-reaction-date">1 year ago</div> <div class="dsq-reaction-user">@joshva</div> </div> </div> </li> <li id="dsq-reaction-26163084"> <div class="dsq-reaction-avatar dsq-avatar dsq-tt" data-dsq-content-id="dsq-reaction-tooltip-26163084"> <a target="_blank" href="http://twitter.com/deliciouspb/status/22263116214"> <img src="A%20micro-manual%20for%20LISP%20Implemented%20in%20C%20%28by%20Nurullah%20Akkaya%29_files/delicious_logo_normal.png"> </a> </div> <div id="dsq-reaction-tooltip-26163084" class="dsq-reaction-tooltip" style="display:none"> <div class="dsq-reaction-tooltip-container"> <div class="dsq-reaction-body">A micro-manual for LISP Implemented in C <a href="http://nakkaya.com/2010/08/24/a-micro-manual-for-lisp-implemented-in-c/">http://bit.ly/biPaxe</a></div> <div class="dsq-reaction-date">1 year ago</div> <div class="dsq-reaction-user">@deliciouspb</div> </div> </div> </li> <li id="dsq-reaction-26163077"> <div class="dsq-reaction-avatar dsq-avatar dsq-tt" data-dsq-content-id="dsq-reaction-tooltip-26163077"> <a target="_blank" href="http://twitter.com/delicious_n_hot/status/22254860137"> <img src="A%20micro-manual%20for%20LISP%20Implemented%20in%20C%20%28by%20Nurullah%20Akkaya%29_files/default_profile_2_normal.png"> </a> </div> <div id="dsq-reaction-tooltip-26163077" class="dsq-reaction-tooltip" style="display:none"> <div class="dsq-reaction-tooltip-container"> <div class="dsq-reaction-body">A micro-manual for LISP Implemented in C: <a href="http://nakkaya.com/2010/08/24/a-micro-manual-for-lisp-implemented-in-c/?utm_source=delicious_n_hot&amp;utm_medium=twitter">http://bit.ly/bOHOMD</a> #delicious #popular</div> <div class="dsq-reaction-date">1 year ago</div> <div class="dsq-reaction-user">@delicious_n_hot</div> </div> </div> </li> <li id="dsq-reaction-26163086"> <div class="dsq-reaction-avatar dsq-avatar dsq-tt" data-dsq-content-id="dsq-reaction-tooltip-26163086"> <a target="_blank" href="http://twitter.com/KarenKinnaman/status/22254859977"> <img src="A%20micro-manual%20for%20LISP%20Implemented%20in%20C%20%28by%20Nurullah%20Akkaya%29_files/Karendirmatch_normal.JPG"> </a> </div> <div id="dsq-reaction-tooltip-26163086" class="dsq-reaction-tooltip" style="display:none"> <div class="dsq-reaction-tooltip-container"> <div class="dsq-reaction-body">via Del.icio.us : A micro-manual for LISP Implemented in C: <a href="http://nakkaya.com/2010/08/24/a-micro-manual-for-lisp-implemented-in-c/?utm_source=twitterfeed&amp;utm_medium=twitter">http://bit.ly/a6Jsmq</a> #social #networking</div> <div class="dsq-reaction-date">1 year ago</div> <div class="dsq-reaction-user">@KarenKinnaman</div> </div> </div> </li> <li id="dsq-reaction-26163079"> <div class="dsq-reaction-avatar dsq-avatar dsq-tt" data-dsq-content-id="dsq-reaction-tooltip-26163079"> <a target="_blank" href="http://twitter.com/john_ababa/status/22254627965"> <img src="A%20micro-manual%20for%20LISP%20Implemented%20in%20C%20%28by%20Nurullah%20Akkaya%29_files/zikannai_normal.png"> </a> </div> <div id="dsq-reaction-tooltip-26163079" class="dsq-reaction-tooltip" style="display:none"> <div class="dsq-reaction-tooltip-container"> <div class="dsq-reaction-body">RT @illness072: 純LispってCだと376行で書けるらしい。<a href="http://nakkaya.com/2010/08/24/a-micro-manual-for-lisp-implemented-in-c/">http://nakkaya.com/2010/08/24/a-micro-manual-for-lisp-implemented-in-c/</a>・・・なの</div> <div class="dsq-reaction-date">1 year ago</div> <div class="dsq-reaction-user">@john_ababa</div> </div> </div> </li> <li id="dsq-reaction-26163080"> <div class="dsq-reaction-avatar dsq-avatar dsq-tt" data-dsq-content-id="dsq-reaction-tooltip-26163080"> <a target="_blank" href="http://twitter.com/illness072/status/22253861731"> <img src="A%20micro-manual%20for%20LISP%20Implemented%20in%20C%20%28by%20Nurullah%20Akkaya%29_files/icon2_normal.jpg"> </a> </div> <div id="dsq-reaction-tooltip-26163080" class="dsq-reaction-tooltip" style="display:none"> <div class="dsq-reaction-tooltip-container"> <div class="dsq-reaction-body">純LispってCだと376行で書けるらしい。<a href="http://nakkaya.com/2010/08/24/a-micro-manual-for-lisp-implemented-in-c/">http://nakkaya.com/2010/08/24/a-micro-manual-for-lisp-implemented-in-c/</a>・・・なの</div> <div class="dsq-reaction-date">1 year ago</div> <div class="dsq-reaction-user">@illness072</div> </div> </div> </li> <li id="dsq-reaction-26163082"> <div class="dsq-reaction-avatar dsq-avatar dsq-tt" data-dsq-content-id="dsq-reaction-tooltip-26163082"> <a target="_blank" href="http://twitter.com/yamanetoshi/status/22220284286"> <img src="A%20micro-manual%20for%20LISP%20Implemented%20in%20C%20%28by%20Nurullah%20Akkaya%29_files/glider_normal.png"> </a> </div> <div id="dsq-reaction-tooltip-26163082" class="dsq-reaction-tooltip" style="display:none"> <div class="dsq-reaction-tooltip-container"> <div class="dsq-reaction-body">A micro-manual for LISP Implemented in C: A micro-manual for LISP Implemented in CRecently I had to go through som... <a href="http://nakkaya.com/2010/08/24/a-micro-manual-for-lisp-implemented-in-c/?utm_source=twitterfeed&amp;utm_medium=twitter">http://bit.ly/a6Jsmq</a></div> <div class="dsq-reaction-date">1 year ago</div> <div class="dsq-reaction-user">@yamanetoshi</div> </div> </div> </li> <li id="dsq-reaction-26163078"> <div class="dsq-reaction-avatar dsq-avatar dsq-tt" data-dsq-content-id="dsq-reaction-tooltip-26163078"> <a target="_blank" href="http://twitter.com/bagutweet/status/22153565196"> <img src="A%20micro-manual%20for%20LISP%20Implemented%20in%20C%20%28by%20Nurullah%20Akkaya%29_files/baguface_normal.png"> </a> </div> <div id="dsq-reaction-tooltip-26163078" class="dsq-reaction-tooltip" style="display:none"> <div class="dsq-reaction-tooltip-container"> <div class="dsq-reaction-body">Tiny lisp implemented in C. Educational. <a href="http://nakkaya.com/2010/08/24/a-micro-manual-for-lisp-implemented-in-c/">http://tinyurl.com/37y3sdf</a></div> <div class="dsq-reaction-date">1 year ago</div> <div class="dsq-reaction-user">@bagutweet</div> </div> </div> </li> <li id="dsq-reaction-25874738"> <div class="dsq-reaction-avatar dsq-avatar dsq-tt" data-dsq-content-id="dsq-reaction-tooltip-25874738"> <a target="_blank" href="http://twitter.com/thefifthcircuit/status/22103482740"> <img src="A%20micro-manual%20for%20LISP%20Implemented%20in%20C%20%28by%20Nurullah%20Akkaya%29_files/tfc_normal.png"> </a> </div> <div id="dsq-reaction-tooltip-25874738" class="dsq-reaction-tooltip" style="display:none"> <div class="dsq-reaction-tooltip-container"> <div class="dsq-reaction-body">A remarkably small Lisp implementation in C. Very educational. <a href="http://nakkaya.com/2010/08/24/a-micro-manual-for-lisp-implemented-in-c/">http://nakkaya.com/2010/08/24/a-micro-manual-for-lisp-implemented-in-c/</a></div> <div class="dsq-reaction-date">1 year ago</div> <div class="dsq-reaction-user">@thefifthcircuit</div> </div> </div> </li> </ul> <div class="dsq-trackback-url"> Trackback URL <input onclick="this.select()" readonly="true" value="http://disqus.com/forums/nakkaya/a_micro_manual_for_lisp_implemented_in_c/trackback/"> </div> </div><div class=" fb_reset" id="fb-root"><div style="position: absolute; top: -10000px; height: 0pt; width: 0pt;"><div><iframe src="A%20micro-manual%20for%20LISP%20Implemented%20in%20C%20%28by%20Nurullah%20Akkaya%29_files/oauth.html" class="FB_UI_Hidden" style="border: medium none; overflow: hidden; height: 240px; width: 575px;" name="f3803333a2e5be" id="fc83745f71021e" scrolling="no"></iframe></div></div></div><div> </div></div><script type="text/javascript" src="A%20micro-manual%20for%20LISP%20Implemented%20in%20C%20%28by%20Nurullah%20Akkaya%29_files/embed.js"></script><noscript><a href="http://disqus.com/forums/nakkaya/?url=ref">View the discussion thread.</a></noscript><a href="http://disqus.com/" class="dsq-brlink">blog comments powered by <span class="logo-disqus">Disqus</span></a></div></div><div id="footer"><a href="http://nakkaya.com/rss-feed"> RSS Feed</a><p>© 2011<a href="http://nakkaya.com/"> Nurullah Akkaya</a></p></div></div><script type="text/javascript">
+//<![CDATA[
+(function() {
+ var links = document.getElementsByTagName('a');
+ var query = '?';
+ for(var i = 0; i < links.length; i++) {
+ if(links[i].href.indexOf('#disqus_thread') >= 0) {
+ query += 'url' + i + '=' + encodeURIComponent(links[i].href) + '&';
+ }
+ }
+ document.write('<script charset="utf-8" type="text/javascript" src="http://disqus.com/forums/nakkaya/get_num_replies.js' + query + '"></' + 'script>');
+ })();
+//]]>
+</script><script charset="utf-8" type="text/javascript" src="A%20micro-manual%20for%20LISP%20Implemented%20in%20C%20%28by%20Nurullah%20Akkaya%29_files/get_num_replies.js"></script><iframe src="A%20micro-manual%20for%20LISP%20Implemented%20in%20C%20%28by%20Nurullah%20Akkaya%29_files/def.html" style="position: absolute; top: -2000px; left: 0px;" id="easyXDM_DISQUS_net_default7967_provider" name="easyXDM_DISQUS_net_default7967_provider" frameborder="0"></iframe></body></html>
BIN  ...al for LISP Implemented in C (by Nurullah Akkaya)_files/Joshva_twitter_profile_normal.gif
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  ...icro-manual for LISP Implemented in C (by Nurullah Akkaya)_files/Karendirmatch_normal.JPG
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
30 .../microlisp/A micro-manual for LISP Implemented in C (by Nurullah Akkaya)_files/MathJax.js
@@ -0,0 +1,30 @@
+/*************************************************************
+ *
+ * MathJax.js
+ *
+ * The main code for the MathJax math-typesetting library. See
+ * http://www.mathjax.org/ for details.
+ *
+ * ---------------------------------------------------------------------
+ *
+ * Copyright (c) 2009-2010 Design Science, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+if (!window.MathJax) {window.MathJax = {}}
+
+MathJax.isPacked = true;
+
+if(document.getElementById&&document.childNodes&&document.createElement){if(!window.MathJax){window.MathJax={}}if(!MathJax.Hub){MathJax.version="1.1a";MathJax.fileversion="1.1.7";(function(d){var b=window[d];if(!b){b=window[d]={}}var f=[];var c=function(g){var h=g.constructor;if(!h){h=new Function("")}for(var i in g){if(i!=="constructor"&&g.hasOwnProperty(i)){h[i]=g[i]}}return h};var a=function(){return new Function("return arguments.callee.Init.call(this,arguments)")};var e=a();e.prototype={bug_test:1};if(!e.prototype.bug_test){a=function(){return function(){return arguments.callee.Init.call(this,arguments)}}}b.Object=c({constructor:a(),Subclass:function(g,i){var h=a();h.SUPER=this;h.Init=this.Init;h.Subclass=this.Subclass;h.Augment=this.Augment;h.protoFunction=this.protoFunction;h.can=this.can;h.has=this.has;h.isa=this.isa;h.prototype=new this(f);h.prototype.constructor=h;h.Augment(g,i);return h},Init:function(g){var h=this;if(g.length===1&&g[0]===f){return h}if(!(h instanceof g.callee)){h=new g.callee(f)}return h.Init.apply(h,g)||h},Augment:function(g,h){var i;if(g!=null){for(i in g){if(g.hasOwnProperty(i)){this.protoFunction(i,g[i])}}if(g.toString!==this.prototype.toString&&g.toString!=={}.toString){this.protoFunction("toString",g.toString)}}if(h!=null){for(i in h){if(h.hasOwnProperty(i)){this[i]=h[i]}}}return this},protoFunction:function(h,g){this.prototype[h]=g;if(typeof g==="function"){g.SUPER=this.SUPER.prototype}},prototype:{Init:function(){},SUPER:function(g){return g.callee.SUPER},can:function(g){return typeof(this[g])==="function"},has:function(g){return typeof(this[g])!=="undefined"},isa:function(g){return(g instanceof Object)&&(this instanceof g)}},can:function(g){return this.prototype.can.call(this,g)},has:function(g){return this.prototype.has.call(this,g)},isa:function(h){var g=this;while(g){if(g===h){return true}else{g=g.SUPER}}return false},SimpleSUPER:c({constructor:function(g){return this.SimpleSUPER.define(g)},define:function(g){var i={};if(g!=null){for(var h in g){if(g.hasOwnProperty(h)){this.protoFunction(h,g[h])}}if(g.toString!==this.prototype.toString&&g.toString!=={}.toString){this.protoFunction("toString",g.toString)}}return i},wrap:function(i,h){if(typeof(h)==="function"&&h.toString().match(/\.\s*SUPER\s*\(/)){var g=new Function(this.wrapper);g.label=i;g.original=h;h=g;g.toString=this.stringify}return h},wrapper:function(){var h=arguments.callee;this.SUPER=h.SUPER[h.label];try{var g=h.original.apply(this,arguments)}catch(i){delete this.SUPER;throw i}delete this.SUPER;return g}.toString().replace(/^\s*function \(\)\s*\{\s*/i,"").replace(/\s*\}\s*$/i,""),toString:function(){return this.original.toString.apply(this.original,arguments)}})})})("MathJax");(function(BASENAME){var BASE=window[BASENAME];if(!BASE){BASE=window[BASENAME]={}}var CALLBACK=function(data){var cb=new Function("return arguments.callee.execute.apply(arguments.callee,arguments)");for(var id in CALLBACK.prototype){if(CALLBACK.prototype.hasOwnProperty(id)){if(typeof(data[id])!=="undefined"){cb[id]=data[id]}else{cb[id]=CALLBACK.prototype[id]}}}cb.toString=CALLBACK.prototype.toString;return cb};CALLBACK.prototype={isCallback:true,hook:function(){},data:[],object:window,execute:function(){if(!this.called||this.autoReset){this.called=!this.autoReset;return this.hook.apply(this.object,this.data.concat([].slice.call(arguments,0)))}},reset:function(){delete this.called},toString:function(){return this.hook.toString.apply(this.hook,arguments)}};var ISCALLBACK=function(f){return(typeof(f)==="function"&&f.isCallback)};var EVAL=function(code){return eval.call(window,code)};EVAL("var __TeSt_VaR__ = 1");if(window.__TeSt_VaR__){try{delete window.__TeSt_VaR__}catch(error){window.__TeSt_VaR__=null}}else{if(window.execScript){EVAL=function(code){BASE.__code=code;code="try {"+BASENAME+".__result = eval("+BASENAME+".__code)} catch(err) {"+BASENAME+".__result = err}";window.execScript(code);var result=BASE.__result;delete BASE.__result;delete BASE.__code;if(result instanceof Error){throw result}return result}}else{EVAL=function(code){BASE.__code=code;code="try {"+BASENAME+".__result = eval("+BASENAME+".__code)} catch(err) {"+BASENAME+".__result = err}";var head=(document.getElementsByTagName("head"))[0];if(!head){head=document.body}var script=document.createElement("script");script.appendChild(document.createTextNode(code));head.appendChild(script);head.removeChild(script);var result=BASE.__result;delete BASE.__result;delete BASE.__code;if(result instanceof Error){throw result}return result}}}var USING=function(args,i){if(arguments.length>1){if(arguments.length===2&&!(typeof arguments[0]==="function")&&arguments[0] instanceof Object&&typeof arguments[1]==="number"){args=[].slice.call(args,i)}else{args=[].slice.call(arguments,0)}}if(args instanceof Array&&args.length===1){args=args[0]}if(typeof args==="function"){if(args.execute===CALLBACK.prototype.execute){return args}return CALLBACK({hook:args})}else{if(args instanceof Array){if(typeof(args[0])==="string"&&args[1] instanceof Object&&typeof args[1][args[0]]==="function"){return CALLBACK({hook:args[1][args[0]],object:args[1],data:args.slice(2)})}else{if(typeof args[0]==="function"){return CALLBACK({hook:args[0],data:args.slice(1)})}else{if(typeof args[1]==="function"){return CALLBACK({hook:args[1],object:args[0],data:args.slice(2)})}}}}else{if(typeof(args)==="string"){return CALLBACK({hook:EVAL,data:[args]})}else{if(args instanceof Object){return CALLBACK(args)}else{if(typeof(args)==="undefined"){return CALLBACK({})}}}}}throw Error("Can't make callback from given data")};var DELAY=function(time,callback){callback=USING(callback);callback.timeout=setTimeout(callback,time);return callback};var WAITFOR=function(callback,signal){callback=USING(callback);if(!callback.called){WAITSIGNAL(callback,signal);signal.pending++}};var WAITEXECUTE=function(){var signals=this.signal;delete this.signal;this.execute=this.oldExecute;delete this.oldExecute;var result=this.execute.apply(this,arguments);if(ISCALLBACK(result)&&!result.called){WAITSIGNAL(result,signals)}else{for(var i=0,m=signals.length;i<m;i++){signals[i].pending--;if(signals[i].pending<=0){signals[i].call()}}}};var WAITSIGNAL=function(callback,signals){if(!(signals instanceof Array)){signals=[signals]}if(!callback.signal){callback.oldExecute=callback.execute;callback.execute=WAITEXECUTE;callback.signal=signals}else{if(signals.length===1){callback.signal.push(signals[0])}else{callback.signal=callback.signal.concat(signals)}}};var AFTER=function(callback){callback=USING(callback);callback.pending=0;for(var i=1,m=arguments.length;i<m;i++){if(arguments[i]){WAITFOR(arguments[i],callback)}}if(callback.pending===0){var result=callback();if(ISCALLBACK(result)){callback=result}}return callback};var HOOKS=function(hooks,data,reset){if(!hooks){return null}if(!(hooks instanceof Array)){hooks=[hooks]}if(!(data instanceof Array)){data=(data==null?[]:[data])}var callbacks=[{}];for(var i=0,m=hooks.length;i<m;i++){if(reset){hooks[i].reset()}var result=hooks[i].apply(window,data);if(ISCALLBACK(result)&&!result.called){callbacks.push(result)}}if(callbacks.length===1){return null}if(callbacks.length===2){return callbacks[1]}return AFTER.apply({},callbacks)};var QUEUE=BASE.Object.Subclass({Init:function(){this.pending=0;this.running=0;this.queue=[];this.Push.apply(this,arguments)},Push:function(){var callback;for(var i=0,m=arguments.length;i<m;i++){callback=USING(arguments[i]);if(callback===arguments[i]&&!callback.called){callback=USING(["wait",this,callback])}this.queue.push(callback)}if(!this.running&&!this.pending){this.Process()}return callback},Process:function(queue){while(!this.running&&!this.pending&&this.queue.length){var callback=this.queue[0];queue=this.queue.slice(1);this.queue=[];this.Suspend();var result=callback();this.Resume();if(queue.length){this.queue=queue.concat(this.queue)}if(ISCALLBACK(result)&&!result.called){WAITFOR(result,this)}}},Suspend:function(){this.running++},Resume:function(){if(this.running){this.running--}},call:function(){this.Process.apply(this,arguments)},wait:function(callback){return callback}});var SIGNAL=QUEUE.Subclass({Init:function(name){QUEUE.prototype.Init.call(this);this.name=name;this.posted=[];this.listeners=[]},Post:function(message,callback,forget){callback=USING(callback);if(this.posting||this.pending){this.Push(["Post",this,message,callback,forget])}else{this.callback=callback;callback.reset();if(!forget){this.posted.push(message)}this.Suspend();this.posting=1;for(var i=0,m=this.listeners.length;i<m;i++){this.listeners[i].reset();var result=(this.listeners[i])(message);if(ISCALLBACK(result)&&!result.called){WAITFOR(result,this)}}this.Resume();delete this.posting;if(!this.pending){this.call()}}return callback},Clear:function(callback){callback=USING(callback);if(this.posting||this.pending){callback=this.Push(["Clear",this,callback])}else{this.posted=[];callback()}return callback},call:function(){this.callback(this);this.Process()},Interest:function(callback,ignorePast){callback=USING(callback);this.listeners[this.listeners.length]=callback;if(!ignorePast){for(var i=0,m=this.posted.length;i<m;i++){callback.reset();var result=callback(this.posted[i]);if(ISCALLBACK(result)&&i===this.posted.length-1){WAITFOR(result,this)}}}return callback},NoInterest:function(callback){for(var i=0,m=this.listeners.length;i<m;i++){if(this.listeners[i]===callback){this.listeners.splice(i,1);return}}},MessageHook:function(msg,callback){callback=USING(callback);if(!this.hooks){this.hooks={};this.Interest(["ExecuteHooks",this])}if(!this.hooks[msg]){this.hooks[msg]=[]}this.hooks[msg].push(callback);for(var i=0,m=this.posted.length;i<m;i++){if(this.posted[i]==msg){callback.reset();callback(this.posted[i])}}return callback},ExecuteHooks:function(msg,more){var type=((msg instanceof Array)?msg[0]:msg);return HOOKS(this.hooks[type],[msg],true)}},{signals:{},find:function(name){if(!SIGNAL.signals[name]){SIGNAL.signals[name]=new SIGNAL(name)}return SIGNAL.signals[name]}});BASE.Callback=BASE.CallBack=USING;BASE.Callback.Delay=DELAY;BASE.Callback.After=AFTER;BASE.Callback.Queue=QUEUE;BASE.Callback.Signal=SIGNAL.find;BASE.Callback.ExecuteHooks=HOOKS})("MathJax");(function(d){var a=window[d];if(!a){a=window[d]={}}var c=(navigator.vendor==="Apple Computer, Inc."&&typeof navigator.vendorSub==="undefined");var f=0;var g=function(h){if(document.styleSheets&&document.styleSheets.length>f){f=document.styleSheets.length}if(!h){h=(document.getElementsByTagName("head"))[0];if(!h){h=document.body}}return h};var e=[];var b=function(){for(var j=0,h=e.length;j<h;j++){a.Ajax.head.removeChild(e[j])}e=[]};a.Ajax={loaded:{},loading:{},loadHooks:{},timeout:15*1000,styleDelay:1,config:{root:""},STATUS:{OK:1,ERROR:-1},rootPattern:new RegExp("^\\["+d+"\\]"),fileURL:function(h){return h.replace(this.rootPattern,this.config.root)},Require:function(j,m){m=a.Callback(m);var k;if(j instanceof Object){for(var h in j){}k=h.toUpperCase();j=j[h]}else{k=j.split(/\./).pop().toUpperCase()}j=this.fileURL(j);if(this.loaded[j]){m(this.loaded[j])}else{var l={};l[k]=j;this.Load(l,m)}return m},Load:function(j,l){l=a.Callback(l);var k;if(j instanceof Object){for(var h in j){}k=h.toUpperCase();j=j[h]}else{k=j.split(/\./).pop().toUpperCase()}j=this.fileURL(j);if(this.loading[j]){if(!this.loadHooks[j]){this.loadHooks[j]=[]}this.loadHooks[j].push(l)}else{this.head=g(this.head);if(this.loader[k]){this.loader[k].call(this,j,l)}else{throw Error("Can't load files of type "+k)}}return l},LoadHook:function(j,k){k=a.Callback(k);if(j instanceof Object){for(var h in j){j=j[h]}}j=this.fileURL(j);if(this.loaded[j]){k(this.loaded[j])}else{if(!this.loadHooks[j]){this.loadHooks[j]=[]}this.loadHooks[j].push(k)}return k},Preloading:function(){for(var k=0,h=arguments.length;k<h;k++){var j=this.fileURL(arguments[k]);if(!this.loading[j]){this.loading[j]={preloaded:true}}}},loader:{JS:function(i,k){var h=document.createElement("script");var j=a.Callback(["loadTimeout",this,i]);this.loading[i]={callback:k,message:a.Message.File(i),timeout:setTimeout(j,this.timeout),status:this.STATUS.OK,script:h};h.onerror=j;h.type="text/javascript";h.src=i;this.head.appendChild(h)},CSS:function(h,j){var i=document.createElement("link");i.rel="stylesheet";i.type="text/css";i.href=h;this.loading[h]={callback:j,message:a.Message.File(h),status:this.STATUS.OK};this.head.appendChild(i);this.timer.create.call(this,[this.timer.file,h],i)}},timer:{create:function(i,h){i=a.Callback(i);if(h.nodeName==="STYLE"&&h.styleSheet&&typeof(h.styleSheet.cssText)!=="undefined"){i(this.STATUS.OK)}else{if(window.chrome&&typeof(window.sessionStorage)!=="undefined"&&h.nodeName==="STYLE"){i(this.STATUS.OK)}else{if(c){this.timer.start(this,[this.timer.checkSafari2,f++,i],this.styleDelay)}else{this.timer.start(this,[this.timer.checkLength,h,i],this.styleDelay)}}}return i},start:function(i,h,j,k){h=a.Callback(h);h.execute=this.execute;h.time=this.time;h.STATUS=i.STATUS;h.timeout=k||i.timeout;h.delay=h.total=0;setTimeout(h,j)},time:function(h){this.total+=this.delay;this.delay=Math.floor(this.delay*1.05+5);if(this.total>=this.timeout){h(this.STATUS.ERROR);return 1}return 0},file:function(i,h){if(h<0){a.Ajax.loadTimeout(i)}else{a.Ajax.loadComplete(i)}},execute:function(){this.hook.call(this.object,this,this.data[0],this.data[1])},checkSafari2:function(h,i,j){if(h.time(j)){return}if(document.styleSheets.length>i&&document.styleSheets[i].cssRules&&document.styleSheets[i].cssRules.length){j(h.STATUS.OK)}else{setTimeout(h,h.delay)}},checkLength:function(h,k,m){if(h.time(m)){return}var l=0;var i=(k.sheet||k.styleSheet);try{if((i.cssRules||i.rules||[]).length>0){l=1}}catch(j){if(j.message.match(/protected variable|restricted URI/)){l=1}else{if(j.message.match(/Security error/)){l=1}}}if(l){setTimeout(a.Callback([m,h.STATUS.OK]),0)}else{setTimeout(h,h.delay)}}},loadComplete:function(h){h=this.fileURL(h);var i=this.loading[h];if(i&&!i.preloaded){a.Message.Clear(i.message);clearTimeout(i.timeout);if(i.script){if(e.length===0){setTimeout(b,0)}e.push(i.script)}this.loaded[h]=i.status;delete this.loading[h];if(!this.loadHooks[h]){this.loadHooks[h]=[]}this.loadHooks[h].push(i.callback)}else{this.loaded[h]=this.STATUS.OK;i={status:this.STATUS.OK}}a.Callback.ExecuteHooks(this.loadHooks[h],i.status)},loadTimeout:function(h){if(this.loading[h].timeout){clearTimeout(this.loading[h].timeout)}this.loading[h].status=this.STATUS.ERROR;this.loadError(h);this.loadComplete(h)},loadError:function(h){a.Message.Set("File failed to load: "+h,null,2000)},Styles:function(j,k){var h=this.StyleString(j);if(h===""){k=a.Callback(k);k()}else{var i=document.createElement("style");i.type="text/css";this.head=g(this.head);this.head.appendChild(i);if(i.styleSheet&&typeof(i.styleSheet.cssText)!=="undefined"){i.styleSheet.cssText=h}else{i.appendChild(document.createTextNode(h))}k=this.timer.create.call(this,k,i)}return k},StyleString:function(m){if(typeof(m)==="string"){return m}var j="",n,l;for(n in m){if(m.hasOwnProperty(n)){if(typeof m[n]==="string"){j+=n+" {"+m[n]+"}\n"}else{if(m[n] instanceof Array){for(var k=0;k<m[n].length;k++){l={};l[n]=m[n][k];j+=this.StyleString(l)}}else{if(n.substr(0,6)==="@media"){j+=n+" {"+this.StyleString(m[n])+"}\n"}else{if(m[n]!=null){l=[];for(var h in m[n]){if(m[n].hasOwnProperty(h)){if(m[n][h]!=null){l[l.length]=h+": "+m[n][h]}}}j+=n+" {"+l.join("; ")+"}\n"}}}}}}return j}}})("MathJax");MathJax.HTML={Element:function(c,e,d){var f=document.createElement(c);if(e){if(e.style){var b=e.style;e.style={};for(var g in b){if(b.hasOwnProperty(g)){e.style[g.replace(/-([a-z])/g,this.ucMatch)]=b[g]}}}MathJax.Hub.Insert(f,e)}if(d){for(var a=0;a<d.length;a++){if(d[a] instanceof Array){f.appendChild(this.Element(d[a][0],d[a][1],d[a][2]))}else{f.appendChild(document.createTextNode(d[a]))}}}return f},ucMatch:function(a,b){return b.toUpperCase()},addElement:function(b,a,d,c){return b.appendChild(this.Element(a,d,c))},TextNode:function(a){return document.createTextNode(a)},addText:function(a,b){return a.appendChild(this.TextNode(b))},setScript:function(a,b){if(this.setScriptBug){a.text=b}else{while(a.firstChild){a.removeChild(a.firstChild)}this.addText(a,b)}},Cookie:{prefix:"mjx",expires:365,Set:function(a,d){var c=[];if(d){for(var f in d){if(d.hasOwnProperty(f)){c.push(f+":"+d[f].toString().replace(/&/g,"&&"))}}}var b=this.prefix+"."+a+"="+escape(c.join("&;"));if(this.expires){var e=new Date();e.setDate(e.getDate()+this.expires);b+="; expires="+e.toGMTString()}document.cookie=b+"; path=/"},Get:function(c,h){if(!h){h={}}var g=new RegExp("(?:^|;\\s*)"+this.prefix+"\\."+c+"=([^;]*)(?:;|$)");var b=g.exec(document.cookie);if(b&&b[1]!==""){var e=unescape(b[1]).split("&;");for(var d=0,a=e.length;d<a;d++){b=e[d].match(/([^:]+):(.*)/);var f=b[2].replace(/&&/g,"&");if(f==="true"){f=true}else{if(f==="false"){f=false}else{if(f.match(/^-?(\d+(\.\d+)?|\.\d+)$/)){f=parseFloat(f)}}}h[b[1]]=f}}return h}}};MathJax.Message={ready:false,log:[{}],current:null,textNodeBug:(navigator.vendor==="Apple Computer, Inc."&&typeof navigator.vendorSub==="undefined")||(window.hasOwnProperty&&window.hasOwnProperty("konqueror")),styles:{"#MathJax_Message":{position:"fixed",left:"1px",bottom:"2px","background-color":"#E6E6E6",border:"1px solid #959595",margin:"0px",padding:"2px 8px","z-index":"102",color:"black","font-size":"80%",width:"auto","white-space":"nowrap"},"#MathJax_MSIE_Frame":{position:"absolute",top:0,left:0,width:"0px","z-index":101,border:"0px",margin:"0px",padding:"0px"}},browsers:{MSIE:function(a){MathJax.Hub.config.styles["#MathJax_Message"].position="absolute";MathJax.Message.quirks=(document.compatMode==="BackCompat")},Chrome:function(a){MathJax.Hub.config.styles["#MathJax_Message"].bottom="1.5em";MathJax.Hub.config.styles["#MathJax_Message"].left="1em"}},Init:function(a){if(a){this.ready=true}if(!document.body||!this.ready){return false}if(this.div&&this.div.parentNode==null){this.div=document.getElementById("MathJax_Message");if(this.div){this.text=this.div.firstChild}}if(!this.div){var b=document.body;if(MathJax.Hub.Browser.isMSIE){b=this.frame=this.addDiv(document.body);b.removeAttribute("id");b.style.position="absolute";b.style.border=b.style.margin=b.style.padding="0px";b.style.zIndex="101";b.style.height="0px";b=this.addDiv(b);b.id="MathJax_MSIE_Frame";window.attachEvent("onscroll",this.MoveFrame);window.attachEvent("onresize",this.MoveFrame);this.MoveFrame()}this.div=this.addDiv(b);this.div.style.display="none";this.text=this.div.appendChild(document.createTextNode(""))}return true},addDiv:function(a){var b=document.createElement("div");b.id="MathJax_Message";if(a.firstChild){a.insertBefore(b,a.firstChild)}else{a.appendChild(b)}return b},MoveFrame:function(){var a=(MathJax.Message.quirks?document.body:document.documentElement);var b=MathJax.Message.frame;b.style.left=a.scrollLeft+"px";b.style.top=a.scrollTop+"px";b.style.width=a.clientWidth+"px";b=b.firstChild;b.style.height=a.clientHeight+"px"},filterText:function(a,b){if(MathJax.Hub.config.messageStyle==="simple"){if(a.match(/^Loading /)){if(!this.loading){this.loading="Loading "}a=this.loading;this.loading+="."}else{if(a.match(/^Processing /)){if(!this.processing){this.processing="Processing "}a=this.processing;this.processing+="."}}}return a},Set:function(b,c,a){if(this.timer){clearTimeout(this.timer);delete this.timeout}if(c==null){c=this.log.length;this.log[c]={}}this.log[c].text=b;this.log[c].filteredText=b=this.filterText(b,c);if(typeof(this.log[c].next)==="undefined"){this.log[c].next=this.current;if(this.current!=null){this.log[this.current].prev=c}this.current=c}if(this.current===c&&MathJax.Hub.config.messageStyle!=="none"){if(this.Init()){if(this.textNodeBug){this.div.innerHTML=b}else{this.text.nodeValue=b}this.div.style.display="";if(this.status){window.status="";delete this.status}}else{window.status=b;this.status=true}}if(a){setTimeout(MathJax.Callback(["Clear",this,c]),a)}return c},Clear:function(b,a){if(this.log[b].prev!=null){this.log[this.log[b].prev].next=this.log[b].next}if(this.log[b].next!=null){this.log[this.log[b].next].prev=this.log[b].prev}if(this.current===b){this.current=this.log[b].next;if(this.text){if(this.div.parentNode==null){this.Init()}if(this.current==null){if(this.timer){clearTimeout(this.timer)}this.timer=setTimeout(MathJax.Callback(["Remove",this]),(a||600))}else{if(MathJax.Hub.config.messageStyle!=="none"){if(this.textNodeBug){this.div.innerHTML=this.log[this.current].filteredText}else{this.text.nodeValue=this.log[this.current].filteredText}}}if(this.status){window.status="";delete this.status}}else{if(this.status){window.status=(this.current==null?"":this.log[this.current].text)}}}delete this.log[b].next;delete this.log[b].prev;delete this.log[b].filteredText},Remove:function(){this.text.nodeValue="";this.div.style.display="none"},File:function(b){var a=MathJax.Ajax.config.root;if(b.substr(0,a.length)===a){b="[MathJax]"+b.substr(a.length)}return this.Set("Loading "+b)},Log:function(){var b=[];for(var c=1,a=this.log.length;c<a;c++){b[c]=this.log[c].text}return b.join("\n")}};MathJax.Hub={config:{root:"",config:[],styleSheets:[],styles:{},jax:[],extensions:[],preJax:null,postJax:null,displayAlign:"center",displayIndent:"0",preRemoveClass:"MathJax_Preview",showProcessingMessages:true,messageStyle:"normal",delayStartupUntil:"none",skipStartupTypeset:false,"v1.0-compatible":true,elements:[],preProcessors:[],inputJax:{},outputJax:{order:{}},menuSettings:{zoom:"None",CTRL:false,ALT:false,CMD:false,Shift:false,zscale:"200%",renderer:"",font:"Auto",context:"MathJax"},errorSettings:{message:["[Math Processing Error]"],style:{color:"#CC0000","font-style":"italic"}}},processUpdateTime:250,signal:MathJax.Callback.Signal("Hub"),Config:function(a){this.Insert(this.config,a);if(this.config.Augment){this.Augment(this.config.Augment)}},CombineConfig:function(c,f){var b=this.config,g,e;c=c.split(/\./);for(var d=0,a=c.length;d<a;d++){g=c[d];if(!b[g]){b[g]={}}e=b;b=b[g]}e[g]=b=this.Insert(f,b);return b},Register:{PreProcessor:function(a){MathJax.Hub.config.preProcessors.push(MathJax.Callback(a))},MessageHook:function(){return MathJax.Hub.signal.MessageHook.apply(MathJax.Hub.signal,arguments)},StartupHook:function(){return MathJax.Hub.Startup.signal.MessageHook.apply(MathJax.Hub.Startup.signal,arguments)},LoadHook:function(){return MathJax.Ajax.LoadHook.apply(MathJax.Ajax,arguments)}},getAllJax:function(e){var c=[],b=this.elementScripts(e);for(var d=0,a=b.length;d<a;d++){if(b[d].MathJax&&b[d].MathJax.elementJax){c.push(b[d].MathJax.elementJax)}}return c},getJaxByType:function(f,e){var c=[],b=this.elementScripts(e);for(var d=0,a=b.length;d<a;d++){if(b[d].MathJax&&b[d].MathJax.elementJax&&b[d].MathJax.elementJax.mimeType===f){c.push(b[d].MathJax.elementJax)}}return c},getJaxByInputType:function(f,e){var c=[],b=this.elementScripts(e);for(var d=0,a=b.length;d<a;d++){if(b[d].MathJax&&b[d].MathJax.elementJax&&b[d].type&&b[d].type.replace(/ *;(.|\s)*/,"")===f){c.push(b[d].MathJax.elementJax)}}return c},getJaxFor:function(a){if(typeof(a)==="string"){a=document.getElementById(a)}if(a&&a.MathJax){return a.MathJax.elementJax}return null},isJax:function(a){if(typeof(a)==="string"){a=document.getElementById(a)}if(a&&a.tagName!=null&&a.tagName.toLowerCase()==="script"){if(a.MathJax){return(a.MathJax.state===MathJax.ElementJax.STATE.PROCESSED?1:-1)}if(a.type&&this.config.inputJax[a.type.replace(/ *;(.|\s)*/,"")]){return -1}}return 0},Queue:function(){return this.queue.Push.apply(this.queue,arguments)},Typeset:function(e,f){if(!MathJax.isReady){return null}var c=this.elementCallback(e,f);var b=MathJax.Callback.Queue();for(var d=0,a=c.elements.length;d<a;d++){if(c.elements[d]){b.Push(["PreProcess",this,c.elements[d]],["Process",this,c.elements[d]])}}return b.Push(c.callback)},PreProcess:function(e,f){var c=this.elementCallback(e,f);var b=MathJax.Callback.Queue();for(var d=0,a=c.elements.length;d<a;d++){if(c.elements[d]){b.Push(["Post",this.signal,["Begin PreProcess",c.elements[d]]],["ExecuteHooks",MathJax.Callback,(arguments.callee.disabled?[]:this.config.preProcessors),c.elements[d],true],["Post",this.signal,["End PreProcess",c.elements[d]]])}}return b.Push(c.callback)},Process:function(a,b){return this.takeAction("Process",a,b)},Update:function(a,b){return this.takeAction("Update",a,b)},Reprocess:function(a,b){return this.takeAction("Reprocess",a,b)},takeAction:function(g,f,h){var d=this.elementCallback(f,h);var c=MathJax.Callback.Queue(["Clear",this.signal]);for(var e=0,b=d.elements.length;e<b;e++){if(d.elements[e]){var a=[];c.Push(["Post",this.signal,["Begin "+g,d.elements[e]]],["Post",this.signal,["Begin Math",d.elements[e]]],["prepareScripts",this,g,d.elements[e],a],["processScripts",this,a],["Post",this.signal,["End Math",d.elements[e]]],["Post",this.signal,["End "+g,d.elements[e]]])}}return c.Push(d.callback)},scriptAction:{Process:function(a){},Update:function(b){var a=b.MathJax.elementJax;if(a&&a.originalText===(b.text==""?b.innerHTML:b.text)){b.MathJax.state=a.STATE.PROCESSED}else{a.outputJax.Remove(a);b.MathJax.state=a.STATE.UPDATE}},Reprocess:function(b){var a=b.MathJax.elementJax;if(a){a.outputJax.Remove(a);b.MathJax.state=a.STATE.UPDATE}}},prepareScripts:function(h,e,f){if(arguments.callee.disabled){return}var b=this.elementScripts(e);var g=MathJax.ElementJax.STATE;for(var d=0,a=b.length;d<a;d++){var c=b[d];if(c.type&&this.config.inputJax[c.type.replace(/ *;(.|\n)*/,"")]){if(c.MathJax&&c.MathJax.state!==g.PENDING){this.scriptAction[h](c)}if(!c.MathJax){c.MathJax={state:g.PENDING}}if(c.MathJax.state!==g.PROCESSED){f.push(c)}}}},checkScriptSiblings:function(a){if(a.MathJax&&a.MathJax.checked){return}var b=this.config;var g=a.previousSibling;if(g&&g.nodeName=="#text"){var d,f;var c=a.nextSibling;if(c&&c.nodeName!="#text"){c=null}if(b.preJax){if(typeof(b.preJax)==="string"){b.preJax=new RegExp(b.preJax+"$")}d=g.nodeValue.match(b.preJax)}if(b.postJax&&c){if(typeof(b.postJax)==="string"){b.postJax=new RegExp("^"+b.postJax)}f=c.nodeValue.match(b.postJax)}if(d&&(!b.postJax||f)){g.nodeValue=g.nodeValue.replace(b.preJax,(d.length>1?d[1]:""));g=null}if(f&&(!b.preJax||d)){c.nodeValue=c.nodeValue.replace(b.postJax,(f.length>1?f[1]:""))}if(g&&!g.nodeValue.match(/\S/)){g=g.previousSibling}}if(b.preRemoveClass&&g&&g.className==b.preRemoveClass){try{g.innerHTML=""}catch(e){}g.style.display="none"}if(a.MathJax){a.MathJax.checked=1}},processScripts:function(h,b,d){if(arguments.callee.disabled){return null}var q,o=MathJax.ElementJax.STATE;var p=this.config.inputJax,c=this.config.outputJax;try{if(!b){b=new Date().getTime()}var j=0,l,f;while(j<h.length){l=h[j];if(!l){j++;continue}f=l.previousSibling;if(f&&f.className==="MathJax_Error"){f.parentNode.removeChild(f)}var k=l.type.replace(/ *;(.|\s)*/,"");if(!l.MathJax||l.MathJax.state===o.PROCESSED){j++;continue}if(!l.MathJax.elementJax||l.MathJax.state===o.UPDATE){this.checkScriptSiblings(l);q=p[k].Process(l);if(typeof q==="function"){if(q.called){continue}this.RestartAfter(q)}q.Attach(l,p[k]);l.MathJax.state=o.OUTPUT}var a=l.MathJax.elementJax;if(!c[a.mimeType]){l.MathJax.state=o.UPDATE;throw Error("No output jax registered for "+a.mimeType)}a.outputJax=c[a.mimeType][0];q=a.outputJax.Process(l);if(typeof q==="function"){if(q.called){continue}this.RestartAfter(q)}l.MathJax.state=o.PROCESSED;this.signal.Post(["New Math",a.inputID]);j++;if(new Date().getTime()-b>this.processUpdateTime&&j<h.length){b=0;this.RestartAfter(MathJax.Callback.Delay(1))}}}catch(g){if(!g.restart){if(!this.config.errorSettings.message){throw g}this.formatError(l,g);j++}if(!d){d=0}var e=Math.floor((d+j)/(d+h.length)*100);d+=j;if(this.config.showProcessingMessages){MathJax.Message.Set("Processing math: "+e+"%",0)}return MathJax.Callback.After(["processScripts",this,h.slice(j),b,d],g.restart)}if((d||h.length)&&this.config.showProcessingMessages){MathJax.Message.Set("Processing Math: 100%",0);MathJax.Message.Clear(0)}return null},formatError:function(a,c){var b=MathJax.HTML.Element("span",{className:"MathJax_Error"},this.config.errorSettings.message);a.parentNode.insertBefore(b,a);this.lastError=c},RestartAfter:function(a){throw this.Insert(Error("restart"),{restart:MathJax.Callback(a)})},elementCallback:function(c,f){if(f==null&&(c instanceof Array||typeof c==="function")){try{MathJax.Callback(c);f=c;c=null}catch(d){}}if(c==null){c=this.config.elements||[]}if(!(c instanceof Array)){c=[c]}c=[].concat(c);for(var b=0,a=c.length;b<a;b++){if(typeof(c[b])==="string"){c[b]=document.getElementById(c[b])}}if(c.length==0){c.push(document.body)}if(!f){f={}}return{elements:c,callback:f}},elementScripts:function(a){if(typeof(a)==="string"){a=document.getElementById(a)}if(a==null){a=document.body}if(a.tagName!=null&&a.tagName.toLowerCase()==="script"){return[a]}return a.getElementsByTagName("script")},Insert:function(c,a){for(var b in a){if(a.hasOwnProperty(b)){if(typeof a[b]==="object"&&!(a[b] instanceof Array)&&(typeof c[b]==="object"||typeof c[b]==="function")){this.Insert(c[b],a[b])}else{c[b]=a[b]}}}return c}};MathJax.Hub.Insert(MathJax.Hub.config.styles,MathJax.Message.styles);MathJax.Hub.Insert(MathJax.Hub.config.styles,{".MathJax_Error":MathJax.Hub.config.errorSettings.style});MathJax.Extension={};MathJax.Hub.Configured=MathJax.Callback({});MathJax.Hub.Startup={script:"",queue:MathJax.Callback.Queue(),signal:MathJax.Callback.Signal("Startup"),params:{},Config:function(){this.queue.Push(["Post",this.signal,"Begin Config"]);var b=MathJax.HTML.Cookie.Get("user");if(b.URL||b.Config){if(confirm("MathJax has found a user-configuration cookie that includes code to be run. Do you want to run it?\n\n(You should press Cancel unless you set up the cookie yourself.)")){if(b.URL){this.queue.Push(["Require",MathJax.Ajax,b.URL])}if(b.Config){this.queue.Push(new Function(b.Config))}}else{MathJax.HTML.Cookie.Set("user",{})}}if(this.params.config){var d=this.params.config.split(/,/);for(var c=0,a=d.length;c<a;c++){if(!d[c].match(/\.js$/)){d[c]+=".js"}this.queue.Push(["Require",MathJax.Ajax,this.URL("config",d[c])])}}if(this.script.match(/\S/)){this.queue.Push(this.script+";\n1;")}this.queue.Push(["ConfigDelay",this],["ConfigBlocks",this],["ConfigDefault",this],[function(e){return e.loadArray(MathJax.Hub.config.config,"config",null,true)},this],["Post",this.signal,"End Config"])},ConfigDelay:function(){var a=this.params.delayStartupUntil||MathJax.Hub.config.delayStartupUntil;if(a==="onload"){return this.onload}if(a==="configured"){return MathJax.Hub.Configured}return a},ConfigBlocks:function(){var c=document.getElementsByTagName("script");var f=null,b=MathJax.Callback.Queue();for(var d=0,a=c.length;d<a;d++){var e=String(c[d].type).replace(/ /g,"");if(e.match(/^text\/x-mathjax-config(;.*)?$/)&&!e.match(/;executed=true/)){c[d].type+=";executed=true";f=b.Push(c[d].innerHTML+";\n1;")}}return f},ConfigDefault:function(){var a=MathJax.Hub.config;if(a["v1.0-compatible"]&&a.jax.length===0){return MathJax.Ajax.Require(this.URL("extensions","v1.0-warning.js"))}},Cookie:function(){return this.queue.Push(["Post",this.signal,"Begin Cookie"],["Get",MathJax.HTML.Cookie,"menu",MathJax.Hub.config.menuSettings],[function(d){var f=d.menuSettings.renderer,b=d.jax;if(f){var c="output/"+f;b.sort();for(var e=0,a=b.length;e<a;e++){if(b[e].substr(0,7)==="output/"){break}}if(e==a-1){b.pop()}else{while(e<a){if(b[e]===c){b.splice(e,1);break}e++}}b.unshift(c)}},MathJax.Hub.config],["Post",this.signal,"End Cookie"])},Styles:function(){return this.queue.Push(["Post",this.signal,"Begin Styles"],["loadArray",this,MathJax.Hub.config.styleSheets,"config"],["Styles",MathJax.Ajax,MathJax.Hub.config.styles],["Post",this.signal,"End Styles"])},Jax:function(){var d=MathJax.Hub.config;for(var e=0,b=d.jax.length,c=0;e<b;e++){if(d.jax[e].substr(0,7)==="output/"){d.outputJax.order[d.jax[e].substr(7)]=c;c++}}var a=MathJax.Callback.Queue();return a.Push(["Post",this.signal,"Begin Jax"],["loadArray",this,d.jax,"jax","config.js"],["Post",this.signal,"End Jax"])},Extensions:function(){var a=MathJax.Callback.Queue();return a.Push(["Post",this.signal,"Begin Extensions"],["loadArray",this,MathJax.Hub.config.extensions,"extensions"],["Post",this.signal,"End Extensions"])},Message:function(){MathJax.Message.Init(true)},Menu:function(){var b=MathJax.Hub.config.menuSettings,a=MathJax.Hub.config.outputJax,d;for(var c in a){if(a.hasOwnProperty(c)){if(a[c].length){d=a[c];break}}}if(d&&d.length){if(b.renderer&&b.renderer!==d[0].id){d.unshift(MathJax.OutputJax[b.renderer])}b.renderer=d[0].id}},onLoad:function(a){var b=this.onload=MathJax.Callback(function(){MathJax.Hub.Startup.signal.Post("onLoad")});if(window.addEventListener){window.addEventListener("load",b,false)}else{if(window.attachEvent){window.attachEvent("onload",b)}else{window.onload=b}}return b},Typeset:function(a,b){if(MathJax.Hub.config.skipStartupTypeset){return function(){}}return this.queue.Push(["Post",this.signal,"Begin Typeset"],["Typeset",MathJax.Hub,a,b],["Post",this.signal,"End Typeset"])},URL:function(b,a){if(!a.match(/^([a-z]+:\/\/|\[|\/)/)){a="[MathJax]/"+b+"/"+a}return a},loadArray:function(b,f,c,a){if(b){if(!(b instanceof Array)){b=[b]}if(b.length){var h=MathJax.Callback.Queue(),j={},e;for(var g=0,d=b.length;g<d;g++){e=this.URL(f,b[g]);if(c){e+="/"+c}if(a){h.Push(["Require",MathJax.Ajax,e,j])}else{h.Push(MathJax.Ajax.Require(e,j))}}return h.Push({})}}return null}};(function(d){var b=window[d],e="["+d+"]";var c=b.Hub,a=b.Ajax,f=b.Callback;var g=MathJax.Object.Subclass({JAXFILE:"jax.js",require:null,config:{},Init:function(i,h){if(arguments.length===0){return this}return(this.constructor.Subclass(i,h))()},Augment:function(k,j){var i=this.constructor,h={};if(k!=null){for(var l in k){if(k.hasOwnProperty(l)){if(typeof k[l]==="function"){i.protoFunction(l,k[l])}else{h[l]=k[l]}}}if(k.toString!==i.prototype.toString&&k.toString!=={}.toString){i.protoFunction("toString",k.toString)}}c.Insert(i.prototype,h);i.Augment(null,j);return this},Process:function(h){var i=a.Require(this.directory+"/"+this.JAXFILE);if(!i.called){this.constructor.prototype.Process=function(j){return i}}return i},Translate:function(h){throw Error(this.directory+"/"+this.JAXFILE+" failed to redefine the Translate() method")},Register:function(h){},Config:function(){this.config=c.CombineConfig(this.id,this.config);if(this.config.Augment){this.Augment(this.config.Augment)}},Startup:function(){},loadComplete:function(i){if(i==="config.js"){a.loadComplete(this.directory+"/"+i)}else{var h=f.Queue();h.Push(c.Register.StartupHook("End Config",{}),["Post",c.Startup.signal,this.id+" Jax Config"],["Config",this],["Post",c.Startup.signal,this.id+" Jax Require"],[function(j){return MathJax.Hub.Startup.loadArray(j.require,this.directory)},this],[function(j,k){return MathJax.Hub.Startup.loadArray(j.extensions,"extensions/"+k)},this.config||{},this.id],["Post",c.Startup.signal,this.id+" Jax Startup"],["Startup",this],["Post",c.Startup.signal,this.id+" Jax Ready"],[function(j){j.Process=j.Translate},this.constructor.prototype],["loadComplete",a,this.directory+"/"+i])}}},{id:"unknown",version:"1.1",directory:e+"/jax",extensionDir:e+"/extensions"});b.InputJax=g.Subclass({elementJax:"mml",Process:function(o){var j=f.Queue();var k=this.elementJax;if(!(k instanceof Array)){k=[k]}for(var n=0,h=k.length;n<h;n++){var l=b.ElementJax.directory+"/"+k[n]+"/"+this.JAXFILE;if(!this.require){this.require=[]}else{if(!(this.require instanceof Array)){this.require=[this.require]}}this.require.push(l);j.Push(a.Require(l))}var p=j.Push(a.Require(this.directory+"/"+this.JAXFILE));if(!p.called){this.constructor.prototype.Process=function(){return p}}k=c.config.outputJax["jax/"+k[0]];if(k){j.Push(a.Require(k[0].directory+"/"+this.JAXFILE))}return j.Push({})},Register:function(h){if(!c.config.inputJax){c.config.inputJax={}}c.config.inputJax[h]=this}},{version:"1.1",directory:g.directory+"/input",extensionDir:g.extensionDir});b.OutputJax=g.Subclass({Register:function(i){var h=c.config.outputJax;if(!h[i]){h[i]=[]}if(h[i].length&&(this.id===c.config.menuSettings.renderer||(h.order[this.id]||0)<(h.order[h[i][0].id]||0))){h[i].unshift(this)}else{h[i].push(this)}if(!this.require){this.require=[]}else{if(!(this.require instanceof Array)){this.require=[this.require]}}this.require.push(b.ElementJax.directory+"/"+(i.split(/\//)[1])+"/"+this.JAXFILE)},Remove:function(h){}},{version:"1.1",directory:g.directory+"/output",extensionDir:g.extensionDir,fontDir:e+(b.isPacked?"":"/..")+"/fonts"});b.ElementJax=g.Subclass({Init:function(i,h){return this.constructor.Subclass(i,h)},inputJax:null,outputJax:null,inputID:null,originalText:"",mimeType:"",Text:function(i,j){var h=this.SourceElement();b.HTML.setScript(h,i);h.MathJax.state=this.STATE.UPDATE;return c.Update(h,j)},Reprocess:function(i){var h=this.SourceElement();h.MathJax.state=this.STATE.UPDATE;return c.Reprocess(h,i)},Update:function(i){var h=this.SourceElement();h.MathJax.state=this.STATE.OUTPUT;return c.Process(h,i)},Remove:function(){this.outputJax.Remove(this);c.signal.Post(["Remove Math",this.inputID]);this.Detach()},SourceElement:function(){return document.getElementById(this.inputID)},Attach:function(i,j){var h=i.MathJax.elementJax;if(i.MathJax.state===this.STATE.UPDATE){h.Clone(this)}else{h=i.MathJax.elementJax=this;if(i.id){this.inputID=i.id}else{i.id=this.inputID=b.ElementJax.GetID();this.newID=1}}h.originalText=(i.text==""?i.innerHTML:i.text);h.inputJax=j;if(h.root){h.root.inputID=h.inputID}},Detach:function(){var h=this.SourceElement();if(!h){return}try{delete h.MathJax}catch(i){h.MathJax=null}if(this.newID){h.id=""}},Clone:function(h){var i;for(i in this){if(!this.hasOwnProperty(i)){continue}if(typeof(h[i])==="undefined"&&i!=="newID"){delete this[i]}}for(i in h){if(!this.hasOwnProperty(i)){continue}if(typeof(this[i])==="undefined"||(this[i]!==h[i]&&i!=="inputID")){this[i]=h[i]}}}},{version:"1.1",directory:g.directory+"/element",extensionDir:g.extensionDir,ID:0,STATE:{PENDING:1,PROCESSED:2,UPDATE:3,OUTPUT:4},GetID:function(){this.ID++;return"MathJax-Element-"+this.ID},Subclass:function(){var h=g.Subclass.apply(this,arguments);h.loadComplete=this.prototype.loadComplete;return h}});b.ElementJax.prototype.STATE=b.ElementJax.STATE})("MathJax");(function(l){var f=window[l];if(!f){f=window[l]={}}var c=f.Hub;var q=c.Startup;var u=c.config;var e=document.getElementsByTagName("head")[0];if(!e){e=document.childNodes[0]}var b=(document.documentElement||document).getElementsByTagName("script");var d=new RegExp("(^|/)"+l+"\\.js(\\?.*)?$");for(var o=b.length-1;o>=0;o--){if(b[o].src.match(d)){q.script=b[o].innerHTML;if(RegExp.$2){var r=RegExp.$2.substr(1).split(/\&/);for(var n=0,h=r.length;n<h;n++){var k=r[n].match(/(.*)=(.*)/);if(k){q.params[unescape(k[1])]=unescape(k[2])}}}u.root=b[o].src.replace(/(^|\/)[^\/]*(\?.*)?$/,"");break}}f.Ajax.config=u;var a={isMac:(navigator.platform.substr(0,3)==="Mac"),isPC:(navigator.platform.substr(0,3)==="Win"),isMSIE:(window.ActiveXObject!=null&&window.clipboardData!=null),isFirefox:(window.netscape!=null&&document.ATTRIBUTE_NODE!=null&&!window.opera),isSafari:(navigator.userAgent.match(/ (Apple)?WebKit\//)!=null&&!window.chrome),isChrome:(window.chrome!=null&&window.chrome.loadTimes!=null),isOpera:(window.opera!=null&&window.opera.version!=null),isKonqueror:(window.hasOwnProperty&&window.hasOwnProperty("konqueror")&&navigator.vendor=="KDE"),versionAtLeast:function(x){var w=(this.version).split(".");x=(new String(x)).split(".");for(var y=0,j=x.length;y<j;y++){if(w[y]!=x[y]){return parseInt(w[y]||"0")>=parseInt(x[y])}}return true},Select:function(j){var i=j[c.Browser];if(i){return i(c.Browser)}return null}};var g=navigator.userAgent.replace(/^Mozilla\/(\d+\.)+\d+ /,"").replace(/[a-z][-a-z0-9._: ]+\/\d+[^ ]*-[^ ]*\.([a-z][a-z])?\d+ /i,"").replace(/Gentoo |Ubuntu\/(\d+\.)*\d+ (\([^)]*\) )?/,"");c.Browser=c.Insert(c.Insert(new String("Unknown"),{version:"0.0"}),a);for(var t in a){if(a.hasOwnProperty(t)){if(a[t]&&t.substr(0,2)==="is"){t=t.slice(2);if(t==="Mac"||t==="PC"){continue}c.Browser=c.Insert(new String(t),a);var p=new RegExp(".*(Version)/((?:\\d+\\.)+\\d+)|.*("+t+")"+(t=="MSIE"?" ":"/")+"((?:\\d+\\.)*\\d+)|(?:^|\\(| )([a-z][-a-z0-9._: ]+|(?:Apple)?WebKit)/((?:\\d+\\.)+\\d+)");var s=p.exec(g)||["","","","unknown","0.0"];c.Browser.name=(s[1]=="Version"?t:(s[3]||s[5]));c.Browser.version=s[2]||s[4]||s[6];break}}}c.Browser.Select({Safari:function(j){var i=parseInt((String(j.version).split("."))[0]);if(i>85){j.webkit=j.version}if(i>=533){j.version="5.0"}else{if(i>=526){j.version="4.0"}else{if(i>=525){j.version="3.1"}else{if(i>500){j.version="3.0"}else{if(i>400){j.version="2.0"}else{if(i>85){j.version="1.0"}}}}}}},Firefox:function(j){if(j.version==="0.0"&&navigator.product==="Gecko"&&navigator.productSub){var i=navigator.productSub.substr(0,8);if(i>="20090630"){j.version="3.5"}else{if(i>="20080617"){j.version="3.0"}else{if(i>="20061024"){j.version="2.0"}}}}},Opera:function(i){i.version=opera.version()},MSIE:function(i){i.isIE9=!!(document.documentMode&&(window.performance||window.msPerformance));MathJax.HTML.setScriptBug=!i.isIE9||document.documentMode<9}});c.Browser.Select(MathJax.Message.browsers);c.queue=f.Callback.Queue();c.queue.Push(["Post",q.signal,"Begin"],["Config",q],["Cookie",q],["Styles",q],["Message",q],function(){var i=f.Callback.Queue(q.Jax(),q.Extensions());return i.Push({})},["Menu",q],q.onLoad(),function(){MathJax.isReady=true},["Typeset",q],["Post",q.signal,"End"])})("MathJax")}};
+
90 ...lisp/microlisp/A micro-manual for LISP Implemented in C (by Nurullah Akkaya)_files/all.js
90 additions, 0 deletions not shown
BIN  ...icrolisp/A micro-manual for LISP Implemented in C (by Nurullah Akkaya)_files/avatar32.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  ...lisp/A micro-manual for LISP Implemented in C (by Nurullah Akkaya)_files/avatar32_002.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  ...p/A micro-manual for LISP Implemented in C (by Nurullah Akkaya)_files/baguface_normal.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
124 ...sp/microlisp/A micro-manual for LISP Implemented in C (by Nurullah Akkaya)_files/def.html
@@ -0,0 +1,124 @@
+<!DOCTYPE html>
+<html><head>
+<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1"></head><body>
+ <script src="def_data/quant.js" async="" type="text/javascript"></script><script src="A%20micro-manual%20for%20LISP%20Implemented%20in%20C%20%28by%20Nurullah%20Akkaya%29_files/ga.js" async="" type="text/javascript"></script><script src="def_data/beacon.js" async=""></script><script>
+ document.domain = 'disqus.com';
+
+ var urls = {
+ sigma: (document.location.protocol == 'https:' ? 'https:' : 'http:') + '//sigma.disqus.com/sigma.html',
+ xdm: "http://mediacdn.disqus.com/1322703032/html/xdm.html",
+ swf: "http://mediacdn.disqus.com/1322703032/xdm.swf",
+ api: (document.location.protocol == 'https:' ? 'https:' : 'http:') +
+ '//api.disqus.com/api/3.0/'
+ },
+
+ settings = {
+ debug: false,
+ domain: "disqus.com",
+ realtimeHost: "qq.disqus.com",
+ realtimePort: "80"
+ };
+
+ var DISQUS=function(){var b=window.document,c=b.getElementsByTagName("script"),f,k,v,p;f=b.getElementsByTagName("head")[0]||b.getElementsByTagName("body")[0];k={running:!1,timer:null,queue:[]};p={};v=c[c.length-1].src.split("/");v.pop();v=v.join("/");p.defer=function(b,c){function j(){if(k.queue.length===0)k.running=!1,clearInterval(k.timer);else{var b=k.queue.shift();if(b[0]())b[1]();else k.queue.push(b)}}k.queue.push([b,c]);j();if(!k.running)k.running=!0,k.timer=setInterval(j,100);return k.queue.length};
+p.each=function(b,c){var j=b.length,f=Array.prototype.forEach;if(isNaN(j))for(var m in b)b.hasOwnProperty(m)&&c(b[m],m,b);else if(f)f.call(b,c);else for(f=0;f<j;f++)c(b[f],f,b)};p.extend=function(){var b,f;arguments.length<=1?(b=p,f=[arguments[0]||{}]):(b=arguments[0]||{},f=Array.prototype.slice.call(arguments,1));for(var j=0;j<f.length;j++)for(var c in f[j])f[j].hasOwnProperty(c)&&(b[c]=f[j][c]);return b};p.load=function(c,k){c=(c.slice(0,4)!="http"?v+"/":"")+c;if(k){var j=c.slice(c.length-1);c+=
+(j!="&"&&j!="?"?"?":"")+(new Date).getTime()}j=b.createElement("script");j.src=c;j.async=!0;j.charset="UTF-8";f.appendChild(j);return j};return p}();DISQUS.extend({comments:{},host:{},net:{},widgets:{}});(function(){function b(b){return b<10?"0"+b:b}function c(b){w.lastIndex=0;return w.test(b)?'"'+b.replace(w,function(b){var c=L[b];return typeof c==="string"?c:"\\u"+("0000"+b.charCodeAt(0).toString(16)).slice(-4)})+'"':'"'+b+'"'}function f(b,k){var u,o,r,p,s=q,y,h=k[b];h&&typeof h==="object"&&typeof h.toJSON==="function"&&!v&&(h=h.toJSON(b));typeof m==="function"&&(h=m.call(k,b,h));switch(typeof h){case "string":return c(h);case "number":return isFinite(h)?String(h):"null";case "boolean":case "null":return String(h);
+case "object":if(!h)return"null";q+=j;y=[];if(Object.prototype.toString.apply(h)==="[object Array]"){p=h.length;for(u=0;u<p;u+=1)y[u]=f(u,h)||"null";r=y.length===0?"[]":q?"[\n"+q+y.join(",\n"+q)+"\n"+s+"]":"["+y.join(",")+"]";q=s;return r}if(m&&typeof m==="object"){p=m.length;for(u=0;u<p;u+=1)o=m[u],typeof o==="string"&&(r=f(o,h))&&y.push(c(o)+(q?": ":":")+r)}else for(o in h)Object.hasOwnProperty.call(h,o)&&(r=f(o,h))&&y.push(c(o)+(q?": ":":")+r);r=y.length===0?"{}":q?"{\n"+q+y.join(",\n"+q)+"\n"+
+s+"}":"{"+y.join(",")+"}";q=s;return r}}var k={},v=!1;if(typeof Date.prototype.toJSON!=="function")Date.prototype.toJSON=function(){return isFinite(this.valueOf())?this.getUTCFullYear()+"-"+b(this.getUTCMonth()+1)+"-"+b(this.getUTCDate())+"T"+b(this.getUTCHours())+":"+b(this.getUTCMinutes())+":"+b(this.getUTCSeconds())+"Z":null},String.prototype.toJSON=Number.prototype.toJSON=Boolean.prototype.toJSON=function(){return this.valueOf()};var p=/[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
+w=/[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,q,j,L={"\u0008":"\\b","\t":"\\t","\n":"\\n","\u000c":"\\f","\r":"\\r",'"':'\\"',"\\":"\\\\"},m;k.stringify=function(b,c,k){var o;j=q="";if(typeof k==="number")for(o=0;o<k;o+=1)j+=" ";else typeof k==="string"&&(j=k);if((m=c)&&typeof c!=="function"&&(typeof c!=="object"||typeof c.length!=="number"))throw Error("JSON.stringify");return f("",{"":b})};k.parse=function(b,c){function f(b,
+j){var k,m,h=b[j];if(h&&typeof h==="object")for(k in h)Object.hasOwnProperty.call(h,k)&&(m=f(h,k),m!==void 0?h[k]=m:delete h[k]);return c.call(b,j,h)}var j,b=String(b);p.lastIndex=0;p.test(b)&&(b=b.replace(p,function(b){return"\\u"+("0000"+b.charCodeAt(0).toString(16)).slice(-4)}));if(/^[\],:{}\s]*$/.test(b.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,"@").replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,"]").replace(/(?:^|:|,)(?:\s*\[)+/g,"")))return j=eval("("+b+")"),
+typeof c==="function"?f({"":j},""):j;throw new SyntaxError("JSON.parse");};DISQUS.json={};var z={a:[1,2,3]};if(Object.toJSON&&Object.toJSON(z).replace(/\s/g,"")==='{"a":[1,2,3]}')DISQUS.json.stringify=Object.toJSON;if(typeof String.prototype.evalJSON==="function"&&(z='{"a":[1,2,3]}'.evalJSON(),z.a&&z.a.length===3&&z.a[2]===3))DISQUS.json.parse=function(b){return b.evalJSON()};(function(){var b=[1,2,3];typeof b.toJSON==="function"&&(b=b.toJSON(),v=!(b&&b.length===3&&b[2]===3))})();if(!DISQUS.json.stringify||
+!DISQUS.json.parse)DISQUS.json={stringify:k.stringify,parse:k.parse}})();(function(b,c,f,k,v,p){function w(d,a){var i=typeof d[a];return i=="function"||!!(i=="object"&&d[a])||i=="unknown"}function q(){q=t;J=!0;for(var d=0;d<O.length;d++)O[d]();O.length=0}function j(d,a){J?d.call(a):O.push(function(){d.call(a)})}function L(){var d=parent;if(N!=="")for(var a=0,i=N.split(".");a<i.length;a++)d=d[i[a]];return d.easyXDM}function m(d){var a=d.match(x),d=a[2],i=a[3],a=a[4]||"";if(d=="http:"&&a==":80"||d=="https:"&&a==":443")a="";return d+"//"+i+a}function z(d){d=d.replace(H,"$1/");
+if(!d.match(/^(http||https):\/\//)){var a=d.substring(0,1)==="/"?"":f.pathname;a.substring(a.length-1)!=="/"&&(a=a.substring(0,a.lastIndexOf("/")+1));d=f.protocol+"//"+f.host+a+d}for(;U.test(d);)d=d.replace(U,"");return d}function C(d,a){var i="",b=d.indexOf("#");b!==-1&&(i=d.substring(b).replace("#","&"),d=d.substring(0,b));var b=[],e;for(e in a)a.hasOwnProperty(e)&&b.push(e+"="+p(a[e]));return d+(V?"#":d.indexOf("?")==-1?"?":"&")+b.join("&")+i}function E(d){return typeof d==="undefined"}function u(){var d=
+{},a={a:[1,2,3]};if(typeof JSON!="undefined"&&typeof JSON.stringify==="function"&&JSON.stringify(a).replace(/\s/g,"")==='{"a":[1,2,3]}')return JSON;if(Object.toJSON&&Object.toJSON(a).replace(/\s/g,"")==='{"a":[1,2,3]}')d.stringify=Object.toJSON;if(typeof String.prototype.evalJSON==="function"&&(a='{"a":[1,2,3]}'.evalJSON(),a.a&&a.a.length===3&&a.a[2]===3))d.parse=function(a){return a.evalJSON()};if(d.stringify&&d.parse)return u=function(){return d},d;return null}function o(d,a,i){var b,e;for(e in a)a.hasOwnProperty(e)&&
+(e in d?(b=a[e],typeof b==="object"?o(d[e],b,i):i||(d[e]=a[e])):d[e]=a[e]);return d}function r(d){if(E(R)){var a=c.createElement("iframe");a.name=D+"TEST";o(a.style,{position:"absolute",left:"-2000px",top:"0px"});c.body.appendChild(a);R=a.contentWindow!==b.frames[a.name];c.body.removeChild(a)}R&&!~navigator.userAgent.indexOf("Firefox")?a=c.createElement('<iframe name="'+d.props.name+'"/>'):(a=c.createElement("IFRAME"),a.name=d.props.name);a.id=a.name=d.props.name;delete d.props.name;d.onLoad&&F(a,
+"load",d.onLoad);if(typeof d.container=="string")d.container=c.getElementById(d.container);if(!d.container)a.style.position="absolute",a.style.top="-2000px",a.style.left="0px",d.container=c.body;var i=d.props.src;delete d.props.src;o(a,d.props);a.border=a.frameBorder=0;d.container.appendChild(a);a.src=i;d.props.src=i;return a}function M(d){var a=d.protocol,i;d.isHost=d.isHost||E(A.xdm_p);V=d.hash||!1;if(!d.props)d.props={};if(d.isHost){if(d.remote=z(d.remote),d.channel=d.channel||"default"+S++,d.secret=
+Math.random().toString(16).substring(2),E(a))if(h.parent==h&&m(f.href)==m(d.remote))a="4";else if(w(b,"postMessage")||w(c,"postMessage"))a="1";else{if(a=w(b,"ActiveXObject"))try{new ActiveXObject("ShockwaveFlash.ShockwaveFlash"),a=!0}catch(l){a=!1}a?a="6":navigator.product==="Gecko"&&"frameElement"in b&&navigator.userAgent.indexOf("WebKit")==-1?a="5":d.remoteHelper?(d.remoteHelper=z(d.remoteHelper),a="2"):a="0"}}else{d.channel=A.xdm_c;d.secret=A.xdm_s;d.remote=A.xdm_e;var a=A.xdm_p,e;if(e=d.acl){a:{e=
+d.acl;var P=d.remote;typeof e=="string"&&(e=[e]);for(var n,G=e.length;G--;)if(n=e[G],n=RegExp(n.substr(0,1)=="^"?n:"^"+n.replace(/(\*)/g,".$1").replace(/\?/g,".")+"$"),n.test(P)){e=!0;break a}e=!1}e=!e}if(e)throw Error("Access denied for "+d.remote);}switch(a){case "0":o(d,{interval:100,delay:2E3,useResize:!0,useParent:!1,usePolling:!1},!0);if(d.isHost){if(!d.local){i=f.protocol+"//"+f.host;a=c.body.getElementsByTagName("img");for(P=a.length;P--;)if(e=a[P],e.src.substring(0,i.length)===i){d.local=
+e.src;break}if(!d.local)d.local=b}i={xdm_c:d.channel,xdm_p:0};d.local===b?(d.usePolling=!0,d.useParent=!0,d.local=f.protocol+"//"+f.host+f.pathname+f.search,i.xdm_e=d.local,i.xdm_pa=1):i.xdm_e=z(d.local);if(d.container)d.useResize=!1,i.xdm_po=1;d.remote=C(d.remote,i)}else o(d,{channel:A.xdm_c,remote:A.xdm_e,useParent:!E(A.xdm_pa),usePolling:!E(A.xdm_po),useResize:d.useParent?!1:d.useResize});i=[new g.stack.HashTransport(d),new g.stack.ReliableBehavior({}),new g.stack.QueueBehavior({encode:!0,maxLength:4E3-
+d.remote.length}),new g.stack.VerifyBehavior({initiate:d.isHost})];break;case "1":i=[new g.stack.PostMessageTransport(d)];break;case "2":i=[new g.stack.NameTransport(d),new g.stack.QueueBehavior,new g.stack.VerifyBehavior({initiate:d.isHost})];break;case "3":i=[new g.stack.NixTransport(d)];break;case "4":i=[new g.stack.SameOriginTransport(d)];break;case "5":i=[new g.stack.FrameElementTransport(d)];break;case "6":if(!d.swf)d.swf="../../tools/easyxdm.swf";i=[new g.stack.FlashTransport(d)]}i.push(new g.stack.QueueBehavior({lazy:d.lazy,
+remove:!0}));return i}function s(d){for(var a,i={incoming:function(a,d){this.up.incoming(a,d)},outgoing:function(a,d){this.down.outgoing(a,d)},callback:function(a){this.up.callback(a)},init:function(){this.down.init()},destroy:function(){this.down.destroy()}},b=0,e=d.length;b<e;b++){a=d[b];o(a,i,!0);if(b!==0)a.down=d[b-1];if(b!==e-1)a.up=d[b+1]}return a}function y(d){d.up.down=d.down;d.down.up=d.up;d.up=d.down=null}var h=this,S=Math.floor(Math.random()*1E4),t=Function.prototype,x=/^((http.?:)\/\/([^:\/\s]+)(:\d+)*)/,
+U=/[\-\w]+\/\.\.\//,H=/([^:])\/\//g,N="",g={},W=b.easyXDM,D="easyXDM_",R,V=!1,F,K;if(w(b,"addEventListener"))F=function(d,a,b){d.addEventListener(a,b,!1)},K=function(d,a,b){d.removeEventListener(a,b,!1)};else if(w(b,"attachEvent"))F=function(d,a,b){d.attachEvent("on"+a,b)},K=function(d,a,b){d.detachEvent("on"+a,b)};else throw Error("Browser not supported");var J=!1,O=[],Q;"readyState"in c?(Q=c.readyState,J=Q=="complete"||~navigator.userAgent.indexOf("AppleWebKit/")&&(Q=="loaded"||Q=="interactive")):
+J=!!c.body;J||(w(b,"addEventListener")?F(c,"DOMContentLoaded",q):(F(c,"readystatechange",function(){c.readyState=="complete"&&q()}),c.documentElement.doScroll&&b===top&&function a(){if(!J){try{c.documentElement.doScroll("left")}catch(b){k(a,1);return}q()}}()),F(b,"load",q));var A=function(a){for(var a=a.substring(1).split("&"),b={},l,e=a.length;e--;)l=a[e].split("="),b[l[0]]=v(l[1]);return b}(/xdm_e=/.test(f.search)?f.search:f.hash);o(g,{version:"2.4.12.1",query:A,stack:{},apply:o,getJSONObject:u,
+whenReady:j,noConflict:function(a){b.easyXDM=W;(N=a)&&(D="easyXDM_"+N.replace(".","_")+"_");return g}});g.DomHelper={on:F,un:K,requiresJSON:function(a){typeof b.JSON=="object"&&b.JSON||c.write('<script type="text/javascript" src="'+a+'"><\/script>')}};(function(){var a={};g.Fn={set:function(b,l){a[b]=l},get:function(b,l){var e=a[b];l&&delete a[b];return e}}})();g.Socket=function(a){var b=s(M(a).concat([{incoming:function(b,i){a.onMessage(b,i)},callback:function(b){if(a.onReady)a.onReady(b)}}])),l=
+m(a.remote);this.origin=m(a.remote);this.destroy=function(){b.destroy()};this.postMessage=function(a){b.outgoing(a,l)};b.init()};g.Rpc=function(a,b){if(b.local)for(var l in b.local)if(b.local.hasOwnProperty(l)){var e=b.local[l];typeof e==="function"&&(b.local[l]={method:e})}var c=s(M(a).concat([new g.stack.RpcBehavior(this,b),{callback:function(b){if(a.onReady)a.onReady(b)}}]));this.origin=m(a.remote);this.destroy=function(){c.destroy()};c.init()};g.stack.SameOriginTransport=function(a){var b,l,e,
+c;return b={outgoing:function(a,b,i){e(a);i&&i()},destroy:function(){l&&(l.parentNode.removeChild(l),l=