Skip to content

Commit 07f884b

Browse files
committed
Merge branch 'dev' into main
2 parents 7622b33 + f7c36a7 commit 07f884b

15 files changed

Lines changed: 588 additions & 255 deletions

CMakePresets.json

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -8,41 +8,45 @@
88
"configurePresets": [
99
{
1010
"name": "dev",
11-
"displayName": "Dev (Release, Linux)",
11+
"displayName": "Linux (Release, GCC)",
1212
"generator": "Unix Makefiles",
1313
"binaryDir": "build",
1414
"cacheVariables": {
1515
"CMAKE_BUILD_TYPE": "Release",
16+
"CMAKE_C_COMPILER": "gcc",
17+
"CMAKE_CXX_COMPILER": "g++",
1618
"QBIN_BUILD_TESTS": "ON"
1719
}
1820
},
1921
{
2022
"name": "dev-debug",
21-
"displayName": "Dev (Debug, Linux)",
23+
"displayName": "Linux (Debug, GCC)",
2224
"generator": "Unix Makefiles",
2325
"binaryDir": "build-debug",
2426
"cacheVariables": {
2527
"CMAKE_BUILD_TYPE": "Debug",
28+
"CMAKE_C_COMPILER": "gcc",
29+
"CMAKE_CXX_COMPILER": "g++",
2630
"QBIN_BUILD_TESTS": "ON"
2731
}
2832
},
2933
{
30-
"name": "win-msvc",
31-
"displayName": "Windows MSVC (Release)",
34+
"name": "win-release",
35+
"displayName": "Windows (Release, VS2022)",
3236
"generator": "Visual Studio 17 2022",
3337
"architecture": "x64",
34-
"binaryDir": "build-win",
38+
"binaryDir": "build\\win-release",
3539
"cacheVariables": {
3640
"CMAKE_BUILD_TYPE": "Release",
3741
"QBIN_BUILD_TESTS": "ON"
3842
}
3943
},
4044
{
41-
"name": "win-msvc-debug",
42-
"displayName": "Windows MSVC (Debug)",
45+
"name": "win-debug",
46+
"displayName": "Windows (Debug, VS2022)",
4347
"generator": "Visual Studio 17 2022",
4448
"architecture": "x64",
45-
"binaryDir": "build-win-debug",
49+
"binaryDir": "build\\win-debug",
4650
"cacheVariables": {
4751
"CMAKE_BUILD_TYPE": "Debug",
4852
"QBIN_BUILD_TESTS": "ON"
@@ -59,12 +63,12 @@
5963
"configurePreset": "dev-debug"
6064
},
6165
{
62-
"name": "win-msvc",
63-
"configurePreset": "win-msvc"
66+
"name": "win-release",
67+
"configurePreset": "win-release"
6468
},
6569
{
66-
"name": "win-msvc-debug",
67-
"configurePreset": "win-msvc-debug"
70+
"name": "win-debug",
71+
"configurePreset": "win-debug"
6872
}
6973
],
7074
"testPresets": [
@@ -79,13 +83,13 @@
7983
"output": { "outputOnFailure": true }
8084
},
8185
{
82-
"name": "win-msvc",
83-
"configurePreset": "win-msvc",
86+
"name": "win-release",
87+
"configurePreset": "win-release",
8488
"output": { "outputOnFailure": true }
8589
},
8690
{
87-
"name": "win-msvc-debug",
88-
"configurePreset": "win-msvc-debug",
91+
"name": "win-debug",
92+
"configurePreset": "win-debug",
8993
"output": { "outputOnFailure": true }
9094
}
9195
]

compiler/CMakeLists.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,19 @@ set(QBIN_COMPILER_SOURCES
2020
src/tools.cpp
2121
src/custom_gate.cpp
2222
src/qasm_frontend.cpp
23+
src/qasm_lexer.cpp
24+
src/qasm_expander.cpp
25+
src/qasm_irbuilder.cpp
2326
)
2427

2528
set(QBIN_COMPILER_HEADERS
2629
include/qbin_compiler/compiler.hpp
2730
include/qbin_compiler/qasm_frontend.hpp
2831
include/qbin_compiler/custom_gate.hpp
2932
include/qbin_compiler/tools.hpp
33+
include/qbin_compiler/qasm_lexer.hpp
34+
include/qbin_compiler/qasm_expander.hpp
35+
include/qbin_compiler/qasm_irbuilder.hpp
3036
)
3137

3238
add_executable(qbin-compile ${QBIN_COMPILER_SOURCES} ${QBIN_COMPILER_HEADERS})
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
#pragma once
2+
#include <string>
3+
#include <vector>
4+
#include "qbin_compiler/custom_gate.hpp"
5+
6+
namespace qbin_compiler {
7+
namespace frontend {
8+
9+
/**
10+
* StatementExpander:
11+
* Expands raw QASM statements into canonical form:
12+
* - Normalizes measure/barrier/reset forms
13+
* - Expands custom gates via GateRegistry
14+
* - Ensures trailing semicolons
15+
*/
16+
struct StatementExpander {
17+
static std::vector<std::string> expand(
18+
const std::vector<std::string>& nondef_lines,
19+
const GateRegistry& gates,
20+
bool verbose);
21+
};
22+
23+
} // namespace frontend
24+
} // namespace qbin_compiler
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#pragma once
2+
#include <string>
3+
#include <vector>
4+
#include "qbin_compiler/qasm_frontend.hpp"
5+
#include "qbin_compiler/custom_gate.hpp"
6+
7+
namespace qbin_compiler {
8+
namespace frontend {
9+
10+
/**
11+
* IRBuilder:
12+
* Converts canonical QASM statements into Program (IR).
13+
*/
14+
struct IRBuilder {
15+
static Program emit(
16+
const std::vector<std::string>& canonical,
17+
const std::unordered_map<std::string, std::pair<int,int>>& qregs,
18+
const std::unordered_map<std::string, std::pair<int,int>>& cregs,
19+
bool verbose);
20+
};
21+
22+
} // namespace frontend
23+
} // namespace qbin_compiler
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#pragma once
2+
#include <string>
3+
#include <vector>
4+
5+
namespace qbin_compiler {
6+
namespace qasm {
7+
8+
/**
9+
* LineProcessor: takes raw QASM text and produces cleaned lines.
10+
* Responsibilities:
11+
* - Remove // comments
12+
* - Remove block comments
13+
* - Normalize CR/LF
14+
* - Return non-empty raw lines
15+
*/
16+
class LineProcessor {
17+
public:
18+
/// Process raw QASM source text into a vector of lines.
19+
static std::vector<std::string> preprocess(const std::string& src);
20+
};
21+
22+
} // namespace qasm
23+
} // namespace qbin_compiler

compiler/src/qasm_expander.cpp

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
#include "qbin_compiler/qasm_expander.hpp"
2+
#include "qbin_compiler/tools.hpp"
3+
4+
#include <regex>
5+
6+
using qbin_compiler::util::to_lower_ascii;
7+
using qbin_compiler::util::trim;
8+
using qbin_compiler::util::vlog;
9+
10+
namespace qbin_compiler {
11+
namespace frontend {
12+
13+
std::vector<std::string> StatementExpander::expand(
14+
const std::vector<std::string>& nondef_lines,
15+
const GateRegistry& gates,
16+
bool verbose)
17+
{
18+
std::vector<std::string> canonical;
19+
20+
auto ensure_semi = [](const std::string& t) {
21+
if (!t.empty() && t.back() == ';') return t;
22+
std::string r = t;
23+
r.push_back(';');
24+
return r;
25+
};
26+
27+
auto expand_recursive = [&](auto&& self,
28+
const std::string& stmt,
29+
std::vector<std::string>& out) -> void {
30+
std::string s = trim(stmt);
31+
if (s.empty()) return;
32+
std::string sl = to_lower_ascii(s);
33+
34+
// skip barrier/reset
35+
if (sl.rfind("barrier", 0) == 0) { vlog(verbose, "skip barrier"); return; }
36+
if (sl.rfind("reset", 0) == 0) { vlog(verbose, "skip reset"); return; }
37+
38+
// measure
39+
{
40+
static std::regex rem1(R"(^\s*measure\s+(.+?)\s*->\s*(.+?)\s*;?$)", std::regex::icase);
41+
static std::regex rem2(R"(^\s*(.+?)\s*=\s*measure\s+(.+?)\s*;?$)", std::regex::icase);
42+
std::smatch m;
43+
if (std::regex_match(s, m, rem1)) {
44+
std::string q = trim(m[1].str());
45+
std::string c = trim(m[2].str());
46+
out.push_back(ensure_semi(c + " = measure " + q));
47+
return;
48+
}
49+
if (std::regex_match(s, m, rem2)) {
50+
out.push_back(ensure_semi(trim(m[1].str()) + " = measure " + trim(m[2].str())));
51+
return;
52+
}
53+
}
54+
55+
// two-qubit gates
56+
{
57+
static std::regex r2(R"(^\s*(cx|cz|swap)\s+(.+?)\s*,\s*(.+?)\s*;?$)", std::regex::icase);
58+
std::smatch m;
59+
if (std::regex_match(s, m, r2)) {
60+
std::string op = to_lower_ascii(m[1].str());
61+
std::string a = trim(m[2].str());
62+
std::string b = trim(m[3].str());
63+
out.push_back(ensure_semi(op + " " + a + ", " + b));
64+
return;
65+
}
66+
}
67+
68+
// one-qubit gates
69+
{
70+
static std::regex r1(R"(^\s*(h|x|y|z|s|sdg|t|tdg|sx|sxdg)\s+(.+?)\s*;?$)", std::regex::icase);
71+
std::smatch m;
72+
if (std::regex_match(s, m, r1)) {
73+
std::string op = to_lower_ascii(m[1].str());
74+
std::string a = trim(m[2].str());
75+
out.push_back(ensure_semi(op + " " + a));
76+
return;
77+
}
78+
}
79+
80+
// parametric gates
81+
{
82+
static std::regex rp(R"(^\s*(rx|ry|rz|phase)\s*\(\s*(.+?)\s*\)\s+(.+?)\s*;?$)", std::regex::icase);
83+
std::smatch m;
84+
if (std::regex_match(s, m, rp)) {
85+
std::string op = to_lower_ascii(m[1].str());
86+
std::string expr = trim(m[2].str());
87+
std::string a = trim(m[3].str());
88+
out.push_back(ensure_semi(op + "(" + expr + ") " + a));
89+
return;
90+
}
91+
}
92+
93+
// custom gate calls
94+
{
95+
static std::regex rcall(R"(^\s*([A-Za-z_]\w*)\s+(.+?)\s*;?$)");
96+
std::smatch m;
97+
if (std::regex_match(s, m, rcall)) {
98+
std::string name = to_lower_ascii(trim(m[1].str()));
99+
std::string rest = trim(m[2].str());
100+
if (gates.hasGate(name)) {
101+
auto args = util::split_commas(rest, true);
102+
auto expanded = gates.getGate(name).expand(args);
103+
for (auto& e : expanded) {
104+
self(self, e, out);
105+
}
106+
return;
107+
}
108+
}
109+
}
110+
111+
// fallback: keep as-is
112+
out.push_back(ensure_semi(s));
113+
};
114+
115+
// process all lines
116+
for (auto& s : nondef_lines) {
117+
std::vector<std::string> tmp;
118+
expand_recursive(expand_recursive, s, tmp);
119+
canonical.insert(canonical.end(), tmp.begin(), tmp.end());
120+
}
121+
122+
return canonical;
123+
}
124+
125+
} // namespace frontend
126+
} // namespace qbin_compiler

0 commit comments

Comments
 (0)