Updating to reflect the latest work.
authorJason Self <j@jxself.org>
Fri, 6 May 2016 19:44:21 +0000 (12:44 -0700)
committerJason Self <j@jxself.org>
Fri, 6 May 2016 19:44:21 +0000 (12:44 -0700)
18 files changed:
zilasm/GPLv3.txt [new file with mode: 0644]
zilasm/Makefile.am
zilasm/configure.ac
zilasm/directives.c [new file with mode: 0644]
zilasm/directives.h [new file with mode: 0644]
zilasm/header.c [new file with mode: 0644]
zilasm/header.h [new file with mode: 0644]
zilasm/labels.c [new file with mode: 0644]
zilasm/labels.h [new file with mode: 0644]
zilasm/main.c
zilasm/opcodes.c [new file with mode: 0644]
zilasm/opcodes.h [new file with mode: 0644]
zilasm/parser.c [new file with mode: 0644]
zilasm/parser.h [new file with mode: 0644]
zilasm/symtable.c [new file with mode: 0644]
zilasm/symtable.h [new file with mode: 0644]
zilasm/zmem.c [new file with mode: 0644]
zilasm/zmem.h [new file with mode: 0644]

diff --git a/zilasm/GPLv3.txt b/zilasm/GPLv3.txt
new file mode 100644 (file)
index 0000000..94a9ed0
--- /dev/null
@@ -0,0 +1,674 @@
+                    GNU GENERAL PUBLIC LICENSE
+                       Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                            Preamble
+
+  The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+  The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works.  By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users.  We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors.  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+  To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights.  Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received.  You must make sure that they, too, receive
+or can get the source code.  And you must show them these terms so they
+know their rights.
+
+  Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+  For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software.  For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+  Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so.  This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software.  The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable.  Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products.  If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+  Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary.  To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+                       TERMS AND CONDITIONS
+
+  0. Definitions.
+
+  "This License" refers to version 3 of the GNU General Public License.
+
+  "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+  "The Program" refers to any copyrightable work licensed under this
+License.  Each licensee is addressed as "you".  "Licensees" and
+"recipients" may be individuals or organizations.
+
+  To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy.  The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+  A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+  To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy.  Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+  To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies.  Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+  An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License.  If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+  1. Source Code.
+
+  The "source code" for a work means the preferred form of the work
+for making modifications to it.  "Object code" means any non-source
+form of a work.
+
+  A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+  The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form.  A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+  The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities.  However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work.  For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+  The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+  The Corresponding Source for a work in source code form is that
+same work.
+
+  2. Basic Permissions.
+
+  All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met.  This License explicitly affirms your unlimited
+permission to run the unmodified Program.  The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work.  This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+  You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force.  You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright.  Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+  Conveying under any other circumstances is permitted solely under
+the conditions stated below.  Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+  3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+  No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+  When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+  4. Conveying Verbatim Copies.
+
+  You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+  You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+  5. Conveying Modified Source Versions.
+
+  You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+    a) The work must carry prominent notices stating that you modified
+    it, and giving a relevant date.
+
+    b) The work must carry prominent notices stating that it is
+    released under this License and any conditions added under section
+    7.  This requirement modifies the requirement in section 4 to
+    "keep intact all notices".
+
+    c) You must license the entire work, as a whole, under this
+    License to anyone who comes into possession of a copy.  This
+    License will therefore apply, along with any applicable section 7
+    additional terms, to the whole of the work, and all its parts,
+    regardless of how they are packaged.  This License gives no
+    permission to license the work in any other way, but it does not
+    invalidate such permission if you have separately received it.
+
+    d) If the work has interactive user interfaces, each must display
+    Appropriate Legal Notices; however, if the Program has interactive
+    interfaces that do not display Appropriate Legal Notices, your
+    work need not make them do so.
+
+  A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit.  Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+  6. Conveying Non-Source Forms.
+
+  You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+    a) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by the
+    Corresponding Source fixed on a durable physical medium
+    customarily used for software interchange.
+
+    b) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by a
+    written offer, valid for at least three years and valid for as
+    long as you offer spare parts or customer support for that product
+    model, to give anyone who possesses the object code either (1) a
+    copy of the Corresponding Source for all the software in the
+    product that is covered by this License, on a durable physical
+    medium customarily used for software interchange, for a price no
+    more than your reasonable cost of physically performing this
+    conveying of source, or (2) access to copy the
+    Corresponding Source from a network server at no charge.
+
+    c) Convey individual copies of the object code with a copy of the
+    written offer to provide the Corresponding Source.  This
+    alternative is allowed only occasionally and noncommercially, and
+    only if you received the object code with such an offer, in accord
+    with subsection 6b.
+
+    d) Convey the object code by offering access from a designated
+    place (gratis or for a charge), and offer equivalent access to the
+    Corresponding Source in the same way through the same place at no
+    further charge.  You need not require recipients to copy the
+    Corresponding Source along with the object code.  If the place to
+    copy the object code is a network server, the Corresponding Source
+    may be on a different server (operated by you or a third party)
+    that supports equivalent copying facilities, provided you maintain
+    clear directions next to the object code saying where to find the
+    Corresponding Source.  Regardless of what server hosts the
+    Corresponding Source, you remain obligated to ensure that it is
+    available for as long as needed to satisfy these requirements.
+
+    e) Convey the object code using peer-to-peer transmission, provided
+    you inform other peers where the object code and Corresponding
+    Source of the work are being offered to the general public at no
+    charge under subsection 6d.
+
+  A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+  A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling.  In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage.  For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product.  A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+  "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source.  The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+  If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information.  But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+  The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed.  Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+  Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+  7. Additional Terms.
+
+  "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law.  If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+  When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it.  (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.)  You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+  Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+    a) Disclaiming warranty or limiting liability differently from the
+    terms of sections 15 and 16 of this License; or
+
+    b) Requiring preservation of specified reasonable legal notices or
+    author attributions in that material or in the Appropriate Legal
+    Notices displayed by works containing it; or
+
+    c) Prohibiting misrepresentation of the origin of that material, or
+    requiring that modified versions of such material be marked in
+    reasonable ways as different from the original version; or
+
+    d) Limiting the use for publicity purposes of names of licensors or
+    authors of the material; or
+
+    e) Declining to grant rights under trademark law for use of some
+    trade names, trademarks, or service marks; or
+
+    f) Requiring indemnification of licensors and authors of that
+    material by anyone who conveys the material (or modified versions of
+    it) with contractual assumptions of liability to the recipient, for
+    any liability that these contractual assumptions directly impose on
+    those licensors and authors.
+
+  All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10.  If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term.  If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+  If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+  Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+  8. Termination.
+
+  You may not propagate or modify a covered work except as expressly
+provided under this License.  Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+  However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+  Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+  Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License.  If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+  9. Acceptance Not Required for Having Copies.
+
+  You are not required to accept this License in order to receive or
+run a copy of the Program.  Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance.  However,
+nothing other than this License grants you permission to propagate or
+modify any covered work.  These actions infringe copyright if you do
+not accept this License.  Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+  10. Automatic Licensing of Downstream Recipients.
+
+  Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License.  You are not responsible
+for enforcing compliance by third parties with this License.
+
+  An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations.  If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+  You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License.  For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+  11. Patents.
+
+  A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based.  The
+work thus licensed is called the contributor's "contributor version".
+
+  A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version.  For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+  Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+  In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement).  To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+  If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients.  "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+  If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+  A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License.  You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+  Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+  12. No Surrender of Others' Freedom.
+
+  If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all.  For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+  13. Use with the GNU Affero General Public License.
+
+  Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work.  The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+  14. Revised Versions of this License.
+
+  The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+  Each version is given a distinguishing version number.  If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation.  If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+  If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+  Later license versions may give you additional or different
+permissions.  However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+  15. Disclaimer of Warranty.
+
+  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. Limitation of Liability.
+
+  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+  17. Interpretation of Sections 15 and 16.
+
+  If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+                     END OF TERMS AND CONDITIONS
+
+            How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+  If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+    <program>  Copyright (C) <year>  <name of author>
+    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+  You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+<http://www.gnu.org/licenses/>.
+
+  The GNU General Public License does not permit incorporating your program
+into proprietary programs.  If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library.  If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.  But first, please read
+<http://www.gnu.org/philosophy/why-not-lgpl.html>.
index eca5dc65ef5cdfa55a67948364d84a32337370c1..b09e69a80c82f185b5f98a2737cc320a4798e103 100644 (file)
@@ -19,4 +19,5 @@
 
 bin_PROGRAMS = zilasm
 
-zilasm_SOURCES = main.c
+zilasm_SOURCES = main.c opcodes.c symtable.c header.c parser.c directives.c labels.c zmem.c
+include_HEADERS =       opcodes.h symtable.h header.h parser.h directives.h labels.h zmem.h
index 569490359d175fb5d82c9b17d40c50d877086a60..7c07031282e1c5dbf1e1110a46657a087009e2d3 100644 (file)
 # along with this program.  If not, see <http://www.gnu.org/licenses/>
 #
 
-AC_PREREQ([2.69])
+AC_PREREQ([2.65])
 AC_INIT([zilasm], [0.1])
 AC_CONFIG_SRCDIR([main.c])
 AC_CONFIG_HEADERS([config.h])
 
-AM_INIT_AUTOMAKE(foreign)
+AM_INIT_AUTOMAKE
 AC_CONFIG_FILES([Makefile])
 
 # Checks for programs.
diff --git a/zilasm/directives.c b/zilasm/directives.c
new file mode 100644 (file)
index 0000000..46a0720
--- /dev/null
@@ -0,0 +1,193 @@
+/*
+ * directives.c -- part of ZilUtils/ZilAsm
+ *
+ * Copyright (C) 2016 Jason Self <j@jxself.org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+#include <stdlib.h>   /* bsearch */
+#include <string.h>   /* strcmp */
+
+#include "directives.h"
+
+#define ARRAY_SIZE(x)  ((sizeof(x)) / (sizeof(x[0])))
+
+static int byte_handler(const char *args)
+{
+       /* !!! TODO !!! */
+       return 0;
+}
+
+static int end_handler(const char *args)
+{
+       /* !!! TODO !!! */
+       return 0;
+}
+
+static int endi_handler(const char *args)
+{
+       /* !!! TODO !!! */
+       return 0;
+}
+
+static int endt_handler(const char *args)
+{
+       /* !!! TODO !!! */
+       return 0;
+}
+
+static int fstr_handler(const char *args)
+{
+       /* !!! TODO !!! */
+       return 0;
+}
+
+static int funct_handler(const char *args)
+{
+       /* !!! TODO !!! */
+       return 0;
+}
+
+static int gstr_handler(const char *args)
+{
+       /* !!! TODO !!! */
+       return 0;
+}
+
+static int gvar_handler(const char *args)
+{
+       /* !!! TODO !!! */
+       return 0;
+}
+
+static int insert_handler(const char *args)
+{
+       /* !!! TODO !!! */
+       return 0;
+}
+
+static int len_handler(const char *args)
+{
+       /* !!! TODO !!! */
+       return 0;
+}
+
+static int new_handler(const char *args)
+{
+       /* !!! TODO !!! */
+       return 0;
+}
+
+static int object_handler(const char *args)
+{
+       /* !!! TODO !!! */
+       return 0;
+}
+
+static int prop_handler(const char *args)
+{
+       /* !!! TODO !!! */
+       return 0;
+}
+
+static int str_handler(const char *args)
+{
+       /* !!! TODO !!! */
+       return 0;
+}
+
+static int strl_handler(const char *args)
+{
+       /* !!! TODO !!! */
+       return 0;
+}
+
+static int table_handler(const char *args)
+{
+       /* !!! TODO !!! */
+       return 0;
+}
+
+static int vocbeg_handler(const char *args)
+{
+       /* !!! TODO !!! */
+       return 0;
+}
+
+static int vocend_handler(const char *args)
+{
+       /* !!! TODO !!! */
+       return 0;
+}
+
+static int word_handler(const char *args)
+{
+       /* !!! TODO !!! */
+       return 0;
+}
+
+static int zword_handler(const char *args)
+{
+       /* !!! TODO !!! */
+       return 0;
+}
+
+// Sorted array
+static Directive Directives[] = {
+       "BYTE",      byte_handler,
+       "END",        end_handler,
+       "ENDI",      endi_handler,
+       "ENDT",      endt_handler,
+       "FSTR",      fstr_handler,
+       "FUNCT",    funct_handler,
+       "GSTR",      gstr_handler,
+       "GVAR",      gvar_handler,
+       "INSERT",  insert_handler,
+       "LEN",        len_handler,
+       "NEW",        new_handler,
+       "OBJECT",  object_handler,
+       "PROP",      prop_handler,
+       "STR",        str_handler,
+       "STRL",      strl_handler,
+       "TABLE",    table_handler,
+       "VOCBEG",  vocbeg_handler,
+       "VOCEND",  vocend_handler,
+       "WORD",      word_handler,
+       "ZWORD",    zword_handler
+};
+
+typedef struct {
+       const char *contents;
+       unsigned length;
+} Name;
+
+static int namecmp(const void *key, const void *elem)
+{
+       const Name      *p = (Name     *)key;
+       const Directive *d = (Directive*)elem;
+
+       int len1 = p->length;
+       int len2 = strlen(d->name);
+
+       int rc = memcmp(p->contents, elem, len1 < len2 ? len1 : len2);
+       return rc ? rc : (len1 - len2);
+}
+
+Directive_handler directive_lookup(const char *name, unsigned namelen)
+{
+       Name n = { name, namelen };
+       Directive *p = (Directive*)bsearch(&n, Directives, ARRAY_SIZE(Directives), sizeof(Directive), namecmp);
+       return p ? p->handler : NULL;
+}
diff --git a/zilasm/directives.h b/zilasm/directives.h
new file mode 100644 (file)
index 0000000..fc889d1
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * directives.h -- part of ZilUtils/ZilAsm
+ *
+ * Copyright (C) 2016 Jason Self <j@jxself.org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+#ifndef ZILASM_DIRECTIVES
+#define ZILASM_DIRECTIVES 1
+
+typedef int (*Directive_handler)(const char *directive_args);
+
+typedef struct {
+       const char        name[16];
+       Directive_handler handler;
+} Directive;
+
+Directive_handler directive_lookup(const char *name, unsigned namelen);
+
+#endif /* ifndef ZILASM_DIRECTIVES */
diff --git a/zilasm/header.c b/zilasm/header.c
new file mode 100644 (file)
index 0000000..8eb0c34
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * header.c -- part of ZilUtils/ZilAsm
+ *
+ * Copyright (C) 2016 Jason Self <j@jxself.org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+#include <string.h>  /* bzero */
+#include <assert.h>
+
+#include "header.h"
+
+Program_header_struct Program_header;
+
+const unsigned MAX_HEADER_LEN = 40;
+
+void program_header_reset(unsigned zversion)
+{
+       bzero(&Program_header, sizeof(Program_header));
+       Program_header.version = zversion;
+}
+
+ZMemblock *program_header_build(void)
+{
+       ZMemblock *zmb = zmem_init(MAX_HEADER_LEN);
+       zmem_putbyte(zmb, Program_header.version);
+       /* TODO */
+       return zmb;
+}
diff --git a/zilasm/header.h b/zilasm/header.h
new file mode 100644 (file)
index 0000000..542c064
--- /dev/null
@@ -0,0 +1,97 @@
+/*
+ * header.h -- part of ZilUtils/ZilAsm
+ *
+ * Copyright (C) 2016 Jason Self <j@jxself.org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+#ifndef ZILASM_HEADER
+#define ZILASM_HEADER 1
+
+#include "zmem.h"
+
+typedef unsigned long   Byte_address;
+typedef unsigned long   Word_address;
+typedef unsigned long Packed_address;
+typedef unsigned long        Offset8;
+typedef unsigned int            Word;
+typedef   signed char           Byte;
+typedef          int            Bool;
+
+typedef struct {
+       unsigned version;  // 1..6
+       // [$01] V1..V3: Flags1
+       Bool  statusline_type;      // bit1: 0=score/turns, 1=hh:mm
+       Bool  split_two_discs;      // bit2
+       Bool  statusline_notavail;  // bit4
+       Bool  screensplit_avail;    // bit5
+       Bool  varpitchfont_default; // bit6
+       // [$01] V4: Flags1
+       Bool  colors_avail;         // v5: bit0
+       Bool  pics_avail;           // v6: bit1
+       Bool  bold_avail;           // v4: bit2
+       Bool  italic_avail;         // v4: bit3
+       Bool  fixedspace_avail;     // v4: bit4
+       Bool  sound_avail;          // v6: bit5
+       Bool  timedkeyb_avail;      // v4: bit7
+       // Addresses
+       Byte_address   highmem_base;  // [$04]
+       Byte_address   start_pc;      //  [$06], v1
+       Packed_address start_routine; //  [$06], v6
+       Byte_address   dictionary;    // [$08]
+       Byte_address   objects;       // [$0A]
+       Byte_address   globals;       // [$0C]
+       Byte_address   static_base;   // [$0E]
+       // [$10] Flags2
+       Bool  transcript_on;        // v1: bit0
+       Bool  print_fixedfont;      // v3: bit1
+       Bool  request_redraw;       // v6: bit2
+       Bool  want_pics;            // v5: bit3
+       Bool  want_undo;            // v5: bit4
+       Bool  want_mouse;           // v5: bit5
+       Bool  want_colors;          // v5: bit6
+       Bool  want_sound;           // v5: bit7
+       Bool  want_menus;           // v5: bit8
+       //
+       Byte_address  abbrevs;        // [$18], v2
+       Word  file_length;            // [$1A], v3
+       Word  checksum;               // [$1C], v3
+       Byte  interpreter_number;     // [$1E], v4
+       Byte  interpreter_version;    // [$1F], v4
+       // Screen
+       Byte  screen_lines;           // [$20], v4 ($FF = infinite)
+       Byte  screen_chars;           // [$21], v4
+       Word  screen_width;           // [$22], v5
+       Word  screen_height;          // [$24], v5
+       Byte  font_width;             // [$26], v5/v6
+       Byte  font_height;            // [$27], v5/v6
+       // Tables
+       Offset8  routines;            // [$28], v6
+       Offset8  strings;             // [$2A], v6
+       Byte     backcolor;           // [$2C], v5
+       Byte     forecolor;           // [$2D], v5
+       Byte_address  term_chartable; // [$2E], v5
+       Word     width3;              // [$30], v6
+       Word     revnumber;           // [$32], v1
+       Byte_address  alphabet;       // [$34], v5
+       Byte_address  header_ext;     // [$36], v5
+} Program_header_struct;
+
+extern Program_header_struct Program_header;
+
+void program_header_reset(unsigned zversion);
+ZMemblock *program_header_build(void);
+
+#endif  /* ifndef ZILASM_HEADER */
diff --git a/zilasm/labels.c b/zilasm/labels.c
new file mode 100644 (file)
index 0000000..22715f6
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * labels.c -- part of ZilUtils/ZilAsm
+ *
+ * Copyright (C) 2016 Jason Self <j@jxself.org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+#include <assert.h>
+
+#include "labels.h"
+
+Symtable *Global_labels;
+Symtable  *Local_labels;
+
+const unsigned MAX_GLOBAL_LABELS = 1024;
+const unsigned MAX_LOCAL_LABELS  = 256;
+const unsigned MAX_LABEL_LEN     = 32;
+const unsigned ADDRESS_SIZE      = sizeof(long long);  /* TODO!!! */
+
+void init_local_labels(void)
+{
+       if (Local_labels)
+               symtable_destroy(Local_labels);
+       Local_labels = symtable_create(MAX_LOCAL_LABELS, MAX_LABEL_LEN, ADDRESS_SIZE);
+}
+
+void init_global_labels(void)
+{
+       assert(Global_labels);
+       Global_labels = symtable_create(MAX_GLOBAL_LABELS, MAX_LABEL_LEN, ADDRESS_SIZE);
+}
diff --git a/zilasm/labels.h b/zilasm/labels.h
new file mode 100644 (file)
index 0000000..19bd95e
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * labels.h -- part of ZilUtils/ZilAsm
+ *
+ * Copyright (C) 2016 Jason Self <j@jxself.org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+#ifndef ZILASM_LABELS
+#define ZILASM_LABELS 1
+
+#include "symtable.h"
+
+extern Symtable *Global_labels;
+extern Symtable  *Local_labels;
+
+extern void init_local_labels(void);
+extern void init_global_labels(void);
+
+#endif /* ifndef ZILASM_LABELS */
index 5dbd24020e15bcf663f48b0f5eaea3e57c45d1eb..38d6ec9eb27ef5bd5755a5f31fa507cf048e6e0a 100644 (file)
@@ -36,223 +36,199 @@ enum { FAIL = -1, OK = 0, NEED_RESTART = 1 };
 
 static struct option const long_options[] =
 {
-    { "help",     no_argument,       NULL, 'h' },
-    { "version",  no_argument,       NULL, 'V' },
-    { "output",   required_argument, NULL, 'o' },
-    { "zversion", required_argument, NULL, ZVERSION },
-    { "zorkid",   required_argument, NULL, ZORKID   },
-    { "serial",   required_argument, NULL, ZSERIAL  },
-    { NULL, 0, NULL, 0 }
+       { "help",     no_argument,       NULL, 'h' },
+       { "version",  no_argument,       NULL, 'V' },
+       { "output",   required_argument, NULL, 'o' },
+       { "zversion", required_argument, NULL, ZVERSION },
+       { "zorkid",   required_argument, NULL, ZORKID   },
+       { "serial",   required_argument, NULL, ZSERIAL  },
+       { NULL, 0, NULL, 0 }
 };
 
-typedef struct
-{
-    int todo;
+typedef struct {
+       int todo;
 } Opcode_dict;
 
 struct
 {
-    int  zversion;     /* 0 - 8     */
-    int  zorkid;       /* 0 - 65535 */
-    char zserial[7];   /* YYMMDD    */
-    Opcode_dict *opcode_dict;
+       int  zversion;     /* 0 - 8     */
+       int  zorkid;       /* 0 - 65535 */
+       char zserial[7];   /* YYMMDD    */
+       Opcode_dict *opcode_dict;
 } Config;
 
 void wrong_arg(const char *err, ...)
 {
-    if (err)
-    {
-        va_list ap;
-        va_start(ap, err);
-        vfprintf(stderr, err, ap);
-        va_end(ap);
-    }
-    fprintf(stderr, "Try `" PACKAGE_NAME " --help' for more information.\n");
-    exit(1);
+       if (err) {
+               va_list ap;
+               va_start(ap, err);
+               vfprintf(stderr, err, ap);
+               va_end(ap);
+       }
+       fprintf(stderr, "Try `" PACKAGE_NAME " --help' for more information.\n");
+       exit(1);
 }
 
 void print_version()
 {
-    printf( PACKAGE_STRING "\n"
-            "License AGPLv3+: GNU AGPL version 3 or later\n"
-            "<http://gnu.org/licenses/agpl.html>\n"
-            "This is free software: you are free to change and redistribute it.\n"
-            "There is NO WARRANTY, to the extent permitted by law.\n"
-          );
-    exit(0);
+       printf( PACKAGE_STRING "\n"
+              "License AGPLv3+: GNU AGPL version 3 or later\n"
+              "<http://gnu.org/licenses/agpl.html>\n"
+              "This is free software: you are free to change and redistribute it.\n"
+              "There is NO WARRANTY, to the extent permitted by law.\n"
+       );
+       exit(0);
 }
 
 void print_usage(int failed)
 {
-    printf("Usage: " PACKAGE_NAME " [OPTION...] [FILES...]\n"
-           "\n"
-           "--version  Display program version and exit\n"
-           "--help     Display this help\n"
-           "\n"
-           "--zversion (accepts numbers 1 - 8, defaults to %d if not specified)\n"
-           "--zorkid   (integer between 0 and 65535, defaults to 0 if not specified)\n"
-           "--serial   (six characters of ASCII, defaults to current date\n"
-           "            in the form YYMMDD if not specified)\n",
-           DEFAULT_ZVERSION
-          );
-    exit(failed);
+       printf("Usage: " PACKAGE_NAME " [OPTION...] [FILES...]\n"
+              "\n"
+              "--version  Display program version and exit\n"
+              "--help     Display this help\n"
+              "\n"
+              "--zversion (accepts numbers 1 - 8, defaults to %d if not specified)\n"
+              "--zorkid   (integer between 0 and 65535, defaults to 0 if not specified)\n"
+              "--serial   (six characters of ASCII, defaults to current date\n"
+              "            in the form YYMMDD if not specified)\n",
+              DEFAULT_ZVERSION
+       );
+       exit(failed);
 }
 
 void fill_zserial(void)
 {
-    time_t t;
-    struct tm *timeinfo;
-    time (&t);
-    timeinfo = localtime(&t);
-    strftime (Config.zserial, sizeof(Config.zserial), "%y%m%d", timeinfo);
+       time_t t;
+       struct tm *timeinfo;
+       time (&t);
+       timeinfo = localtime(&t);
+       strftime (Config.zserial, sizeof(Config.zserial), "%y%m%d", timeinfo);
 }
 
 void fill_config(void)
 {
-    bzero(&Config, sizeof(Config));
-    Config.zversion = DEFAULT_ZVERSION;
-    fill_zserial();
+       bzero(&Config, sizeof(Config));
+       Config.zversion = DEFAULT_ZVERSION;
+       fill_zserial();
 }
 
 void parse_intarg(int *dest, const char name[], int min, int max, int defval)
 {
-    if (!optarg)
-    {
-        *dest = defval;
-        return;
-    }
-    int n = atoi(optarg);
-    if (n >= min && n <= max)
-    {
-        *dest = n;
-        return;
-    }
-    wrong_arg("Wrong %s value %s, must be integer between %d and %d\n",
-              name, optarg, min, max);
+       if (!optarg) {
+               *dest = defval;
+               return;
+       }
+       int n = atoi(optarg);
+       if (n >= min && n <= max) {
+               *dest = n;
+               return;
+       }
+       wrong_arg("Wrong %s value %s, must be integer between %d and %d\n",
+               name, optarg, min, max);
 }
 
 void parse_zserial(void)
 {
-    if (!optarg)
-    {
-        fill_zserial();
-        return;
-    }
-    size_t n = strlen(optarg);
-    if (n == sizeof(Config.zserial) - 1)
-    {
-        char *p = optarg;
-        while (*p && isalnum(*p))
-            p++;
-        if (!*p)      /* ..optarg contains alphanumeric only? */
-        {
-            strncpy(Config.zserial, optarg, sizeof(Config.zserial));
-            return;
-        }
-    }
-    wrong_arg("Wrong zserial value %s, must be 6 ascii characters\n", optarg);
+       if (!optarg) {
+               fill_zserial();
+               return;
+       }
+       size_t n = strlen(optarg);
+       if (n == sizeof(Config.zserial) - 1) {
+               char *p = optarg;
+               while (*p && isalnum(*p))
+                       p++;
+               if (!*p) {    /* ..optarg contains alphanumeric only? */
+                       strncpy(Config.zserial, optarg, sizeof(Config.zserial));
+                       return;
+               }
+       }
+       wrong_arg("Wrong zserial value %s, must be 6 ascii characters\n", optarg);
 }
 
 void new_file_suffix(char *result, size_t maxlen, const char *src, const char *newsuffix)
 {
-    strncpy(result, src, maxlen);
-    char *p = strrchr(result, '.');
-    if (p && strchr(p, '/'))
-        p = NULL;
-    if (p)
-    {
-        strncpy(p, newsuffix, maxlen - (p - result));
-    }
-    else
-    {
-        strncat(result, newsuffix, maxlen);
-    }
-    result[maxlen] = 0;
+       strncpy(result, src, maxlen);
+       char *p = strrchr(result, '.');
+       if (p && strchr(p, '/'))
+               p = NULL;
+       if (p) {
+               strncpy(p, newsuffix, maxlen - (p - result));
+       } else {
+               strncat(result, newsuffix, maxlen);
+       }
+       result[maxlen] = 0;
 }
 
 char *build_output_filename(const char basename[], const char *suffix)
 {
-    int n = strlen(basename) + strlen(suffix);
-    char *ofile = malloc(n + 1);  /* todo!!! check for NULL. free. */
-    new_file_suffix(ofile, n, basename, suffix);
-    return ofile;
-}
-
-void build_opcode_dict(void)
-{
-    /* TODO */
+       int n = strlen(basename) + strlen(suffix);
+       char *ofile = malloc(n + 1);  /* todo!!! check for NULL. free. */
+       new_file_suffix(ofile, n, basename, suffix);
+       return ofile;
 }
 
 int init_assembly(void)
 {
-    /* TODO */
-    return OK;
+       /* TODO */
+       return OK;
 }
 
 int assembly(void)
 {
-    /* TODO */
-    return OK;
+       /* TODO */
+       return OK;
 }
 
 int main(int argc, char *argv[], char *envp[])
 {
-    const char *output_file = NULL;
-    int i;
+       const char *output_file = NULL;
+       int i;
+
+       fill_config();
 
-    fill_config();
+       int opt = 0;
+       while ((opt = getopt_long (argc, argv, "hVo:", long_options, NULL)) != -1) {
+               switch(opt) {
+               case 'h'     : print_usage(0);
+               case 'V'     : print_version();
+               case 'o'     : if (output_file) wrong_arg("Output file must be given once\n");
+                              output_file = optarg;
+                              break;
+               case ZVERSION: parse_intarg(&Config.zversion, "zversion", 1, 8,      1); break;
+               case ZORKID  : parse_intarg(&Config.zorkid,   "zorkid",   0, 0xFFFF, 0); break;
+               case ZSERIAL : parse_zserial();                                          break;
+               default      : wrong_arg(0);
+               }
+       }
 
-    int opt = 0;
-    while ((opt = getopt_long (argc, argv, "hVo:", long_options, NULL)) != -1)
-    {
-        switch(opt)
-        {
-        case 'h'     :
-            print_usage(0);
-        case 'V'     :
-            print_version();
-        case 'o'     :
-            if (output_file) wrong_arg("Output file must be given once\n");
-            output_file = optarg;
-            break;
-        case ZVERSION:
-            parse_intarg(&Config.zversion, "zversion", 1, 8,      1);
-            break;
-        case ZORKID  :
-            parse_intarg(&Config.zorkid,   "zorkid",   0, 0xFFFF, 0);
-            break;
-        case ZSERIAL :
-            parse_zserial();
-            break;
-        default      :
-            wrong_arg(0);
-        }
-    }
+       int first_input_file = optind;
+       if (first_input_file >= argc)
+               wrong_arg("Missing input file\n");
+       if (!output_file)
+               output_file = build_output_filename(argv[first_input_file], ".dat");
 
-    int first_input_file = optind;
-    if (first_input_file >= argc)
-        wrong_arg("Missing input file\n");
-    if (!output_file)
-        output_file = build_output_filename(argv[first_input_file], ".dat");
+       // TODO: Everything :)
 
-    // TODO: Everything :)
+       printf("Input files:\n");
+       for (i = optind; i < argc; i++)
+               printf("\t%s\n", argv[i]);
 
-    printf("Input files:\n");
-    for (i = optind; i < argc; i++)
-        printf("\t%s\n", argv[i]);
+       printf("Output file: %s\n\n", output_file);
 
-    printf("Output file: %s\n\n", output_file);
+       printf("Config:\n"
+              "- ZVersion: %d\n"
+              "- ZorkID:   %d\n"
+              "- ZSerial:  %s\n",
+              Config.zversion, Config.zorkid, Config.zserial
+       );
 
-    printf("Config:\n"
-           "- ZVersion: %d\n"
-           "- ZorkID:   %d\n"
-           "- ZSerial:  %s\n",
-           Config.zversion, Config.zorkid, Config.zserial
-          );
+       init_opcodes(Config.zversion, 0);
 
-    build_opcode_dict();  /* ..fills Config.opcode_dict */
+       while(init_assembly() == OK && assembly() == NEED_RESTART);
 
-    while(init_assembly() == OK && assembly() == NEED_RESTART);
+       /* TODO! List global symbols */
+       /* TODO! Find abbreviations */
 
-    return 0;
+       return 0;
 }
diff --git a/zilasm/opcodes.c b/zilasm/opcodes.c
new file mode 100644 (file)
index 0000000..5478891
--- /dev/null
@@ -0,0 +1,185 @@
+/*
+ * opcodes.c -- part of ZilUtils/ZilAsm
+ *
+ * Copyright (C) 2016 Jason Self <j@jxself.org>
+ *
+ * Based on ZILF (c) 2010, 2015 Jesse McGrew
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+#include <assert.h>
+
+#include "opcodes.h"
+
+typedef struct {
+       unsigned opcode;
+       const char *classic_name;
+       const char *inform_name;
+       int minver;
+       int maxver;
+       ZOpcode_flags flags;
+} Opcode_detailed_info;
+
+static Opcode_detailed_info detailed_opcodes[] = {
+       { 20,  "ADD",         "add",             1, 6, Zop_store   },              // Add
+       { 259, "ASHIFT",      "art_shift",       5, 6, Zop_store   },              // Ashift
+       { 255, "ASSIGNED?",   "check_arg_count", 5, 6, Zop_branch | Zop_indvar },  // Assigned_P
+       { 9,   "BAND",        "and",             1, 6, Zop_store   },              // Band
+       { 143, "BCOM",        "not",             1, 4, Zop_store   },              // Bcom_V1
+       { 248, "BCOM",        "not",             5, 6, Zop_store   },              // Bcom_V5
+       { 8,   "BOR",         "or",              1, 6, Zop_store   },              // Bor
+       { 7,   "BTST",        "test",            1, 6, Zop_branch  },              // Btst
+       { 242, "BUFOUT",      "buffer_mode",     4, 6, 0           },              // Bufout
+       { 224, "CALL",        "call_vs",         1, 6, Zop_store | Zop_call },     // Call
+       { 136, "CALL1",       "call_1s",         4, 6, Zop_store | Zop_call },     // Call1
+       { 25,  "CALL2",       "call_2s",         4, 6, Zop_store | Zop_call },     // Call2
+       { 185, "CATCH",       "catch",           5, 6, Zop_store   },              // Catch
+       { 268, "CHECKU",      "check_unicode",   5, 6, Zop_store   },              // Checku
+       { 237, "CLEAR",       "erase_window",    4, 6, 0           },              // Clear
+       { 27,  "COLOR",       "set_colour",      5, 5, 0           },              // Color_v5
+       { 27,  "COLOR",       "set_colour",      6, 6, Zop_varargs },              // Color_v6
+       { 253, "COPYT",       "copy_table",      5, 6, 0           },              // Copyt
+       { 187, "CRLF",        "new_line",        1, 6, 0           },              // Crlf
+       { 240, "CURGET",      "get_cursor",      4, 6, 0           },              // Curget
+       { 239, "CURSET",      "set_cursor",      4, 6, 0           },              // Curset
+       { 263, "DCLEAR",      "erase_picture",   6, 6, 0           },              // Dclear
+       { 134, "DEC",         "dec",             1, 6, Zop_indvar  },              // Dec
+       { 244, "DIRIN",       "input_stream",    3, 6, 0           },              // Dir-In
+       { 243, "DIROUT",      "output_stream",   3, 6, 0           },              // Dir-Out
+       { 261, "DISPLAY",     "draw_picture",    6, 6, 0           },              // Display
+       { 23,  "DIV",         "div",             1, 6, Zop_store   },              // Div
+       { 4,   "DLESS?",      "dec_chk",         1, 6, Zop_branch | Zop_indvar },  // Dless_P
+//     { 271, "ENDMOVE",     "ENDMOVE",         5, 6, Zop_store   },              // Endmove = 271
+       { 1,   "EQUAL?",      "jeq",             1, 6, Zop_branch | Zop_varargs }, // Equal_P
+       { 238, "ERASE",       "erase_line",      4, 6, 0           },              // Erase
+       { 12,  "FCLEAR",      "clear_attr",      1, 6, 0           },              // Fclear
+       { 130, "FIRST?",      "get_child",       1, 6, Zop_store | Zop_branch },   // First_P
+       { 260, "FONT",        "set_font",        5, 6, Zop_store   },              // Font
+       { 11,  "FSET",        "set_attr",        1, 6, 0           },              // Fset
+       { 10,  "FSET?",       "test_attr",       1, 6, Zop_branch  },              // Fset_P
+       { 185, "FSTACK",      "pop",             1, 4, 0           },              // Fstack_V1
+       { 277, "FSTACK",      "pop_stack",       6, 6, 0           },              // Fstack_V6
+       { 15,  "GET",         "loadw",           1, 6, Zop_store   },              // Get
+       { 16,  "GETB",        "loadb",           1, 6, Zop_store   },              // Getb
+       { 17,  "GETP",        "get_prop",        1, 6, Zop_store   },              // Getp
+       { 18,  "GETPT",       "get_prop_addr",   1, 6, Zop_store   },              // Getpt
+       { 3,   "GRTR?",       "jg",              1, 6, Zop_branch  },              // Grtr_P
+       { 241, "HLIGHT",      "set_text_style",  4, 6, 0           },              // Hlight
+       { 249, "ICALL",       "call_vn",         5, 6, Zop_call    },              // Icall
+       { 143, "ICALL1",      "call_1n",         5, 6, Zop_call    },              // Icall1
+       { 26,  "ICALL2",      "call_2n",         5, 6, Zop_call    },              // Icall2
+       { 5,   "IGRTR?",      "inc_chk",         1, 6, Zop_branch | Zop_indvar },  // Igrtr_P
+       { 6,   "IN?",         "jin",             1, 6, Zop_branch  },              // In_P
+       { 133, "INC",         "inc",             1, 6, Zop_indvar  },              // Inc
+       { 246, "INPUT",       "read_char",       4, 6, Zop_store   },              // Input
+       { 247, "INTBL?",      "scan_table",      4, 6, Zop_store | Zop_branch },   // Intbl_P
+       { 266, "IRESTORE",    "restore_undo",    5, 6, Zop_store   },              // Irestore
+       { 265, "ISAVE",       "save_undo",       5, 6, Zop_store   },              // Isave
+       { 250, "IXCALL",      "call_vn2",        5, 6, Zop_extra | Zop_call },     // Ixcall
+       { 140, "JUMP",        "jump",            1, 6, Zop_label | Zop_term },     // Jump
+       { 2,   "LESS?",       "jl",              1, 6, Zop_branch  },              // Less_P
+       { 251, "LEX",         "tokenise",        5, 6, 0           },              // Lex
+       { 131, "LOC",         "get_parent",      1, 6, Zop_store   },              // Loc
+       { 264, "MARGIN",      "set_margins",     6, 6, 0           },              // Margin
+       { 283, "MENU",        "make_menu",       6, 6, Zop_branch  },              // Menu
+       { 24,  "MOD",         "mod",             1, 6, Zop_store   },              // Mod
+       { 278, "MOUSE-INFO",  "read_mouse",      6, 6, 0           },              // MouseInfo
+       { 279, "MOUSE-LIMIT", "mouse_window",    6, 6, 0           },              // MouseLimit
+       { 14,  "MOVE",        "insert_obj",      1, 6, 0           },              // Move
+       { 22,  "MUL",         "mul",             1, 6, Zop_store   },              // Mul
+       { 129, "NEXT?",       "get_sibling",     1, 6, Zop_store | Zop_branch },   // Next_P
+       { 19,  "NEXTP",       "get_next_prop",   1, 6, Zop_store   },              // Nextp
+       { 180, "NOOP",        "nop",             1, 6, 0           },              // Noop
+       { 191, "ORIGINAL?",   "piracy",          5, 6, Zop_branch  },              // Original_P
+       { 262, "PICINF",      "picture_data",    6, 6, Zop_branch  },              // Picinf
+       { 284, "PICSET",      "picture_table",   6, 6, 0           },              // Picset
+       { 233, "POP",         "pull",            1, 5, 0           },              // Pop_v1
+       { 233, "POP",         "pull",            6, 6, Zop_store   },              // Pop_v6
+       { 141, "PRINT",       "print_paddr",     1, 6, 0           },              // Print
+       { 135, "PRINTB",      "print_addr",      1, 6, 0           },              // Printb
+       { 229, "PRINTC",      "print_char",      1, 6, 0           },              // Printc
+       { 138, "PRINTD",      "print_obj",       1, 6, 0           },              // Printd
+       { 282, "PRINTF",      "print_form",      6, 6, 0           },              // Printf
+       { 178, "PRINTI",      "print",           1, 6, Zop_string  },              // Printi
+//     { 267, "PRINTMOVE",   "PRINTMOVE",       5, 6, Zop_store   },              // Printmove
+       { 230, "PRINTN",      "print_num",       1, 6, 0           },              // Printn
+       { 179, "PRINTR",      "print_ret",       1, 6, Zop_string | Zop_term },    // Printr
+       { 254, "PRINTT",      "print_table",     5, 6, 0           },              // Printt
+       { 267, "PRINTU",      "print_unicode",   5, 6, 0           },              // Printu
+       { 132, "PTSIZE",      "get_prop_len",    1, 6, Zop_store   },              // Ptsize
+       { 232, "PUSH",        "push",            1, 6, 0           },              // Push
+       { 225, "PUT",         "storew",          1, 6, 0           },              // Put
+       { 226, "PUTB",        "storeb",          1, 6, 0           },              // Putb
+       { 227, "PUTP",        "put_prop",        1, 6, 0           },              // Putp
+       { 186, "QUIT",        "quit",            1, 6, Zop_term    },              // Quit
+       { 231, "RANDOM",      "random",          1, 6, Zop_store   },              // Random
+       { 228, "READ",        "sread",           1, 4, 0           },              // Read_v1
+       { 228, "READ",        "aread",           5, 6, Zop_store   },              // Read_v5
+       { 137, "REMOVE",      "remove_obj",      1, 6, 0           },              // Remove
+       { 183, "RESTART",     "restart",         1, 6, Zop_term    },              // Restart
+       { 182, "RESTORE",     "restore",         1, 3, Zop_branch  },              // Restore_v1
+       { 182, "RESTORE",     "restore",         4, 4, Zop_store   },              // Restore_v4
+       { 257, "RESTORE",     "restore",         5, 6, Zop_store   },              // Restore_V5
+       { 139, "RETURN",      "ret",             1, 6, Zop_term    },              // Return
+       { 177, "RFALSE",      "rfalse",          1, 6, Zop_term    },              // Rfalse
+       { 184, "RSTACK",      "ret_popped",      1, 6, Zop_term    },              // Rstack
+//     { 268, "RTIME",       "RTIME",           5, 6, Zop_store   },              // Rtime
+       { 176, "RTRUE",       "rtrue",           1, 6, Zop_term    },              // Rtrue
+       { 181, "SAVE",        "save",            1, 3, Zop_branch  },              // Save_v1
+       { 181, "SAVE",        "save",            4, 4, Zop_store   },              // Save_v4
+       { 256, "SAVE",        "save",            5, 6, Zop_store   },              // Save_V5
+       { 235, "SCREEN",      "set_window",      3, 6, 0           },              // Screen
+       { 276, "SCROLL",      "scroll_window",   6, 6, 0           },              // Scroll
+//     { 269, "SEND",        "SEND",            5, 6, Zop_store   },              // Send
+       { 270, "SERVER",      "SERVER",          5, 6, Zop_store   },              // Server
+       { 13,  "SET",         "store",           1, 6, Zop_indvar  },              // Set
+       { 258, "SHIFT",       "log_shift",       5, 6, Zop_store   },              // Shift
+       { 245, "SOUND",       "sound_effect",    3, 6, 0           },              // Sound
+       { 234, "SPLIT",       "split_window",    3, 6, 0           },              // Split
+       { 21,  "SUB",         "sub",             1, 6, Zop_store   },              // Sub
+       { 28,  "THROW",       "throw",           5, 6, Zop_term    },              // Throw
+       { 188, "USL",         "show_status",     1, 3, 0           },              // Usl
+       { 142, "VALUE",       "load",            1, 6, Zop_store | Zop_indvar },   // Value
+       { 189, "VERIFY",      "verify",          3, 6, Zop_branch  },              // Verify
+       { 274, "WINATTR",     "window_style",    6, 6, 0           },              // Winattr
+       { 275, "WINGET",      "get_wind_prop",   6, 6, Zop_store   },              // Winget
+       { 272, "WINPOS",      "move_window",     6, 6, 0           },              // Winpos
+       { 281, "WINPUT",      "put_wind_prop",   6, 6, 0           },              // Winput
+       { 273, "WINSIZE",     "window_size",     6, 6, 0           },              // Winsize
+       { 236, "XCALL",       "call_vs2",        4, 6, Zop_store | Zop_extra | Zop_call }, // Xcall
+       { 280, "XPUSH",       "push_stack",      6, 6, Zop_branch  },              // Xpush
+       { 128, "ZERO?",       "jz",              1, 6, Zop_branch  },              // Zero_P
+       { 252, "ZWSTR",       "encode_text",     5, 6, 0           }               // Zwstr
+};
+
+Symtable *Opcodes;
+
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
+
+void init_opcodes(int version, int inform_syntax)
+{
+       const unsigned maxnamelen = 16;
+       int n;
+       if (Opcodes) symtable_destroy(Opcodes); 
+       Opcodes = symtable_create(2 * ARRAY_SIZE(detailed_opcodes), maxnamelen, sizeof(ZOpcode));
+       assert(Opcodes);
+       for(n = 0; n < ARRAY_SIZE(detailed_opcodes); n++) {
+               Opcode_detailed_info *p = &detailed_opcodes[n];
+               if (version < p->minver) continue;
+               if (version > p->maxver) continue;
+               ZOpcode q = { p->opcode, p->flags };
+               symtable_add(Opcodes, inform_syntax ? p->inform_name : p->classic_name, &q);
+       }
+}
diff --git a/zilasm/opcodes.h b/zilasm/opcodes.h
new file mode 100644 (file)
index 0000000..bddcb0d
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * opcodes.h -- part of ZilUtils/ZilAsm
+ *
+ * Copyright (C) 2016 Jason Self <j@jxself.org>
+ *
+ * Based on ZILF (c) 2010, 2015 Jesse McGrew
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+#ifndef ZILASM_OPCODES
+#define ZILASM_OPCODES 1
+
+#include "symtable.h"
+
+typedef enum {
+       Zop_none    =   0,
+       Zop_store   =   1,   // ..stores a result
+       Zop_branch  =   2,   // ..branches to a label
+       Zop_extra   =   4,   // ..takes an extra operand type byte, for a total of 8 possible operands
+       Zop_varargs =   8,   // ..is nominally 2OP but can take up to 4 operands
+       Zop_string  =  16,   // ..has a string literal operand
+       Zop_label   =  32,   // ..can take a local label operand
+       Zop_indvar  =  64,   // ..first operand is an indirect variable number
+       Zop_call    = 128,   // ..first operand is a packed routine address
+       Zop_term    = 256    // ..control flow does not pass to the following instruction
+} ZOpcode_flags;
+
+typedef struct {
+       unsigned opcode;
+       ZOpcode_flags flags;
+} ZOpcode;
+
+extern Symtable *Opcodes;
+
+void init_opcodes(int version, int inform_syntax);
+
+#endif  /* ifndef ZILASM_OPCODES */
diff --git a/zilasm/parser.c b/zilasm/parser.c
new file mode 100644 (file)
index 0000000..7f8af7e
--- /dev/null
@@ -0,0 +1,171 @@
+/*
+ * parser.c -- part of ZilUtils/ZilAsm
+ *
+ * Copyright (C) 2016 Jason Self <j@jxself.org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+#include <stdio.h>   /* fopen, fgets */
+#include <string.h>  /* strlen */
+
+#include "parser.h"
+#include "directives.h"
+#include "opcodes.h"
+#include "labels.h"
+
+#define iscomment(c)   ((c) == '#')
+#define isbindigit(c)  ((c) == '0' || (c) == '1')
+
+/* !!! TODO !!! */
+#define fatal_error(errmsg)
+#define PC NULL
+
+void checksep(const char *p)
+{
+       if (!*p || iscomment(*p) || isspace(*p)) return;
+       fatal_error("wrong chars");
+}
+
+const char *pass_spaces(const char *p)
+{
+       while(p && isspace(*p)) p++;
+       return (p && *p) ? p : NULL;
+}
+
+const char *pass_alnums(const char *p)
+{
+       while(p && isalnum(*p)) p++;
+       return (p && *p) ? p : NULL;
+}
+
+int tryparse_directive(const char *p)
+{
+       if (*p != '.')
+               return 0;
+       const char *a = p+1;
+       const char *b = pass_alnums(a);
+       checksep(b);
+       Directive_handler f = directive_lookup(a, b - a);
+       if (!f) return 0;
+       return (*f)(b);
+}
+
+int tryparse_assignment(const char *a, const char *b, const char *c)
+{
+       return 0;
+}
+
+int tryparse_label(const char *a, const char *b, const char *c)
+{
+       if (*(c+1) != ':') {
+               symtable_add2(Local_labels, a, b - a, PC);
+       } else if (*(c+2) != ':') {
+               symtable_add2(Global_labels, a, b - a, PC);
+       } else {
+               fatal_error("wrong label type");
+       }
+
+       while (*c++ == ':');
+       if (*c && ((c = pass_spaces(c)) != NULL) && *c)
+               return tryparse_instruction(c);
+       return 1;
+}
+
+int tryparse_name(const char *a)
+{
+       const char *b = pass_alnums(a);
+       const char *c = pass_spaces(b);
+
+       if (!c)        return 0;
+       if (*c == '=') return tryparse_assignment(a, b, c + 1);
+       if (*c == ':') return tryparse_label(a, b, c);
+       return 0;
+}
+
+int tryparse_instruction(const char *a)
+{
+       const char *b = pass_alnums(a);
+       ZOpcode *op = symtable_lookup2(Opcodes, a, b - a);
+       if (!op) return 0;
+       ZOpcode_flags flags = op->flags;
+       /* !!! TODO !!! */
+       return 0;
+}
+
+/*
+ *  Line can be one from: Comment, Global label, Local label, Directive, Name=Value, Instruction
+ */
+int parse_line(const char *p)
+{
+       for (; *p; p++) {
+               char c = *p;
+               int n;
+               if (isspace(c))                  continue;
+               if (iscomment(c))                return 0;
+               if (n = tryparse_directive(p))   return n;
+               if (n = tryparse_name(p))        return n;  // ..label or assignment
+               if (n = tryparse_instruction(p)) return n;
+               fatal_error("wrong line");
+       }
+       return 0;
+}
+
+int parse_file(const char *filename)
+{
+       FILE *fp = fopen(filename, "r");
+       if (!fp) fatal_error("wrong file");
+
+       const int MAX_LINESIZE = 1024;
+       char line[MAX_LINESIZE];
+       int newline_missing = 0;
+
+       while (fgets(line, MAX_LINESIZE, fp)) {
+               if (newline_missing) fatal_error("line too long");
+
+               int n = strlen(line);
+               if (!n) continue;
+
+               parse_line(line);
+
+               newline_missing = (line[n-1] != '\n');
+       }
+
+       close(fp);
+}
+
+/*
+
+line_passed() {
+    skip_spaces();
+    return (current_token == LINE_END || current_token == LINE_COMMENT);
+}
+
+if (line_passed()) continue;
+if (current_token == DIRECTIVE) {
+    if (!try_next_token(NAME))
+        fatal_error("directive contains incorrect chars")
+    handler = get_directive_handler(current_token);
+    if (!handler)
+        fatal error("unknown directive");
+    (*handler)(remaining_line);
+    if (line_passed()) continue;
+    fatal_error("unexpected line tail");
+} else if (current_token == NAME) {
+    skip_spaces();
+    if (current_token == ASSIGNMENT)
+}
+    
+
+*/
diff --git a/zilasm/parser.h b/zilasm/parser.h
new file mode 100644 (file)
index 0000000..ef4bee2
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * parser.h -- part of ZilUtils/ZilAsm
+ *
+ * Copyright (C) 2016 Jason Self <j@jxself.org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+#ifndef ZILASM_PARSER
+#define ZILASM_PARSER 1
+
+int parse_file(const char *filename);
+
+#endif  /* ifndef ZILASM_PARSER */
diff --git a/zilasm/symtable.c b/zilasm/symtable.c
new file mode 100644 (file)
index 0000000..d1dd902
--- /dev/null
@@ -0,0 +1,144 @@
+/*
+ * symtable.c -- part of ZilUtils/ZilAsm
+ *
+ * Copyright (C) 2016 Jason Self <j@jxself.org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+#include <string.h>
+#include <stdlib.h>
+#include <assert.h>
+
+#include "symtable.h"
+
+#define FIELD_SIZE(Typ,Field)  (sizeof(((Typ*)0)->Field))
+
+Symtable* symtable_create(unsigned elems_count, unsigned name_size, unsigned elem_size)
+{
+       size_t n = elems_count * (name_size + elem_size) + sizeof(Symtable) - FIELD_SIZE(Symtable, contents);
+       Symtable *p = malloc(n);
+       assert(p);
+       bzero(p, n);
+       p->elems_count = elems_count;
+       p->name_size   = name_size;
+       p->elem_size   = elem_size;
+       return p;
+}
+
+void symtable_destroy(Symtable *p)
+{
+       assert(p);
+       free(p);
+}
+
+static unsigned name2pos(const Symtable *p, const char *name, unsigned namelen)
+{
+       assert(p);
+       unsigned key = 0;
+       while(namelen--)
+               key = ((key << 1) | (*name++));
+       return key % p->elems_count;
+}
+
+static char *getsym(const Symtable *p, unsigned pos)
+{
+       //assert(p);   //already checked by caller
+       //assert(pos < p->elems_count);
+       return ((char*)p) + sizeof(Symtable) - FIELD_SIZE(Symtable, contents) + (pos * p->elem_size);
+}
+
+void* symtable_lookup2(const Symtable *p, const char *name, unsigned namelen)
+{
+       assert(p);
+       assert(name);
+       assert(namelen > 0);
+       assert(namelen < p->name_size);
+
+       unsigned start = name2pos(p, name, namelen);
+       unsigned pos = start;
+
+       do {
+               char *s = getsym(p, pos);
+               if (!*s)
+                       return NULL;
+               if (!memcmp(name, s, namelen))
+                       return s + p->name_size;
+               if (++pos >= p->elems_count)
+                       pos = 0;
+       } while(pos != start);
+
+       return NULL;
+}
+
+void* symtable_lookup(const Symtable *p, const char *name)
+{
+       assert(name);
+       return symtable_lookup2(p, name, strlen(name));
+}
+
+void* symtable_add(Symtable *p, const char *name, void *contents)
+{
+       assert(name);
+       return symtable_add2(p, name, strlen(name), contents);
+}
+
+void* symtable_add2(Symtable *p, const char *name, unsigned namelen, void *contents)
+{
+       assert(p);
+       assert(name);
+       assert(namelen > 0 && namelen < p->name_size);
+       assert(contents);
+
+       unsigned start = name2pos(p, name, namelen);
+       unsigned pos = start;
+
+       do {
+               char *s = getsym(p, pos);
+               if (!*s) {
+                       memcpy(s, name, namelen + 1);
+                       s[namelen] = '\0';
+                       memcpy(s + p->name_size, contents, p->elem_size);
+                       return s + p->name_size;
+               }
+               if (!memcmp(name, s, namelen) && s[namelen] == '\0') {
+                       /* TODO!! report error */
+                       return NULL;  /* ..already added */
+               }
+               if (++pos >= p->elems_count)
+                       pos = 0;
+       } while(pos != start);
+
+       /* TODO!! report overflow */
+       return NULL;
+       /* TODO!!! */
+}
+
+static int sortfunc(const void *a, const void *b)
+{
+       const char *s1 = a;
+       const char *s2 = b;
+       if (!*s1 && !*s2) return  0;
+       if (!*s1)         return  1;
+       if (!*s2)         return -1;
+       return strcmp(s1, s2);
+}
+
+void symtable_sort(Symtable *p)
+{
+       assert(p);
+       qsort(getsym(p, 0), p->elems_count, p->elem_size + p->name_size, sortfunc);
+}
+
+/* END */
diff --git a/zilasm/symtable.h b/zilasm/symtable.h
new file mode 100644 (file)
index 0000000..aa72b0e
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * symtable.h -- part of ZilUtils/ZilAsm
+ *
+ * Copyright (C) 2016 Jason Self <j@jxself.org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+#ifndef ZILASM_SYMTABLE
+#define ZILASM_SYMTABLE 1
+
+typedef struct {
+       unsigned elems_count;
+       unsigned name_size;
+       unsigned elem_size;
+       char contents[1];
+} Symtable;
+
+Symtable* symtable_create (unsigned elems_count, unsigned name_size, unsigned elem_size);
+void*     symtable_lookup (const Symtable*, const char *name);
+void*     symtable_lookup2(const Symtable*, const char *name, unsigned namelen);
+void*     symtable_add    (Symtable*, const char *name, void *contents);
+void*     symtable_add2   (Symtable*, const char *name, unsigned namelen, void *contents);
+void      symtable_sort   (Symtable*);
+void      symtable_destroy(Symtable*);
+
+#endif  /* ifndef ZILASM_SYMTABLE */
diff --git a/zilasm/zmem.c b/zilasm/zmem.c
new file mode 100644 (file)
index 0000000..b67e3c2
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * zmem.c -- part of ZilUtils/ZilAsm
+ *
+ * Copyright (C) 2016 Jason Self <j@jxself.org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+#include <assert.h>
+#include <strings.h>  /* bzero */
+#include <stdlib.h>   /* malloc, free */
+
+#include "zmem.h"
+
+ZMemblock* zmem_init(unsigned maxsize)
+{
+       ZMemblock *zmb = malloc(sizeof(ZMemblock) + maxsize - 1);
+       assert(zmb);
+       zmb->allocated_size = maxsize;
+       zmb->used_size = 0;
+       bzero(&zmb->contents, maxsize);
+       return zmb;
+}
+
+void zmem_destroy(ZMemblock *zmb)
+{
+       assert(zmb);
+       free(zmb);
+}
+
+void zmem_putbyte(ZMemblock *zmb, unsigned char val)
+{
+       assert(zmb);
+       assert(zmb->used_size < zmb->allocated_size);
+       zmb->contents[zmb->used_size++] = val;
+}
diff --git a/zilasm/zmem.h b/zilasm/zmem.h
new file mode 100644 (file)
index 0000000..8ac1c02
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * zmem.h -- part of ZilUtils/ZilAsm
+ *
+ * Copyright (C) 2016 Jason Self <j@jxself.org>
+ *
+ * Based on ZILF (c) 2010, 2015 Jesse McGrew
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+#ifndef ZILASM_ZMEM
+#define ZILASM_ZMEM 1
+
+typedef struct {
+       unsigned allocated_size;
+       unsigned used_size;
+       unsigned char contents[1];
+} ZMemblock;
+
+extern ZMemblock* zmem_init(unsigned maxsize);
+extern void       zmem_destroy(ZMemblock *zmb);
+extern void       zmem_putbyte(ZMemblock *zmb, unsigned char val);
+
+#endif  /* ifndef ZILASM_ZMEM */