Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

v3 MVP #165

Merged
merged 84 commits into from
Nov 13, 2023
Merged
Show file tree
Hide file tree
Changes from 75 commits
Commits
Show all changes
84 commits
Select commit Hold shift + click to select a range
66f0676
Adding FetchContent blocks for fmt and range-v3 in case they are not …
rturrado Oct 1, 2023
7f39194
Updated cqasm-utils functions to use ranges (now one-liners), and add…
rturrado Sep 29, 2023
4f7bbc2
Added cqasm-utils tests to test/CMakeLists.txt.
rturrado Sep 29, 2023
93a1a8e
Added range-v3 as a Conan dependency.
rturrado Oct 3, 2023
a03bb75
Added v3x-mvp tests.
rturrado Oct 3, 2023
95793c6
Updated grammar and visitor.
rturrado Oct 3, 2023
6c16c7a
Temporarily making V1 analyzer and resolver case-sensitive.
rturrado Oct 3, 2023
3398e77
Temporarily changing test/v1x/parsing.
rturrado Oct 3, 2023
59d606a
Added list of requirements to v3 lexer.
rturrado Oct 3, 2023
0521573
Added list of requirements to v3 lexer.
rturrado Oct 4, 2023
3410250
WIP.
rturrado Oct 9, 2023
5390253
v1x/cqasm-analyzer:
rturrado Oct 11, 2023
9076bd8
Updated parser grammar.
rturrado Oct 11, 2023
d0c699c
Fixed include files for src/v1x/cqasm-{types,values}.tree.
rturrado Oct 11, 2023
96a9042
Using nested namespaces for v1x/cqasm-instruction.
rturrado Oct 11, 2023
44413d2
Adding generate_tree_py calls for v3 parser.
rturrado Oct 11, 2023
7ac0966
Adding v3x/semantic-{instruction,primitives,semantic-helper}.
rturrado Oct 11, 2023
aa59adc
Added v3x/cqasm-semantic.tree, and updated v3x/cqasm-{ast,types,value…
rturrado Oct 11, 2023
fdc88a1
Revert "Using nested namespaces for v1x/cqasm-instruction."
rturrado Oct 12, 2023
628da61
Minor changes to v1x header files:
rturrado Oct 12, 2023
83379fe
Far away from everything but:
rturrado Oct 12, 2023
3696ac3
Removing the array supertype.
rturrado Oct 12, 2023
61cadb1
Reorganized test folder to accommodate future v3x tests.
rturrado Oct 13, 2023
c1351fc
src/CMakeLists.txt: fixed appending of v3 tree-gen files to CQASM_V3X…
rturrado Oct 13, 2023
4382891
Amend of commit below.
rturrado Oct 13, 2023
2499db3
Minor changes to v1x header files:
rturrado Oct 13, 2023
5a2ebf9
- Implemented BuildTreeGenAstVisitor.cpp.
rturrado Oct 13, 2023
ab28db7
Removed Toy v1 parsing resource files.
rturrado Oct 15, 2023
69d6719
Added V3 MVP parsing resource files.
rturrado Oct 15, 2023
1031d40
Changes to the type system: added int and real types to cqasm-types.t…
rturrado Oct 15, 2023
c1ada2c
Removed semantic.3.0.golden.txt files for the time being.
rturrado Oct 17, 2023
ecf94ac
Added and updated some res/v3x/parsing files.
rturrado Oct 17, 2023
a9ce86e
Changed v3 lexer to admit version numbers with multi-digit major and …
rturrado Oct 17, 2023
7bd242c
Version lexer admits C++ style single line comments (starting with '/…
rturrado Oct 17, 2023
8d09f33
Finished adding and updating the res/v3x/parsing files.
rturrado Oct 17, 2023
28d901a
parsing.cpp: removed version comparison, as I'm interested in purely …
rturrado Oct 17, 2023
4ddd9c9
Removed unused import statement 'get'.
rturrado Oct 17, 2023
4943430
Minor changes to the lexer:
rturrado Oct 19, 2023
f5f9fdc
Added helper functions to Version class.
rturrado Oct 20, 2023
04fdad5
Added skeletons for AnalyzeTreeGenAstVisitor.
rturrado Oct 21, 2023
0a54d10
Added v3 resolver.
rturrado Oct 22, 2023
5204b25
Updated res/v3x/ast.golden.txt files. Because:
rturrado Oct 24, 2023
d22d23c
Added res/v3x/parsing/version/*/semantic.3.0.golden.txt files.
rturrado Oct 24, 2023
89a3ec7
We are doing semantic analysis for v3 files containing only a version.
rturrado Oct 24, 2023
bf2ccc3
Updated res/v3x/ast.golden.txt files. Because:
rturrado Oct 25, 2023
dfd695e
Added bit_array_of_0_b and qubit_array_of_0_q tests.
rturrado Oct 25, 2023
cffca93
Merge remote-tracking branch 'origin/v3-mvp' into v3-mvp
rturrado Oct 25, 2023
4539cd9
Added semantic checks for variable definitions.
rturrado Oct 25, 2023
90161c4
Added some res/v3/parsing files that are already passing the semantic…
rturrado Oct 25, 2023
18f9347
Updated some res/v3x/ast.golden.txt files. Because:
rturrado Oct 26, 2023
94ce29b
Added semantic checks for instructions and expressions.
rturrado Oct 26, 2023
a159d5b
Updated some res/v3x/semantic.3.0.golden.txt files. Because:
rturrado Oct 31, 2023
f9e9ca8
Minor changes to v1 code:
rturrado Oct 31, 2023
f7470d7
Registered two overloads for 'cnot' and 'h' using qubit arrays.
rturrado Oct 31, 2023
b97203a
Added semantic checks for indexes.
rturrado Oct 31, 2023
47d57bb
Updated some res/v3x/semantic.3.0.golden.txt files:
rturrado Nov 2, 2023
6005107
Added semantic checks for the measure instruction.
rturrado Nov 2, 2023
613da36
Added "pi, eu, im, tau" tests.
rturrado Nov 3, 2023
3a48a8d
Renamed measure_statement folder to measure_instruction.
rturrado Nov 3, 2023
7951995
Renamed res/v1x/parsing folders by changing dashes to underscores, be…
rturrado Nov 4, 2023
ff0b8b8
Removed test/v1x/dirent-compat.h
rturrado Nov 4, 2023
e8a9b16
Updated test/{v1x,v3x}/parsing.cpp files.
rturrado Nov 4, 2023
1e470e8
Updated res/v3x/parsing/measure_instruction/{bit_and_qubit,no_qubit} …
rturrado Nov 4, 2023
3ff51a0
Minor changes to src/{v1x,v3x}/cqasm-values.cpp.
rturrado Nov 4, 2023
dceb804
Added check_input_indices_equals_output_indices to src/v3x/AnalyzeTre…
rturrado Nov 4, 2023
391fa4c
Changed res/v3x/parsing/measure_instruction/input.cq files so they do…
rturrado Nov 4, 2023
25601e4
Measure instruction can only work with one input operand (qubit, qubi…
rturrado Nov 4, 2023
87356c4
Updated res/v3x/parsing/measure_instruction files.
rturrado Nov 4, 2023
dc3401d
Fixed some errors and suggestions pointed out by clang-tidy.
rturrado Nov 4, 2023
efe1a75
Restored v1 code to be case-insensitive again. The Overload templates…
rturrado Nov 5, 2023
e1a82b4
Changed line endings from DOS to Unix.
rturrado Nov 5, 2023
cae4a33
Fixed v10.qc test.
rturrado Nov 5, 2023
8fb61e8
Changed ssize_t to tree::signed_size_t to fix Windows compilation.
rturrado Nov 5, 2023
3c56567
Updated res/v3x/parsing/*/*/semantic.3.0.golden.txt files. Because:
rturrado Nov 5, 2023
8c432be
Added request_same_size_input_output_indices flag to a semantic::Inst…
rturrado Nov 5, 2023
07f24b0
Trying to fix Python (macos-latest) build.
rturrado Nov 6, 2023
fcd84c5
Trying to fix C++ tests (clang/MacOS/ARM64) build.
rturrado Nov 6, 2023
d07de07
Added more 'measure_instruction' tests.
rturrado Nov 6, 2023
92ef8c7
Updated res/v3x/parsing/tests. Because:
rturrado Nov 9, 2023
e6945bb
Removed output_operands from instruction in src/v3x/cqasm-ast.tree.
rturrado Nov 9, 2023
97711e4
Removed the Maybe<Mapping> parameter from the resolver.
rturrado Nov 9, 2023
2088e76
Renamed request_same_size_input_output_indices to request_qubit_and_b…
rturrado Nov 10, 2023
49bc8ec
Added python/module/cqasm/v3x folder.
rturrado Nov 10, 2023
fa2828b
Fixed some clang-tidy warnings.
rturrado Nov 10, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
16 changes: 7 additions & 9 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -35,17 +35,16 @@ option(LIBQASM_BUILD_TESTS
OFF
)

# Compatibility mode. When enabled, the legacy API headers in src/library are
# added to the public headers of the cqasm target. To enable this in your CMake
# project, add `option(LIBQASM_COMPAT "" ON)` before the `add_subdirectory`
# command.
# Compatibility mode.
# When enabled, the legacy API headers in src/library are added to the public headers of the cqasm target.
# To enable this in your CMake project, add `option(LIBQASM_COMPAT "" ON)` before the `add_subdirectory` command.
option(LIBQASM_COMPAT
"whether the legacy API headers should be added to the cqasm library"
OFF
)

# Whether the Python module should be built. This should only be enabled for
# setup.py's builds.
# Whether the Python module should be built.
# This should only be enabled for setup.py's builds.
option(LIBQASM_BUILD_PYTHON
"Whether the Python module should be built"
OFF
Expand All @@ -70,8 +69,7 @@ set(LIBQASM_PYTHON_EXT ""
)
mark_as_advanced(LIBQASM_PYTHON_EXT)

# The Python library requires the compatibility headers, so make sure those are
# enabled.
# The Python library requires the compatibility headers, so make sure those are enabled.
if(LIBQASM_BUILD_PYTHON AND NOT LIBQASM_COMPAT)
message(SEND_ERROR "The Python library requires the compatibility headers! Please add -DLIBQASM_COMPAT=ON")
endif()
Expand Down Expand Up @@ -126,4 +124,4 @@ if(LIBQASM_BUILD_PYTHON)
add_subdirectory(python)
endif()

endif() # NOT TARGET cqasm
endif() # NOT TARGET cqasm
3 changes: 2 additions & 1 deletion conanfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from conan.errors import ConanInvalidConfiguration
from conan.tools.build import check_min_cppstd
from conan.tools.cmake import CMakeToolchain, CMakeDeps, CMake
from conan.tools.files import copy, get
from conan.tools.files import copy
from conan.tools.scm import Version


Expand Down Expand Up @@ -58,6 +58,7 @@ def build_requirements(self):
if self.settings.arch != "armv8":
self.tool_requires("flex/2.6.4")
self.tool_requires("bison/3.8.2")
self.requires("range-v3/0.12.0")
if self.settings.arch != "armv8":
self.tool_requires("zulu-openjdk/11.0.19")
if self.options.build_tests:
Expand Down
9 changes: 2 additions & 7 deletions include/cqasm-annotations.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,8 @@

#include <string>

namespace cqasm {

/**
* Namespace for tree annotation objects used by libqasm.
*/
namespace annotations {
namespace cqasm::annotations {

/**
* Source location annotation object, containing source file line numbers etc.
Expand Down Expand Up @@ -68,5 +64,4 @@ class SourceLocation {
*/
std::ostream &operator<<(std::ostream &os, const SourceLocation &object);

} // namespace annotations
} // namespace cqasm
} // namespace cqasm::annotations
171 changes: 171 additions & 0 deletions include/cqasm-overload.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
#pragma once

#include "cqasm-overload.hpp"
#include "cqasm-tree.hpp"

#include <exception>
#include <string>
#include <unordered_map>
#include <utility> // pair
#include <vector>


/**
* Overload templates are case-sensitive.
* The code using them can be case-insensitive by converting to lowercase before adding and resolving an overload.
*/
namespace cqasm::overload {

struct NameResolutionFailure : public std::exception {};
struct OverloadResolutionFailure : public std::exception {};

/**
* Represents a possible overload for the parameter types of a function, gate, or error model.
* T is some tag type identifying the overload.
*/
template <class T, class TypeBase>
class Overload {
using Type = tree::One<TypeBase>;
using Types = tree::Any<TypeBase>;

T tag_;
Types param_types_;
rturrado marked this conversation as resolved.
Show resolved Hide resolved

public:
Overload(const T &tag, const Types &param_types) : tag_{ tag }, param_types_{ param_types} {}
Overload(const Overload &other) : tag_{ other.tag_ }, param_types_{ other.param_types_ } {}
Overload(Overload &&other) noexcept : tag_{ std::move(other.tag_) }, param_types_{ other.param_types_ } {}
Overload& operator=(const Overload &other) { tag_ = other.tag_; param_types_ = other.param_types_; return *this; }
Overload& operator=(Overload &&other) noexcept { tag_ = std::move(other.tag_); param_types_ = other.param_types_; return *this; }

/**
* Returns the tag for this overload.
*/
[[nodiscard]] const T &get_tag() const {
return tag_;
}

/**
* Returns the number of parameters for this overload.
*/
[[nodiscard]] std::size_t num_params() const {
return param_types_.size();
}

/**
* Returns the parameter type object for the parameter at the specified index.
*/
[[nodiscard]] const Type &param_type_at(std::size_t index) const {
return param_types_.at(index);
}
};

/**
* Represents a set of possible overloads for the parameter types of a
* function, gate, or error model. T is some tag type identifying the overload.
* In case of a function, T would contain at least the return type, but maybe
* also a lambda to represent the actual function. Note that ambiguous
* overloads are silently resolved by using the last applicable overload, so
* more specific overloads should always be added last.
*/
template <class T, class TypeBase, class Node>
class OverloadResolver {
using Type = tree::One<TypeBase>;
using Types = tree::Any<TypeBase>;
using Value = tree::One<Node>;
using Values = tree::Any<Node>;

std::vector<Overload<T, TypeBase>> overloads;

public:
/**
* Adds a possible overload to the resolver. Note that ambiguous
* overloads are silently resolved by using the last applicable overload,
* so more specific overloads should always be added last.
*/
void add_overload(const T &tag, const Types &param_types) {
overloads.emplace_back(tag, param_types);
}

/**
* Tries to resolve which overload belongs to the given argument list, if
* any. Raises an OverloadResolutionFailure if no applicable overload
* exists, otherwise the tag corresponding to the first proper overload and
* the appropriately promoted vector of value pointers are returned.
*/
[[nodiscard]] std::pair<T, Values> resolve(const Values &args) {
for (auto overload = overloads.rbegin(); overload != overloads.rend(); ++overload) {
if (overload->num_params() != args.size()) {
continue;
}
Values promoted_args;
bool ok = true;
for (size_t i = 0; i < args.size(); i++) {
auto promoted_arg = promote(args.at(i), overload->param_type_at(i));
if (promoted_arg.empty()) {
ok = false;
break;
}
promoted_args.add(promoted_arg);
}
if (ok) {
return std::pair<T, Values>(overload->get_tag(), promoted_args);
}
}
throw OverloadResolutionFailure{};
}
};

/**
* Table of overloaded callables with case-sensitive identifier matching.
* T is the tag type of the callable/overload pair.
*/
template <class T, class TypeBase, class Node>
class OverloadedNameResolver {
using Type = tree::One<TypeBase>;
using Types = tree::Any<TypeBase>;
using Value = tree::One<Node>;
using Values = tree::Any<Node>;

std::unordered_map<std::string, OverloadResolver<T, TypeBase, Node>> table;

public:
/**
* Registers a callable.
* Matching will be done case-sensitively.
* The param_types variadic specifies the amount and types of the parameters that
* (this particular overload of) the function expects.
* The C++ implementation of the function can assume that
* the value list it gets is of the right size and the values are of the right types.
* Note that ambiguous overloads are silently resolved by using the last applicable overload,
* so more specific overloads should always be added last.
*/
virtual void add_overload(const std::string &name, const T &tag, const Types &param_types) {
auto entry = table.find(name);
if (entry == table.end()) {
auto resolver = OverloadResolver<T, TypeBase, Node>();
resolver.add_overload(tag, param_types);
table.insert(std::pair<std::string, OverloadResolver<T, TypeBase, Node>>(name, std::move(resolver)));
} else {
entry->second.add_overload(tag, param_types);
}
}

/**
* Resolves the particular overload for the callable with the given case-sensitively matched name.
* Raises NameResolutionFailure if no callable with the requested name is found,
* raises an OverloadResolutionFailure if overload resolution fails, or otherwise
* returns the tag of the first applicable callable/overload pair and
* the appropriately promoted vector of value pointers.
*/
[[nodiscard]] virtual std::pair<T, Values> resolve(const std::string &name, const Values &args) {
auto entry = table.find(name);
if (entry == table.end()) {
throw NameResolutionFailure{};
} else {
return entry->second.resolve(args);
}
}
};

} // cqasm::overload
4 changes: 2 additions & 2 deletions include/cqasm-utils.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,12 @@ namespace utils {
/**
* Makes a string lowercase.
*/
std::string lowercase(const std::string &name);
std::string to_lowercase(const std::string &name);

/**
* Case-insensitive string compare.
*/
bool case_insensitive_equals(const std::string &lhs, const std::string &rhs);
bool equal_case_insensitive(const std::string &lhs, const std::string &rhs);

} // namespace utils
} // namespace cqasm
48 changes: 30 additions & 18 deletions include/cqasm-version.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,17 +23,7 @@ namespace cqasm::version {
* Version number primitive used within the AST and semantic trees.
*/
class Version : public std::vector<std::int64_t> {
public:
/**
* Default constructor.
*/
Version() = default;

/**
* Constructs a version object from a string.
*/
explicit Version(const std::string &version);

private:
/**
* Compares this version against the other version.
* Returns:
Expand All @@ -44,15 +34,37 @@ class Version : public std::vector<std::int64_t> {
*/
[[nodiscard]] int compare(const Version &other) const;

public:
/**
* Compares this version against the other version.
* Returns:
* 1 if this version is newer than the other,
* -1 if this version is older than the other, or
* 0 if both versions are the same.
* When there is a mismatch in the number of components between the versions, missing components are interpreted as 0.
* Default constructor.
*/
Version() = default;

/**
* Constructs a version object from a string.
*/
Version(const std::string &version);

/**
* Constructs a version object from an array of chars.
*/
[[nodiscard]] int compare(const std::string &other) const;
Version(const char *version);

[[nodiscard]] bool equal(const Version &rhs) const {
return compare(rhs) == 0;
}
[[nodiscard]] bool less_than(const Version &rhs) const {
return compare(rhs) < 0;
}
[[nodiscard]] bool more_than(const Version &rhs) const {
return compare(rhs) > 0;
}
[[nodiscard]] bool less_than_or_equal(const Version &rhs) const {
return !more_than(rhs);
}
[[nodiscard]] bool more_than_or_equal(const Version &rhs) const {
rturrado marked this conversation as resolved.
Show resolved Hide resolved
return !less_than(rhs);
}
};

/**
Expand Down
Loading
Loading