Compare commits
1 Commits
Author | SHA1 | Date | |
---|---|---|---|
5ba7d7aef6 |
2
.gitignore
vendored
2
.gitignore
vendored
@ -3,5 +3,3 @@
|
||||
CMakeFiles/
|
||||
CMakeCache.txt
|
||||
node_modules/
|
||||
/dist/
|
||||
/dist-newstyle/
|
||||
|
@ -1,5 +0,0 @@
|
||||
# Revision history for elna
|
||||
|
||||
## 1.0 -- YYYY-mm-dd
|
||||
|
||||
* First version. Released on an unsuspecting world.
|
@ -5,8 +5,9 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS 1)
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
|
||||
find_package(Boost COMPONENTS process program_options REQUIRED)
|
||||
find_package(FLEX)
|
||||
find_package(Boost COMPONENTS program_options REQUIRED)
|
||||
find_package(FLEX REQUIRED)
|
||||
find_package(BISON REQUIRED)
|
||||
include_directories(${Boost_INCLUDE_DIR})
|
||||
|
||||
FLEX_TARGET(scanner source/scanner.l ${CMAKE_CURRENT_BINARY_DIR}/scanner.cpp)
|
||||
@ -26,3 +27,20 @@ add_executable(elna cli/main.cpp
|
||||
)
|
||||
target_include_directories(elna PRIVATE include)
|
||||
target_link_libraries(elna LINK_PUBLIC ${Boost_LIBRARIES})
|
||||
|
||||
FLEX_TARGET(lexer parser/lexer.ll ${CMAKE_CURRENT_BINARY_DIR}/lexer.cpp)
|
||||
BISON_TARGET(parser parser/parser.yy ${CMAKE_CURRENT_BINARY_DIR}/parser.cpp)
|
||||
add_flex_bison_dependency(lexer parser)
|
||||
|
||||
add_executable(test parser/main.cpp
|
||||
source/lexer.cpp include/elna/source/lexer.hpp
|
||||
source/parser.cpp include/elna/source/parser.hpp
|
||||
source/types.cpp include/elna/source/types.hpp
|
||||
source/symbol_table.cpp include/elna/source/symbol_table.hpp
|
||||
source/result.cpp include/elna/source/result.hpp
|
||||
source/semantic.cpp include/elna/source/semantic.hpp
|
||||
source/optimizer.cpp include/elna/source/optimizer.hpp
|
||||
${BISON_parser_OUTPUTS} ${FLEX_lexer_OUTPUTS}
|
||||
)
|
||||
target_include_directories(test PRIVATE ${CMAKE_CURRENT_BINARY_DIR} parser include)
|
||||
# target_link_libraries(test ${FLEX_LIBRARIES})
|
||||
|
373
LICENSE
373
LICENSE
@ -1,373 +0,0 @@
|
||||
Mozilla Public License Version 2.0
|
||||
==================================
|
||||
|
||||
1. Definitions
|
||||
--------------
|
||||
|
||||
1.1. "Contributor"
|
||||
means each individual or legal entity that creates, contributes to
|
||||
the creation of, or owns Covered Software.
|
||||
|
||||
1.2. "Contributor Version"
|
||||
means the combination of the Contributions of others (if any) used
|
||||
by a Contributor and that particular Contributor's Contribution.
|
||||
|
||||
1.3. "Contribution"
|
||||
means Covered Software of a particular Contributor.
|
||||
|
||||
1.4. "Covered Software"
|
||||
means Source Code Form to which the initial Contributor has attached
|
||||
the notice in Exhibit A, the Executable Form of such Source Code
|
||||
Form, and Modifications of such Source Code Form, in each case
|
||||
including portions thereof.
|
||||
|
||||
1.5. "Incompatible With Secondary Licenses"
|
||||
means
|
||||
|
||||
(a) that the initial Contributor has attached the notice described
|
||||
in Exhibit B to the Covered Software; or
|
||||
|
||||
(b) that the Covered Software was made available under the terms of
|
||||
version 1.1 or earlier of the License, but not also under the
|
||||
terms of a Secondary License.
|
||||
|
||||
1.6. "Executable Form"
|
||||
means any form of the work other than Source Code Form.
|
||||
|
||||
1.7. "Larger Work"
|
||||
means a work that combines Covered Software with other material, in
|
||||
a separate file or files, that is not Covered Software.
|
||||
|
||||
1.8. "License"
|
||||
means this document.
|
||||
|
||||
1.9. "Licensable"
|
||||
means having the right to grant, to the maximum extent possible,
|
||||
whether at the time of the initial grant or subsequently, any and
|
||||
all of the rights conveyed by this License.
|
||||
|
||||
1.10. "Modifications"
|
||||
means any of the following:
|
||||
|
||||
(a) any file in Source Code Form that results from an addition to,
|
||||
deletion from, or modification of the contents of Covered
|
||||
Software; or
|
||||
|
||||
(b) any new file in Source Code Form that contains any Covered
|
||||
Software.
|
||||
|
||||
1.11. "Patent Claims" of a Contributor
|
||||
means any patent claim(s), including without limitation, method,
|
||||
process, and apparatus claims, in any patent Licensable by such
|
||||
Contributor that would be infringed, but for the grant of the
|
||||
License, by the making, using, selling, offering for sale, having
|
||||
made, import, or transfer of either its Contributions or its
|
||||
Contributor Version.
|
||||
|
||||
1.12. "Secondary License"
|
||||
means either the GNU General Public License, Version 2.0, the GNU
|
||||
Lesser General Public License, Version 2.1, the GNU Affero General
|
||||
Public License, Version 3.0, or any later versions of those
|
||||
licenses.
|
||||
|
||||
1.13. "Source Code Form"
|
||||
means the form of the work preferred for making modifications.
|
||||
|
||||
1.14. "You" (or "Your")
|
||||
means an individual or a legal entity exercising rights under this
|
||||
License. For legal entities, "You" includes any entity that
|
||||
controls, is controlled by, or is under common control with You. For
|
||||
purposes of this definition, "control" means (a) the power, direct
|
||||
or indirect, to cause the direction or management of such entity,
|
||||
whether by contract or otherwise, or (b) ownership of more than
|
||||
fifty percent (50%) of the outstanding shares or beneficial
|
||||
ownership of such entity.
|
||||
|
||||
2. License Grants and Conditions
|
||||
--------------------------------
|
||||
|
||||
2.1. Grants
|
||||
|
||||
Each Contributor hereby grants You a world-wide, royalty-free,
|
||||
non-exclusive license:
|
||||
|
||||
(a) under intellectual property rights (other than patent or trademark)
|
||||
Licensable by such Contributor to use, reproduce, make available,
|
||||
modify, display, perform, distribute, and otherwise exploit its
|
||||
Contributions, either on an unmodified basis, with Modifications, or
|
||||
as part of a Larger Work; and
|
||||
|
||||
(b) under Patent Claims of such Contributor to make, use, sell, offer
|
||||
for sale, have made, import, and otherwise transfer either its
|
||||
Contributions or its Contributor Version.
|
||||
|
||||
2.2. Effective Date
|
||||
|
||||
The licenses granted in Section 2.1 with respect to any Contribution
|
||||
become effective for each Contribution on the date the Contributor first
|
||||
distributes such Contribution.
|
||||
|
||||
2.3. Limitations on Grant Scope
|
||||
|
||||
The licenses granted in this Section 2 are the only rights granted under
|
||||
this License. No additional rights or licenses will be implied from the
|
||||
distribution or licensing of Covered Software under this License.
|
||||
Notwithstanding Section 2.1(b) above, no patent license is granted by a
|
||||
Contributor:
|
||||
|
||||
(a) for any code that a Contributor has removed from Covered Software;
|
||||
or
|
||||
|
||||
(b) for infringements caused by: (i) Your and any other third party's
|
||||
modifications of Covered Software, or (ii) the combination of its
|
||||
Contributions with other software (except as part of its Contributor
|
||||
Version); or
|
||||
|
||||
(c) under Patent Claims infringed by Covered Software in the absence of
|
||||
its Contributions.
|
||||
|
||||
This License does not grant any rights in the trademarks, service marks,
|
||||
or logos of any Contributor (except as may be necessary to comply with
|
||||
the notice requirements in Section 3.4).
|
||||
|
||||
2.4. Subsequent Licenses
|
||||
|
||||
No Contributor makes additional grants as a result of Your choice to
|
||||
distribute the Covered Software under a subsequent version of this
|
||||
License (see Section 10.2) or under the terms of a Secondary License (if
|
||||
permitted under the terms of Section 3.3).
|
||||
|
||||
2.5. Representation
|
||||
|
||||
Each Contributor represents that the Contributor believes its
|
||||
Contributions are its original creation(s) or it has sufficient rights
|
||||
to grant the rights to its Contributions conveyed by this License.
|
||||
|
||||
2.6. Fair Use
|
||||
|
||||
This License is not intended to limit any rights You have under
|
||||
applicable copyright doctrines of fair use, fair dealing, or other
|
||||
equivalents.
|
||||
|
||||
2.7. Conditions
|
||||
|
||||
Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted
|
||||
in Section 2.1.
|
||||
|
||||
3. Responsibilities
|
||||
-------------------
|
||||
|
||||
3.1. Distribution of Source Form
|
||||
|
||||
All distribution of Covered Software in Source Code Form, including any
|
||||
Modifications that You create or to which You contribute, must be under
|
||||
the terms of this License. You must inform recipients that the Source
|
||||
Code Form of the Covered Software is governed by the terms of this
|
||||
License, and how they can obtain a copy of this License. You may not
|
||||
attempt to alter or restrict the recipients' rights in the Source Code
|
||||
Form.
|
||||
|
||||
3.2. Distribution of Executable Form
|
||||
|
||||
If You distribute Covered Software in Executable Form then:
|
||||
|
||||
(a) such Covered Software must also be made available in Source Code
|
||||
Form, as described in Section 3.1, and You must inform recipients of
|
||||
the Executable Form how they can obtain a copy of such Source Code
|
||||
Form by reasonable means in a timely manner, at a charge no more
|
||||
than the cost of distribution to the recipient; and
|
||||
|
||||
(b) You may distribute such Executable Form under the terms of this
|
||||
License, or sublicense it under different terms, provided that the
|
||||
license for the Executable Form does not attempt to limit or alter
|
||||
the recipients' rights in the Source Code Form under this License.
|
||||
|
||||
3.3. Distribution of a Larger Work
|
||||
|
||||
You may create and distribute a Larger Work under terms of Your choice,
|
||||
provided that You also comply with the requirements of this License for
|
||||
the Covered Software. If the Larger Work is a combination of Covered
|
||||
Software with a work governed by one or more Secondary Licenses, and the
|
||||
Covered Software is not Incompatible With Secondary Licenses, this
|
||||
License permits You to additionally distribute such Covered Software
|
||||
under the terms of such Secondary License(s), so that the recipient of
|
||||
the Larger Work may, at their option, further distribute the Covered
|
||||
Software under the terms of either this License or such Secondary
|
||||
License(s).
|
||||
|
||||
3.4. Notices
|
||||
|
||||
You may not remove or alter the substance of any license notices
|
||||
(including copyright notices, patent notices, disclaimers of warranty,
|
||||
or limitations of liability) contained within the Source Code Form of
|
||||
the Covered Software, except that You may alter any license notices to
|
||||
the extent required to remedy known factual inaccuracies.
|
||||
|
||||
3.5. Application of Additional Terms
|
||||
|
||||
You may choose to offer, and to charge a fee for, warranty, support,
|
||||
indemnity or liability obligations to one or more recipients of Covered
|
||||
Software. However, You may do so only on Your own behalf, and not on
|
||||
behalf of any Contributor. You must make it absolutely clear that any
|
||||
such warranty, support, indemnity, or liability obligation is offered by
|
||||
You alone, and You hereby agree to indemnify every Contributor for any
|
||||
liability incurred by such Contributor as a result of warranty, support,
|
||||
indemnity or liability terms You offer. You may include additional
|
||||
disclaimers of warranty and limitations of liability specific to any
|
||||
jurisdiction.
|
||||
|
||||
4. Inability to Comply Due to Statute or Regulation
|
||||
---------------------------------------------------
|
||||
|
||||
If it is impossible for You to comply with any of the terms of this
|
||||
License with respect to some or all of the Covered Software due to
|
||||
statute, judicial order, or regulation then You must: (a) comply with
|
||||
the terms of this License to the maximum extent possible; and (b)
|
||||
describe the limitations and the code they affect. Such description must
|
||||
be placed in a text file included with all distributions of the Covered
|
||||
Software under this License. Except to the extent prohibited by statute
|
||||
or regulation, such description must be sufficiently detailed for a
|
||||
recipient of ordinary skill to be able to understand it.
|
||||
|
||||
5. Termination
|
||||
--------------
|
||||
|
||||
5.1. The rights granted under this License will terminate automatically
|
||||
if You fail to comply with any of its terms. However, if You become
|
||||
compliant, then the rights granted under this License from a particular
|
||||
Contributor are reinstated (a) provisionally, unless and until such
|
||||
Contributor explicitly and finally terminates Your grants, and (b) on an
|
||||
ongoing basis, if such Contributor fails to notify You of the
|
||||
non-compliance by some reasonable means prior to 60 days after You have
|
||||
come back into compliance. Moreover, Your grants from a particular
|
||||
Contributor are reinstated on an ongoing basis if such Contributor
|
||||
notifies You of the non-compliance by some reasonable means, this is the
|
||||
first time You have received notice of non-compliance with this License
|
||||
from such Contributor, and You become compliant prior to 30 days after
|
||||
Your receipt of the notice.
|
||||
|
||||
5.2. If You initiate litigation against any entity by asserting a patent
|
||||
infringement claim (excluding declaratory judgment actions,
|
||||
counter-claims, and cross-claims) alleging that a Contributor Version
|
||||
directly or indirectly infringes any patent, then the rights granted to
|
||||
You by any and all Contributors for the Covered Software under Section
|
||||
2.1 of this License shall terminate.
|
||||
|
||||
5.3. In the event of termination under Sections 5.1 or 5.2 above, all
|
||||
end user license agreements (excluding distributors and resellers) which
|
||||
have been validly granted by You or Your distributors under this License
|
||||
prior to termination shall survive termination.
|
||||
|
||||
************************************************************************
|
||||
* *
|
||||
* 6. Disclaimer of Warranty *
|
||||
* ------------------------- *
|
||||
* *
|
||||
* Covered Software is provided under this License on an "as is" *
|
||||
* basis, without warranty of any kind, either expressed, implied, or *
|
||||
* statutory, including, without limitation, warranties that the *
|
||||
* Covered Software is free of defects, merchantable, fit for a *
|
||||
* particular purpose or non-infringing. The entire risk as to the *
|
||||
* quality and performance of the Covered Software is with You. *
|
||||
* Should any Covered Software prove defective in any respect, You *
|
||||
* (not any Contributor) assume the cost of any necessary servicing, *
|
||||
* repair, or correction. This disclaimer of warranty constitutes an *
|
||||
* essential part of this License. No use of any Covered Software is *
|
||||
* authorized under this License except under this disclaimer. *
|
||||
* *
|
||||
************************************************************************
|
||||
|
||||
************************************************************************
|
||||
* *
|
||||
* 7. Limitation of Liability *
|
||||
* -------------------------- *
|
||||
* *
|
||||
* Under no circumstances and under no legal theory, whether tort *
|
||||
* (including negligence), contract, or otherwise, shall any *
|
||||
* Contributor, or anyone who distributes Covered Software as *
|
||||
* permitted above, be liable to You for any direct, indirect, *
|
||||
* special, incidental, or consequential damages of any character *
|
||||
* including, without limitation, damages for lost profits, loss of *
|
||||
* goodwill, work stoppage, computer failure or malfunction, or any *
|
||||
* and all other commercial damages or losses, even if such party *
|
||||
* shall have been informed of the possibility of such damages. This *
|
||||
* limitation of liability shall not apply to liability for death or *
|
||||
* personal injury resulting from such party's negligence to the *
|
||||
* extent applicable law prohibits such limitation. Some *
|
||||
* jurisdictions do not allow the exclusion or limitation of *
|
||||
* incidental or consequential damages, so this exclusion and *
|
||||
* limitation may not apply to You. *
|
||||
* *
|
||||
************************************************************************
|
||||
|
||||
8. Litigation
|
||||
-------------
|
||||
|
||||
Any litigation relating to this License may be brought only in the
|
||||
courts of a jurisdiction where the defendant maintains its principal
|
||||
place of business and such litigation shall be governed by laws of that
|
||||
jurisdiction, without reference to its conflict-of-law provisions.
|
||||
Nothing in this Section shall prevent a party's ability to bring
|
||||
cross-claims or counter-claims.
|
||||
|
||||
9. Miscellaneous
|
||||
----------------
|
||||
|
||||
This License represents the complete agreement concerning the subject
|
||||
matter hereof. If any provision of this License is held to be
|
||||
unenforceable, such provision shall be reformed only to the extent
|
||||
necessary to make it enforceable. Any law or regulation which provides
|
||||
that the language of a contract shall be construed against the drafter
|
||||
shall not be used to construe this License against a Contributor.
|
||||
|
||||
10. Versions of the License
|
||||
---------------------------
|
||||
|
||||
10.1. New Versions
|
||||
|
||||
Mozilla Foundation is the license steward. Except as provided in Section
|
||||
10.3, no one other than the license steward has the right to modify or
|
||||
publish new versions of this License. Each version will be given a
|
||||
distinguishing version number.
|
||||
|
||||
10.2. Effect of New Versions
|
||||
|
||||
You may distribute the Covered Software under the terms of the version
|
||||
of the License under which You originally received the Covered Software,
|
||||
or under the terms of any subsequent version published by the license
|
||||
steward.
|
||||
|
||||
10.3. Modified Versions
|
||||
|
||||
If you create software not governed by this License, and you want to
|
||||
create a new license for such software, you may create and use a
|
||||
modified version of this License if you rename the license and remove
|
||||
any references to the name of the license steward (except to note that
|
||||
such modified license differs from this License).
|
||||
|
||||
10.4. Distributing Source Code Form that is Incompatible With Secondary
|
||||
Licenses
|
||||
|
||||
If You choose to distribute Source Code Form that is Incompatible With
|
||||
Secondary Licenses under the terms of this version of the License, the
|
||||
notice described in Exhibit B of this License must be attached.
|
||||
|
||||
Exhibit A - Source Code Form License Notice
|
||||
-------------------------------------------
|
||||
|
||||
This Source Code Form is subject to the terms of the Mozilla Public
|
||||
License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
If it is not possible or desirable to put the notice in a particular
|
||||
file, then You may include the notice in a location (such as a LICENSE
|
||||
file in a relevant directory) where a recipient would be likely to look
|
||||
for such a notice.
|
||||
|
||||
You may add additional accurate notices of copyright ownership.
|
||||
|
||||
Exhibit B - "Incompatible With Secondary Licenses" Notice
|
||||
---------------------------------------------------------
|
||||
|
||||
This Source Code Form is "Incompatible With Secondary Licenses", as
|
||||
defined by the Mozilla Public License, v. 2.0.
|
@ -4,9 +4,87 @@
|
||||
|
||||
namespace elna::riscv
|
||||
{
|
||||
elfio_writer::elfio_writer(ELFIO::section *text,
|
||||
elfio_section_writer::iterator::reference elfio_section_writer::iterator::operator*() const noexcept
|
||||
{
|
||||
return payload;
|
||||
}
|
||||
|
||||
elfio_section_writer::iterator::pointer elfio_section_writer::iterator::operator->() const noexcept
|
||||
{
|
||||
return &payload;
|
||||
}
|
||||
|
||||
elfio_section_writer::iterator& elfio_section_writer::iterator::operator++()
|
||||
{
|
||||
this->payload.data += *this->sizes;
|
||||
this->payload.label = *(++this->labels);
|
||||
this->payload.size = *(++this->sizes);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
elfio_section_writer::iterator& elfio_section_writer::iterator::operator++(int)
|
||||
{
|
||||
auto tmp = *this;
|
||||
++(*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool elfio_section_writer::iterator::operator==(const iterator& that) const
|
||||
{
|
||||
return this->labels == that.labels;
|
||||
}
|
||||
|
||||
bool elfio_section_writer::iterator::operator!=(const iterator& that) const
|
||||
{
|
||||
return !(*this == that);
|
||||
}
|
||||
|
||||
elfio_section_writer::elfio_section_writer(ELFIO::section *section)
|
||||
: m_section(section)
|
||||
{
|
||||
}
|
||||
|
||||
void elfio_section_writer::operator()(const std::string& label, const std::byte *data, std::size_t size)
|
||||
{
|
||||
labels.push_back(label);
|
||||
sizes.push_back(size);
|
||||
m_section->append_data(reinterpret_cast<const char *>(data), size);
|
||||
}
|
||||
|
||||
std::pair<std::string_view, bool> elfio_section_writer::operator()(const std::byte *data, std::size_t size)
|
||||
{
|
||||
auto found = std::find_if(begin(), end(),
|
||||
[data, size](elfio_section_writer::entry entry) {
|
||||
return size == entry.size && std::memcmp(entry.data, data, size) == 0;
|
||||
});
|
||||
if (found == end())
|
||||
{
|
||||
(*this)(".CL" + std::to_string(labels.size()), data, size);
|
||||
return std::pair<std::string_view, bool>(labels.back(), true);
|
||||
}
|
||||
return std::pair<std::string_view, bool>(found->label, false);
|
||||
}
|
||||
|
||||
elfio_section_writer::iterator elfio_section_writer::begin() const
|
||||
{
|
||||
return elfio_section_writer::iterator(labels.cbegin(), sizes.cbegin(),
|
||||
reinterpret_cast<const std::byte *>(m_section->get_data()));
|
||||
}
|
||||
|
||||
elfio_section_writer::iterator elfio_section_writer::end() const
|
||||
{
|
||||
return elfio_section_writer::iterator(labels.cend(), sizes.cend());
|
||||
}
|
||||
|
||||
ELFIO::section *elfio_section_writer::section() noexcept
|
||||
{
|
||||
return m_section;
|
||||
}
|
||||
|
||||
elfio_writer::elfio_writer(ELFIO::section *text, ELFIO::section *read_only,
|
||||
ELFIO::symbol_section_accessor symbol_accessor, ELFIO::string_section_accessor string_accessor)
|
||||
: text(text),
|
||||
: text(text), read_only(elfio_section_writer(read_only)),
|
||||
symbol_accessor(symbol_accessor), string_accessor(string_accessor)
|
||||
{
|
||||
}
|
||||
@ -22,6 +100,20 @@ namespace elna::riscv
|
||||
return text->get_size();
|
||||
}
|
||||
|
||||
std::string_view elfio_writer::sink(const std::byte *data, std::size_t size)
|
||||
{
|
||||
auto offset = read_only.section()->get_size();
|
||||
auto [result, inserted] = read_only(data, size);
|
||||
|
||||
if (inserted)
|
||||
{
|
||||
this->symbol_accessor.add_symbol(this->string_accessor, result.data(), offset,
|
||||
result.size(), ELFIO::STB_LOCAL, ELFIO::STT_NOTYPE, 0,
|
||||
read_only.section()->get_index());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void elfio_writer::sink(const std::string& label)
|
||||
{
|
||||
this->symbol_accessor.add_symbol(this->string_accessor, "printf", 0x00000000, 0,
|
||||
@ -96,11 +188,17 @@ namespace elna::riscv
|
||||
rel_sec->set_link(sym_sec->get_index());
|
||||
rel_sec->set_flags(ELFIO::SHF_ALLOC);
|
||||
|
||||
// Create read only data section
|
||||
ELFIO::section* ro_sec = writer.sections.add(".rodata");
|
||||
ro_sec->set_type(ELFIO::SHT_PROGBITS);
|
||||
ro_sec->set_flags(ELFIO::SHF_ALLOC);
|
||||
ro_sec->set_addr_align(0x4);
|
||||
|
||||
// Create symbol relocation table writers
|
||||
ELFIO::symbol_section_accessor syma(writer, sym_sec);
|
||||
ELFIO::relocation_section_accessor rela(writer, rel_sec);
|
||||
auto _writer = std::make_shared<elfio_writer>(text_sec, ro_sec, syma, stra);
|
||||
|
||||
auto _writer = std::make_shared<elfio_writer>(text_sec, syma, stra);
|
||||
auto references = generate(intermediate_code_generator, table, _writer);
|
||||
|
||||
syma.arrange_local_symbols();
|
||||
|
@ -7,17 +7,87 @@
|
||||
|
||||
namespace elna::riscv
|
||||
{
|
||||
/**
|
||||
* Writer to a single label.
|
||||
*/
|
||||
struct elfio_section_writer
|
||||
{
|
||||
struct entry
|
||||
{
|
||||
std::string_view label;
|
||||
const std::byte *data{ nullptr };
|
||||
std::size_t size{ 0 };
|
||||
};
|
||||
|
||||
/**
|
||||
* An iterator over label and string pairs.
|
||||
*/
|
||||
struct iterator
|
||||
{
|
||||
using iterator_category = std::forward_iterator_tag;
|
||||
using difference_type = ptrdiff_t;
|
||||
using value_type = entry;
|
||||
using pointer = const value_type *;
|
||||
using reference = const value_type&;
|
||||
|
||||
reference operator*() const noexcept;
|
||||
pointer operator->() const noexcept;
|
||||
iterator& operator++();
|
||||
iterator& operator++(int);
|
||||
bool operator==(const iterator& that) const;
|
||||
bool operator!=(const iterator& that) const;
|
||||
|
||||
private:
|
||||
std::vector<std::string>::const_iterator labels;
|
||||
std::vector<std::size_t>::const_iterator sizes;
|
||||
value_type payload;
|
||||
|
||||
iterator(std::vector<std::string>::const_iterator labels, std::vector<std::size_t>::const_iterator sizes,
|
||||
const std::byte *data)
|
||||
: labels(labels), sizes(sizes)
|
||||
{
|
||||
if (data != nullptr)
|
||||
{
|
||||
payload = { *this->labels, data, *this->sizes};
|
||||
}
|
||||
}
|
||||
|
||||
iterator(std::vector<std::string>::const_iterator labels, std::vector<std::size_t>::const_iterator sizes)
|
||||
: labels(labels), sizes(sizes), payload{}
|
||||
{
|
||||
}
|
||||
|
||||
friend elfio_section_writer;
|
||||
};
|
||||
explicit elfio_section_writer(ELFIO::section *section);
|
||||
|
||||
void operator()(const std::string& label, const std::byte *data, std::size_t size);
|
||||
std::pair<std::string_view, bool> operator()(const std::byte *data, std::size_t size);
|
||||
|
||||
iterator begin() const;
|
||||
iterator end() const;
|
||||
|
||||
ELFIO::section *section() noexcept;
|
||||
|
||||
private:
|
||||
std::vector<std::string> labels;
|
||||
std::vector<std::size_t> sizes;
|
||||
ELFIO::section *m_section;
|
||||
};
|
||||
|
||||
class elfio_writer final : public source::writer<std::byte>
|
||||
{
|
||||
ELFIO::section *text;
|
||||
elfio_section_writer read_only;
|
||||
ELFIO::symbol_section_accessor symbol_accessor;
|
||||
ELFIO::string_section_accessor string_accessor;
|
||||
|
||||
public:
|
||||
elfio_writer(ELFIO::section *text, ELFIO::symbol_section_accessor symbol_accessor,
|
||||
elfio_writer(ELFIO::section *text, ELFIO::section *read_only, ELFIO::symbol_section_accessor symbol_accessor,
|
||||
ELFIO::string_section_accessor string_accessor);
|
||||
|
||||
std::size_t sink(const std::string& label, const std::byte *data, std::size_t size) override;
|
||||
std::string_view sink(const std::byte *data, std::size_t size) override;
|
||||
void sink(const std::string& label) override;
|
||||
std::size_t size() const override;
|
||||
};
|
||||
|
@ -171,6 +171,16 @@ namespace elna::source
|
||||
*/
|
||||
virtual std::size_t sink(const std::string& label, const T *data, std::size_t size) = 0;
|
||||
|
||||
/**
|
||||
* Writes data and returns a label under that the data can be accessed.
|
||||
*
|
||||
* \param data Data to be written.
|
||||
* \param size Data size.
|
||||
*
|
||||
* \return Label for the symbol.
|
||||
*/
|
||||
virtual std::string_view sink(const T *data, std::size_t size) = 0;
|
||||
|
||||
/**
|
||||
* Creates an external symbol.
|
||||
*/
|
||||
|
131
parser/lexer.ll
Normal file
131
parser/lexer.ll
Normal file
@ -0,0 +1,131 @@
|
||||
%{
|
||||
#define YY_NO_UNISTD_H
|
||||
#define YY_USER_ACTION this->location.columns(yyleng);
|
||||
|
||||
#include <sstream>
|
||||
#include "parser.hpp"
|
||||
|
||||
#undef YY_DECL
|
||||
#define YY_DECL yy::parser::symbol_type elna::syntax::FooLexer::lex()
|
||||
#define yyterminate() return yy::parser::make_YYEOF(this->location)
|
||||
%}
|
||||
|
||||
%option c++ noyywrap never-interactive
|
||||
%option yyclass="elna::syntax::FooLexer"
|
||||
|
||||
%%
|
||||
%{
|
||||
this->location.step();
|
||||
%}
|
||||
|
||||
\-\-.* {
|
||||
/* Skip the comment */
|
||||
}
|
||||
[\ \t\r] ; /* Skip the whitespaces */
|
||||
\n+ {
|
||||
this->location.lines(yyleng);
|
||||
this->location.step();
|
||||
}
|
||||
if {
|
||||
return yy::parser::make_IF(this->location);
|
||||
}
|
||||
then {
|
||||
return yy::parser::make_THEN(this->location);
|
||||
}
|
||||
while {
|
||||
return yy::parser::make_WHILE(this->location);
|
||||
}
|
||||
do {
|
||||
return yy::parser::make_DO(this->location);
|
||||
}
|
||||
proc {
|
||||
return yy::parser::make_PROCEDURE(this->location);
|
||||
}
|
||||
begin {
|
||||
return yy::parser::make_BEGIN_BLOCK(this->location);
|
||||
}
|
||||
end {
|
||||
return yy::parser::make_END_BLOCK(this->location);
|
||||
}
|
||||
const {
|
||||
return yy::parser::make_CONST(this->location);
|
||||
}
|
||||
var {
|
||||
return yy::parser::make_VAR(this->location);
|
||||
}
|
||||
True {
|
||||
return yy::parser::make_BOOLEAN(true, this->location);
|
||||
}
|
||||
False {
|
||||
return yy::parser::make_BOOLEAN(false, this->location);
|
||||
}
|
||||
[A-Za-z_][A-Za-z0-9_]* {
|
||||
return yy::parser::make_IDENTIFIER(yytext, this->location);
|
||||
}
|
||||
[0-9]+ {
|
||||
return yy::parser::make_NUMBER(strtol(yytext, NULL, 10), this->location);
|
||||
}
|
||||
\( {
|
||||
return yy::parser::make_LEFT_PAREN(this->location);
|
||||
}
|
||||
\) {
|
||||
return yy::parser::make_RIGHT_PAREN(this->location);
|
||||
}
|
||||
\>= {
|
||||
return yy::parser::make_GREATER_EQUAL(this->location);
|
||||
}
|
||||
\<= {
|
||||
return yy::parser::make_LESS_EQUAL(this->location);
|
||||
}
|
||||
\> {
|
||||
return yy::parser::make_GREATER_THAN(this->location);
|
||||
}
|
||||
\< {
|
||||
return yy::parser::make_LESS_THAN(this->location);
|
||||
}
|
||||
\/= {
|
||||
return yy::parser::make_NOT_EQUAL(this->location);
|
||||
}
|
||||
= {
|
||||
return yy::parser::make_EQUALS(this->location);
|
||||
}
|
||||
; {
|
||||
return yy::parser::make_SEMICOLON(this->location);
|
||||
}
|
||||
\. {
|
||||
return yy::parser::make_DOT(this->location);
|
||||
}
|
||||
, {
|
||||
return yy::parser::make_COMMA(this->location);
|
||||
}
|
||||
\+ {
|
||||
return yy::parser::make_PLUS(this->location);
|
||||
}
|
||||
\- {
|
||||
return yy::parser::make_MINUS(this->location);
|
||||
}
|
||||
\* {
|
||||
return yy::parser::make_MULTIPLICATION(this->location);
|
||||
}
|
||||
\/ {
|
||||
return yy::parser::make_DIVISION(this->location);
|
||||
}
|
||||
:= {
|
||||
return yy::parser::make_ASSIGNMENT(this->location);
|
||||
}
|
||||
: {
|
||||
return yy::parser::make_COLON(this->location);
|
||||
}
|
||||
\^ {
|
||||
return yy::parser::make_HAT(this->location);
|
||||
}
|
||||
@ {
|
||||
return yy::parser::make_AT(this->location);
|
||||
}
|
||||
. {
|
||||
std::stringstream ss;
|
||||
|
||||
ss << "Illegal character 0x" << std::hex << static_cast<unsigned char>(yytext[0]);
|
||||
throw yy::parser::syntax_error(this->location, ss.str());
|
||||
}
|
||||
%%
|
46
parser/main.cpp
Normal file
46
parser/main.cpp
Normal file
@ -0,0 +1,46 @@
|
||||
#include "parser.hpp"
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
|
||||
int main()
|
||||
{
|
||||
std::istringstream inp(
|
||||
"const world = 5, hello = 7;\n"
|
||||
"var x: Int, y: ^Int;\n"
|
||||
"begin\n"
|
||||
"end.\n"
|
||||
);
|
||||
std::unique_ptr<elna::source::program> program;
|
||||
int result{ 1 };
|
||||
|
||||
elna::syntax::FooLexer lexer(inp);
|
||||
yy::parser parser(lexer, program);
|
||||
try
|
||||
{
|
||||
result = parser();
|
||||
}
|
||||
catch (yy::parser::syntax_error& syntax_error)
|
||||
{
|
||||
std::cerr << syntax_error.location << ": " << syntax_error.what() << std::endl;
|
||||
return result;
|
||||
}
|
||||
|
||||
for (auto& definition : program->definitions())
|
||||
{
|
||||
auto const_definition = dynamic_cast<elna::source::constant_definition *>(definition.get());
|
||||
|
||||
std::cout << "const " << const_definition->identifier() << " = "
|
||||
<< const_definition->body().number() << std::endl;
|
||||
}
|
||||
for (auto& declaration : program->declarations())
|
||||
{
|
||||
std::cout << "var " << declaration->identifier() << ": ";
|
||||
|
||||
if (declaration->type().is_pointer())
|
||||
{
|
||||
std::cout << '^';
|
||||
}
|
||||
std::cout << declaration->type().base() << std::endl;
|
||||
}
|
||||
return result;
|
||||
}
|
406
parser/parser.yy
Normal file
406
parser/parser.yy
Normal file
@ -0,0 +1,406 @@
|
||||
%require "3.2"
|
||||
%language "c++"
|
||||
|
||||
%code requires {
|
||||
#include <cstdint>
|
||||
#include "elna/source/parser.hpp"
|
||||
|
||||
|
||||
#if ! defined(yyFlexLexerOnce)
|
||||
#include <FlexLexer.h>
|
||||
#endif
|
||||
|
||||
namespace elna::syntax
|
||||
{
|
||||
class FooLexer;
|
||||
}
|
||||
}
|
||||
|
||||
%code provides {
|
||||
namespace elna::syntax
|
||||
{
|
||||
|
||||
class FooLexer : public yyFlexLexer
|
||||
{
|
||||
public:
|
||||
yy::location location;
|
||||
|
||||
FooLexer(std::istream& arg_yyin)
|
||||
: yyFlexLexer(&arg_yyin)
|
||||
{
|
||||
}
|
||||
|
||||
yy::parser::symbol_type lex();
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
%define api.token.raw
|
||||
%define api.token.constructor
|
||||
%define api.value.type variant
|
||||
%define parse.assert
|
||||
|
||||
%parse-param {elna::syntax::FooLexer& lexer}
|
||||
%parse-param {std::unique_ptr<elna::source::program>& program}
|
||||
%locations
|
||||
|
||||
%header
|
||||
|
||||
%code {
|
||||
#define yylex lexer.lex
|
||||
}
|
||||
%start program;
|
||||
|
||||
%token <std::string> IDENTIFIER "identifier"
|
||||
%token <std::int32_t> NUMBER "number"
|
||||
%token <bool> BOOLEAN
|
||||
%token IF THEN WHILE DO
|
||||
%token CONST VAR PROCEDURE
|
||||
%token BEGIN_BLOCK END_BLOCK
|
||||
%token TRUE FALSE
|
||||
%token LEFT_PAREN RIGHT_PAREN SEMICOLON DOT COMMA
|
||||
%token GREATER_EQUAL LESS_EQUAL LESS_THAN GREATER_THAN NOT_EQUAL EQUALS
|
||||
%token PLUS MINUS MULTIPLICATION DIVISION
|
||||
%token ASSIGNMENT COLON HAT AT
|
||||
|
||||
%type <std::unique_ptr<elna::source::integer_literal>> integer_literal;
|
||||
%type <std::unique_ptr<elna::source::boolean_literal>> boolean_literal;
|
||||
%type <std::unique_ptr<elna::source::variable_expression>> variable_expression;
|
||||
%type <std::unique_ptr<elna::source::constant_definition>> constant_definition;
|
||||
%type <std::unique_ptr<elna::source::unary_expression>> reference_expression dereference_expression;
|
||||
%type <std::vector<std::unique_ptr<elna::source::constant_definition>>> constant_definition_part constant_definitions;
|
||||
%type <std::unique_ptr<elna::source::type_expression>> type_expression;
|
||||
%type <std::unique_ptr<elna::source::declaration>> variable_declaration;
|
||||
%type <std::vector<std::unique_ptr<elna::source::declaration>>> variable_declaration_part variable_declarations;
|
||||
%type <std::unique_ptr<elna::source::assign_statement>> assign_statement;
|
||||
%type <std::unique_ptr<elna::source::expression>> expression factor term comparand;
|
||||
%type <std::unique_ptr<elna::source::statement>> statement;
|
||||
%type <std::vector<std::unique_ptr<elna::source::expression>>> arguments;
|
||||
%type <std::unique_ptr<elna::source::call_statement>> call_statement;
|
||||
%type <std::unique_ptr<elna::source::compound_statement>> compound_statement;
|
||||
%type <std::vector<std::unique_ptr<elna::source::statement>>> statements;
|
||||
%type <std::unique_ptr<elna::source::if_statement>> if_statement;
|
||||
%type <std::unique_ptr<elna::source::while_statement>> while_statement;
|
||||
%type <std::unique_ptr<elna::source::procedure_definition>> procedure_definition;
|
||||
%type <std::vector<std::unique_ptr<elna::source::procedure_definition>>> procedure_definition_part procedure_definitions;
|
||||
%%
|
||||
program: constant_definition_part variable_declaration_part procedure_definition_part statement DOT
|
||||
{
|
||||
elna::source::position position;
|
||||
std::vector<std::unique_ptr<elna::source::definition>> definitions($1.size());
|
||||
std::vector<std::unique_ptr<elna::source::declaration>> declarations($2.size());
|
||||
std::vector<std::unique_ptr<elna::source::definition>>::iterator definition = definitions.begin();
|
||||
std::vector<std::unique_ptr<elna::source::declaration>>::iterator declaration = declarations.begin();
|
||||
|
||||
for (auto& constant : $1)
|
||||
{
|
||||
*definition++ = std::move(constant);
|
||||
}
|
||||
for (auto& variable : $2)
|
||||
{
|
||||
*declaration++ = std::move(variable);
|
||||
}
|
||||
program = std::make_unique<elna::source::program>(position,
|
||||
std::move(definitions), std::move(declarations), std::move($4));
|
||||
}
|
||||
procedure_definition:
|
||||
PROCEDURE IDENTIFIER SEMICOLON constant_definition_part variable_declaration_part statement SEMICOLON
|
||||
{
|
||||
elna::source::position position;
|
||||
std::vector<std::unique_ptr<elna::source::definition>> definitions($4.size());
|
||||
std::vector<std::unique_ptr<elna::source::declaration>> declarations($5.size());
|
||||
std::vector<std::unique_ptr<elna::source::definition>>::iterator definition = definitions.begin();
|
||||
std::vector<std::unique_ptr<elna::source::declaration>>::iterator declaration = declarations.begin();
|
||||
|
||||
for (auto& constant : $4)
|
||||
{
|
||||
*definition++ = std::move(constant);
|
||||
}
|
||||
for (auto& variable : $5)
|
||||
{
|
||||
*declaration++ = std::move(variable);
|
||||
}
|
||||
auto block = std::make_unique<elna::source::block>(position,
|
||||
std::move(definitions), std::move(declarations), std::move($6));
|
||||
$$ = std::make_unique<elna::source::procedure_definition>(position,
|
||||
$2, std::move(block));
|
||||
}
|
||||
procedure_definition_part:
|
||||
/* no procedure definitions. */ {}
|
||||
| procedure_definitions { std::swap($1, $$); }
|
||||
procedure_definitions:
|
||||
procedure_definition procedure_definitions
|
||||
{
|
||||
std::swap($$, $2);
|
||||
$$.emplace($$.cbegin(), std::move($1));
|
||||
}
|
||||
| procedure_definition { $$.emplace_back(std::move($1)); }
|
||||
integer_literal: NUMBER
|
||||
{
|
||||
elna::source::position position{
|
||||
static_cast<std::size_t>(@1.begin.line),
|
||||
static_cast<std::size_t>(@1.begin.column)
|
||||
};
|
||||
$$ = std::make_unique<elna::source::integer_literal>(position, $1);
|
||||
}
|
||||
boolean_literal: BOOLEAN
|
||||
{
|
||||
elna::source::position position{
|
||||
static_cast<std::size_t>(@1.begin.line),
|
||||
static_cast<std::size_t>(@1.begin.column)
|
||||
};
|
||||
$$ = std::make_unique<elna::source::boolean_literal>(position, $1);
|
||||
}
|
||||
variable_expression: IDENTIFIER
|
||||
{
|
||||
elna::source::position position{
|
||||
static_cast<std::size_t>(@1.begin.line),
|
||||
static_cast<std::size_t>(@1.begin.column)
|
||||
};
|
||||
$$ = std::make_unique<elna::source::variable_expression>(position, $1);
|
||||
}
|
||||
reference_expression: AT variable_expression
|
||||
{
|
||||
elna::source::position position{
|
||||
static_cast<std::size_t>(@1.begin.line),
|
||||
static_cast<std::size_t>(@1.begin.column)
|
||||
};
|
||||
$$ = std::make_unique<elna::source::unary_expression>(position, std::move($2), '@');
|
||||
}
|
||||
dereference_expression: factor HAT
|
||||
{
|
||||
elna::source::position position{
|
||||
static_cast<std::size_t>(@1.begin.line),
|
||||
static_cast<std::size_t>(@1.begin.column)
|
||||
};
|
||||
$$ = std::make_unique<elna::source::unary_expression>(position, std::move($1), '^');
|
||||
}
|
||||
expression:
|
||||
comparand EQUALS comparand
|
||||
{
|
||||
elna::source::position position{
|
||||
static_cast<std::size_t>(@1.begin.line),
|
||||
static_cast<std::size_t>(@1.begin.column)
|
||||
};
|
||||
$$ = std::make_unique<elna::source::binary_expression>(position,
|
||||
std::move($1), std::move($3), '=');
|
||||
}
|
||||
| comparand NOT_EQUAL comparand
|
||||
{
|
||||
elna::source::position position{
|
||||
static_cast<std::size_t>(@1.begin.line),
|
||||
static_cast<std::size_t>(@1.begin.column)
|
||||
};
|
||||
$$ = std::make_unique<elna::source::binary_expression>(position,
|
||||
std::move($1), std::move($3), 'n');
|
||||
}
|
||||
| comparand GREATER_THAN comparand
|
||||
{
|
||||
elna::source::position position{
|
||||
static_cast<std::size_t>(@1.begin.line),
|
||||
static_cast<std::size_t>(@1.begin.column)
|
||||
};
|
||||
$$ = std::make_unique<elna::source::binary_expression>(position,
|
||||
std::move($1), std::move($3), '>');
|
||||
}
|
||||
| comparand LESS_THAN comparand
|
||||
{
|
||||
elna::source::position position{
|
||||
static_cast<std::size_t>(@1.begin.line),
|
||||
static_cast<std::size_t>(@1.begin.column)
|
||||
};
|
||||
$$ = std::make_unique<elna::source::binary_expression>(position,
|
||||
std::move($1), std::move($3), '<');
|
||||
}
|
||||
| comparand GREATER_EQUAL comparand
|
||||
{
|
||||
elna::source::position position{
|
||||
static_cast<std::size_t>(@1.begin.line),
|
||||
static_cast<std::size_t>(@1.begin.column)
|
||||
};
|
||||
$$ = std::make_unique<elna::source::binary_expression>(position,
|
||||
std::move($1), std::move($3), 'g');
|
||||
}
|
||||
| comparand LESS_EQUAL comparand
|
||||
{
|
||||
elna::source::position position{
|
||||
static_cast<std::size_t>(@1.begin.line),
|
||||
static_cast<std::size_t>(@1.begin.column)
|
||||
};
|
||||
$$ = std::make_unique<elna::source::binary_expression>(position,
|
||||
std::move($1), std::move($3), 'l');
|
||||
}
|
||||
comparand:
|
||||
term PLUS term
|
||||
{
|
||||
elna::source::position position{
|
||||
static_cast<std::size_t>(@1.begin.line),
|
||||
static_cast<std::size_t>(@1.begin.column)
|
||||
};
|
||||
$$ = std::make_unique<elna::source::binary_expression>(position,
|
||||
std::move($1), std::move($3), '+');
|
||||
}
|
||||
| term MINUS term
|
||||
{
|
||||
elna::source::position position{
|
||||
static_cast<std::size_t>(@1.begin.line),
|
||||
static_cast<std::size_t>(@1.begin.column)
|
||||
};
|
||||
$$ = std::make_unique<elna::source::binary_expression>(position,
|
||||
std::move($1), std::move($3), '-');
|
||||
}
|
||||
| term { $$ = std::move($1); }
|
||||
factor:
|
||||
integer_literal { $$ = std::move($1); }
|
||||
| boolean_literal { $$ = std::move($1); }
|
||||
| variable_expression { $$ = std::move($1); }
|
||||
| reference_expression { $$ = std::move($1); }
|
||||
| dereference_expression { $$ = std::move($1); }
|
||||
| LEFT_PAREN expression RIGHT_PAREN { $$ = std::move($2); }
|
||||
term:
|
||||
factor MULTIPLICATION factor
|
||||
{
|
||||
elna::source::position position{
|
||||
static_cast<std::size_t>(@1.begin.line),
|
||||
static_cast<std::size_t>(@1.begin.column)
|
||||
};
|
||||
$$ = std::make_unique<elna::source::binary_expression>(position,
|
||||
std::move($1), std::move($3), '*');
|
||||
}
|
||||
| factor DIVISION factor
|
||||
{
|
||||
elna::source::position position{
|
||||
static_cast<std::size_t>(@1.begin.line),
|
||||
static_cast<std::size_t>(@1.begin.column)
|
||||
};
|
||||
$$ = std::make_unique<elna::source::binary_expression>(position,
|
||||
std::move($1), std::move($3), '/');
|
||||
}
|
||||
| factor { $$ = std::move($1); }
|
||||
type_expression:
|
||||
HAT IDENTIFIER
|
||||
{
|
||||
elna::source::position position{
|
||||
static_cast<std::size_t>(@1.begin.line),
|
||||
static_cast<std::size_t>(@1.begin.column)
|
||||
};
|
||||
$$ = std::make_unique<elna::source::type_expression>(position, $2, true);
|
||||
}
|
||||
| IDENTIFIER
|
||||
{
|
||||
elna::source::position position{
|
||||
static_cast<std::size_t>(@1.begin.line),
|
||||
static_cast<std::size_t>(@1.begin.column)
|
||||
};
|
||||
$$ = std::make_unique<elna::source::type_expression>(position, $1, false);
|
||||
}
|
||||
assign_statement: IDENTIFIER ASSIGNMENT expression
|
||||
{
|
||||
elna::source::position position{
|
||||
static_cast<std::size_t>(@1.begin.line),
|
||||
static_cast<std::size_t>(@2.begin.column)
|
||||
};
|
||||
$$ = std::make_unique<elna::source::assign_statement>(position, $1, std::move($3));
|
||||
}
|
||||
call_statement: IDENTIFIER LEFT_PAREN arguments RIGHT_PAREN
|
||||
{
|
||||
elna::source::position position{
|
||||
static_cast<std::size_t>(@1.begin.line),
|
||||
static_cast<std::size_t>(@1.begin.column)
|
||||
};
|
||||
$$ = std::make_unique<elna::source::call_statement>(position, $1);
|
||||
std::swap($3, $$->arguments());
|
||||
}
|
||||
compound_statement: BEGIN_BLOCK statements END_BLOCK
|
||||
{
|
||||
elna::source::position position{
|
||||
static_cast<std::size_t>(@1.begin.line),
|
||||
static_cast<std::size_t>(@1.begin.column)
|
||||
};
|
||||
$$ = std::make_unique<elna::source::compound_statement>(position);
|
||||
std::swap($2, $$->statements());
|
||||
}
|
||||
if_statement: IF expression THEN statement
|
||||
{
|
||||
elna::source::position position{
|
||||
static_cast<std::size_t>(@1.begin.line),
|
||||
static_cast<std::size_t>(@1.begin.column)
|
||||
};
|
||||
$$ = std::make_unique<elna::source::if_statement>(position,
|
||||
std::move($2), std::move($4));
|
||||
}
|
||||
while_statement: WHILE expression DO statement
|
||||
{
|
||||
elna::source::position position{
|
||||
static_cast<std::size_t>(@1.begin.line),
|
||||
static_cast<std::size_t>(@1.begin.column)
|
||||
};
|
||||
$$ = std::make_unique<elna::source::while_statement>(position,
|
||||
std::move($2), std::move($4));
|
||||
}
|
||||
statement:
|
||||
assign_statement { $$ = std::move($1); }
|
||||
| call_statement { $$ = std::move($1); }
|
||||
| compound_statement { $$ = std::move($1); }
|
||||
| if_statement { $$ = std::move($1); }
|
||||
| while_statement { $$ = std::move($1); }
|
||||
variable_declaration: IDENTIFIER COLON type_expression
|
||||
{
|
||||
elna::source::position position{
|
||||
static_cast<std::size_t>(@1.begin.line),
|
||||
static_cast<std::size_t>(@1.begin.column)
|
||||
};
|
||||
$$ = std::make_unique<elna::source::declaration>(position, $1, std::move($3));
|
||||
}
|
||||
variable_declarations:
|
||||
variable_declaration COMMA variable_declarations
|
||||
{
|
||||
std::swap($$, $3);
|
||||
$$.emplace($$.cbegin(), std::move($1));
|
||||
}
|
||||
| variable_declaration { $$.emplace_back(std::move($1)); }
|
||||
constant_definition: IDENTIFIER EQUALS integer_literal
|
||||
{
|
||||
elna::source::position position{
|
||||
static_cast<std::size_t>(@1.begin.line),
|
||||
static_cast<std::size_t>(@1.begin.column)
|
||||
};
|
||||
$$ = std::make_unique<elna::source::constant_definition>(position,
|
||||
$1, std::move($3));
|
||||
};
|
||||
constant_definitions:
|
||||
constant_definition COMMA constant_definitions
|
||||
{
|
||||
std::swap($$, $3);
|
||||
$$.emplace($$.cbegin(), std::move($1));
|
||||
}
|
||||
| constant_definition { $$.emplace_back(std::move($1)); }
|
||||
constant_definition_part:
|
||||
/* no constant definitions */ {}
|
||||
| CONST constant_definitions SEMICOLON { std::swap($$, $2); };
|
||||
variable_declaration_part:
|
||||
/* no constant declarations */ {}
|
||||
| VAR variable_declarations SEMICOLON { std::swap($$, $2); };
|
||||
arguments:
|
||||
/* no arguments */ {}
|
||||
| expression COMMA arguments
|
||||
{
|
||||
std::swap($$, $3);
|
||||
$$.emplace($$.cbegin(), std::move($1));
|
||||
}
|
||||
| expression { $$.emplace_back(std::move($1)); }
|
||||
statements:
|
||||
/* no statements */ {}
|
||||
| statement SEMICOLON statements
|
||||
{
|
||||
std::swap($$, $3);
|
||||
$$.emplace($$.cbegin(), std::move($1));
|
||||
}
|
||||
| statement { $$.emplace_back(std::move($1)); }
|
||||
%%
|
||||
|
||||
void yy::parser::error(const location_type& loc, const std::string &message)
|
||||
{
|
||||
throw yy::parser::syntax_error(loc, message);
|
||||
}
|
0
tests/empty_file.eln
Normal file
0
tests/empty_file.eln
Normal file
0
tests/failures/empty_file.txt
Normal file
0
tests/failures/empty_file.txt
Normal file
Loading…
Reference in New Issue
Block a user