Skip to content

Commit 4adb8cc

Browse files
committed
Introduce binary + symbol concatenation
1 parent be38a61 commit 4adb8cc

File tree

9 files changed

+76
-2
lines changed

9 files changed

+76
-2
lines changed

src/FunctorOps.cpp

+3
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ char const* functorOpNameLegacy(FunctorOp op) {
4848
/** Binary Functor Operators */
4949
case FunctorOp::ADD:
5050
case FunctorOp::FADD:
51+
case FunctorOp::SSADD:
5152
case FunctorOp::UADD: return "+";
5253
case FunctorOp::SUB:
5354
case FunctorOp::USUB:
@@ -223,6 +224,8 @@ const std::vector<IntrinsicFunctorInfo> FUNCTOR_INTRINSICS = {
223224
VARIADIC(CAT, Symbol),
224225
OP_1(STRLEN, Symbol, Signed),
225226
OP_3(SUBSTR, Symbol, Signed, Signed, Symbol, false),
227+
228+
{functorOpNameSymbol(FOp::SSADD), {TAttr::Symbol, TAttr::Symbol}, TAttr::Symbol, FOp::SSADD, false, false},
226229
};
227230

228231
template <typename F>

src/FunctorOps.h

+1
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ enum class FunctorOp {
101101
FMIN, // min of two floats
102102
SMAX, // max of two symbols
103103
SMIN, // min of two symbols
104+
SSADD, // string-string concatenation
104105

105106
// Produces values within a numeric range. Format is `range(bgn, endExcl, step = 1)`.
106107
// e.g. `range(0, 5)` produces the sequence `0, 1, 2, 3, 4`.

src/interpreter/Engine.cpp

+8
Original file line numberDiff line numberDiff line change
@@ -784,6 +784,14 @@ RamDomain Engine::execute(const Node* node, Context& ctxt) {
784784
case FunctorOp::URANGE:
785785
case FunctorOp::FRANGE:
786786
fatal("ICE: functor `%s` must map onto `NestedIntrinsicOperator`", cur.getOperator());
787+
788+
case FunctorOp::SSADD: {
789+
auto sleft = execute(shadow.getChild(0), ctxt);
790+
auto sright = execute(shadow.getChild(1), ctxt);
791+
const std::string& strleft = getSymbolTable().decode(sleft);
792+
const std::string& strright = getSymbolTable().decode(sright);
793+
return getSymbolTable().encode(strleft + strright);
794+
}
787795
}
788796

789797
{UNREACHABLE_BAD_CASE_ANALYSIS}

src/synthesiser/Synthesiser.cpp

+31-2
Original file line numberDiff line numberDiff line change
@@ -1864,7 +1864,7 @@ void Synthesiser::emitCode(std::ostream& out, const Statement& stmt) {
18641864

18651865
// strings
18661866
case BinaryConstraintOp::MATCH: {
1867-
if (const StringConstant* str = dynamic_cast<const StringConstant*>(&rel.getLHS()); str) {
1867+
if (const StringConstant* str = as<StringConstant>(&rel.getLHS()); str) {
18681868
const auto& regex = synthesiser.compileRegex(str->getConstant());
18691869
if (regex) {
18701870
out << "std::regex_match(symTable.decode(";
@@ -1884,7 +1884,7 @@ void Synthesiser::emitCode(std::ostream& out, const Statement& stmt) {
18841884
break;
18851885
}
18861886
case BinaryConstraintOp::NOT_MATCH: {
1887-
if (const StringConstant* str = dynamic_cast<const StringConstant*>(&rel.getLHS()); str) {
1887+
if (const StringConstant* str = as<StringConstant>(&rel.getLHS()); str) {
18881888
const auto& regex = synthesiser.compileRegex(str->getConstant());
18891889
if (regex) {
18901890
out << "!std::regex_match(symTable.decode(";
@@ -2313,6 +2313,35 @@ void Synthesiser::emitCode(std::ostream& out, const Statement& stmt) {
23132313
case FunctorOp::URANGE:
23142314
case FunctorOp::FRANGE:
23152315
fatal("ICE: functor `%s` must map onto `NestedIntrinsicOperator`", op.getOperator());
2316+
2317+
case FunctorOp::SSADD: {
2318+
const StringConstant* lstr = as<StringConstant>(args[0]);
2319+
const StringConstant* rstr = as<StringConstant>(args[1]);
2320+
if (lstr && rstr) {
2321+
out << "RamSigned("
2322+
<< synthesiser.convertSymbol2Idx(lstr->getConstant() + rstr->getConstant()) << ")";
2323+
} else {
2324+
out << "symTable.encode(";
2325+
if (lstr) {
2326+
out << "R\"_(" << lstr->getConstant() << ")_\"";
2327+
} else {
2328+
out << "symTable.decode(";
2329+
dispatch(*args[0], out);
2330+
out << ")";
2331+
}
2332+
out << " + ";
2333+
if (rstr) {
2334+
out << "R\"_(" << rstr->getConstant() << ")_\"";
2335+
} else {
2336+
out << "symTable.decode(";
2337+
dispatch(*args[1], out);
2338+
out << ")";
2339+
}
2340+
out << ")";
2341+
}
2342+
break;
2343+
}
2344+
23162345
}
23172346
PRINT_END_COMMENT(out);
23182347

tests/evaluation/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,7 @@ positive_test(subtype2)
161161
positive_test(subtype)
162162
positive_test(sum-aggregate)
163163
positive_test(sum-aggregate2)
164+
positive_test(symbol_operations)
164165
positive_test(term)
165166
positive_test(unpacking)
166167
positive_test(unsigned_operations)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
pre--post
2+
pre-(a)
3+
pre-(b)
4+
(a)-post
5+
(b)-post
6+
(b)(a)(a)
7+
(a)(b)(b)
8+
one:1, pi:3.140000
9+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// Souffle - A Datalog Compiler
2+
// Copyright (c) 2023, The Souffle Developers. All rights reserved
3+
// Licensed under the Universal Permissive License v 1.0 as shown at:
4+
// - https://opensource.org/licenses/UPL
5+
// - <souffle root>/licenses/SOUFFLE-UPL.txt
6+
7+
.decl Add(s:symbol)
8+
Add("pre-" + "-post").
9+
Add("pre-" + s) :- some_symbol(s).
10+
Add(s + "-post") :- some_symbol(s).
11+
Add(s1 + s2 + s3) :-
12+
some_symbol(s1),
13+
some_symbol(s2),
14+
some_symbol(s3),
15+
s1 != s2,
16+
s1 != s3.
17+
Add("one:" + to_string(1) + ", pi:" + to_string(3.14) + "\n").
18+
19+
.decl some_symbol(s:symbol)
20+
some_symbol("(a)").
21+
some_symbol("(b)").
22+
23+
.output Add()

tests/evaluation/symbol_operations/symbol_operations.err

Whitespace-only changes.

tests/evaluation/symbol_operations/symbol_operations.out

Whitespace-only changes.

0 commit comments

Comments
 (0)