Skip to content

Commit 99a9373

Browse files
committed
Implement ++ operator for string concatenation
1 parent fa3d83a commit 99a9373

File tree

5 files changed

+58
-5
lines changed

5 files changed

+58
-5
lines changed

man/rgbasm.5

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -548,7 +548,7 @@ There are a number of escape sequences you can use within a string:
548548
.El
549549
.Pp
550550
Multi-line strings are contained in triple quotes
551-
.Pq Ql \&"\&"\&"for instance\&"\&"\&" .
551+
.Pq Ql \&"\&"\&"for instance""" .
552552
Escape sequences work the same way in multi-line strings; however, literal newline characters will be included as-is, without needing to escape them with
553553
.Ql \er
554554
or
@@ -560,10 +560,19 @@ Inside them, backslashes and braces are treated like regular characters, so they
560560
For example, the raw string
561561
.Ql #"\et\e1{s}\e"
562562
is equivalent to the regular string
563-
.Ql "\e\et\e\e1\e{s}\e\e" .
563+
.Ql \&"\e\et\e\e1\e{s}\e\e" .
564564
(Note that this prevents raw strings from including the double quote character.)
565565
Raw strings also may be contained in triple quotes for them to be multi-line, so they can include literal newline or quote characters (although still not three quotes in a row).
566566
.Pp
567+
You can use the
568+
.Sq ++
569+
operator to concatenate two strings.
570+
.Ql \&"str" ++ \&"ing"
571+
is equivalent to
572+
.Ql \&"string" ,
573+
or to
574+
.Ql STRCAT("str", \&"ing") .
575+
.Pp
567576
The following functions operate on string expressions, and return strings themselves.
568577
.Bl -column "STRSLICE(str, start, stop)"
569578
.It Sy Name Ta Sy Operation

src/asm/lexer.cpp

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1774,12 +1774,17 @@ static Token yylex_NORMAL() {
17741774

17751775
// Handle ambiguous 1- or 2-char tokens
17761776

1777-
case '+': // Either += or ADD
1778-
if (peek() == '=') {
1777+
case '+': // Either +=, ADD, or CAT
1778+
switch (peek()) {
1779+
case '=':
17791780
shiftChar();
17801781
return Token(T_(POP_ADDEQ));
1782+
case '+':
1783+
shiftChar();
1784+
return Token(T_(OP_CAT));
1785+
default:
1786+
return Token(T_(OP_ADD));
17811787
}
1782-
return Token(T_(OP_ADD));
17831788

17841789
case '-': // Either -= or SUB
17851790
if (peek() == '=') {

src/asm/parser.y

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,9 @@
125125
%token OP_MUL "*" OP_DIV "/" OP_MOD "%"
126126
%token OP_EXP "**"
127127

128+
// String operators
129+
%token OP_CAT "++"
130+
128131
// Comparison operators
129132
%token OP_LOGICEQU "==" OP_LOGICNE "!="
130133
%token OP_LOGICLT "<" OP_LOGICGT ">"
@@ -147,6 +150,7 @@
147150
%left OP_AND OP_OR OP_XOR
148151
%left OP_SHL OP_SHR OP_USHR
149152
%left OP_MUL OP_DIV OP_MOD
153+
%left OP_CAT
150154
%precedence NEG // applies to unary OP_LOGICNOT, OP_ADD, OP_SUB, OP_NOT
151155
%right OP_EXP
152156

@@ -1613,6 +1617,10 @@ string_literal:
16131617
STRING {
16141618
$$ = std::move($1);
16151619
}
1620+
| string OP_CAT string {
1621+
$$ = std::move($1);
1622+
$$.append($3);
1623+
}
16161624
| OP_STRSLICE LPAREN string COMMA iconst COMMA iconst RPAREN {
16171625
size_t len = strlenUTF8($3, false);
16181626
uint32_t start = adjustNegativeIndex($5, len, "STRSLICE");

test/asm/string-concat.asm

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
SECTION "test", ROM0
2+
3+
MACRO test
4+
assert !strcmp(\1, \2)
5+
ENDM
6+
7+
test "a"++"b", "ab"
8+
test "a"++""++"b", "ab"
9+
test "a"++"b", strcat("a", "b")
10+
test "a"++"b"++"c", strcat("a","b","c")
11+
test "" ++ "", ""
12+
test strupr("a") ++ strlwr("B"), "Ab"
13+
14+
def str equs "hi"
15+
test #str ++ strupr(#str), "hiHI"
16+
test "a" ++ """b""" ++ strupr("c") ++ strslice(#str, 0, 0), "abC"
17+
18+
charmap "a", 1
19+
charmap "b", 2
20+
charmap "ab", 12
21+
assert "a" + "b" == 3
22+
assert "a" ++ "b" == 12
23+
24+
; errors
25+
assert 2 ++ 2 == 4
26+
ld a, [hl++]

test/asm/string-concat.err

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
error: string-concat.asm(25):
2+
syntax error, unexpected ++
3+
error: string-concat.asm(26):
4+
syntax error, unexpected ++, expecting ] or + or -
5+
error: Assembly aborted (2 errors)!

0 commit comments

Comments
 (0)