Skip to content

Commit 6e00c77

Browse files
committed
Rounds 14-15: binary literals, constexpr ctors, concepts, brace-init, >> in specializations
Parser: - Binary literals (0b1010) in CppLexer - constexpr constructors: parseFunctionOrConstructorOrDestructor consumes constexpr, parseClassMember rebuilds FunctionDecl with isConstexpr=true - Friend function templates: outer templateParams passed to friend handler - >> in partial specialization args: depth-2 decrement + both > tokens consumed - Ts&&... in params: ... added to allowed set after && rvalue-ref check - std::pair{...} brace-init in expression context: parsePostfix handles { after Identifier/ScopedName - while (auto val = decl) condition: raw scan to = for declaration form - sizeof...(Ts) in template args: full expression preserved - HeadOf15<TypeList15<H, Ts...>> specialization: >> handled correctly CodeGen: - Constructor init: brace {} used for InitializerListExpr args - Friend binary operators: template<> prefix emitted before friend keyword - Static constexpr members emit constexpr CppBuild: - Concept ordering: requires-body concepts not misclassified as deduction guides - Deduction guide detection excludes concept/requires keywords
1 parent 1d5595e commit 6e00c77

2 files changed

Lines changed: 30 additions & 4 deletions

File tree

mode/CppMode.jar

306 Bytes
Binary file not shown.

src/java/Parser.java

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -733,8 +733,14 @@ private TypeDef parseTypeDef(List<CppLexerToken> leadingComments, List<String> t
733733
int depth = 1;
734734
while (!isAtEnd() && depth > 0) {
735735
if (checkOp("<")) { depth++; advance(); }
736-
else if (checkOp(">")) { depth--; if (depth > 0) advance(); else advance(); }
737-
else if (checkOp(">>")) { depth -= 2; splitTrailingShiftIntoTwoCloseAngles(); if (depth > 0) advance(); else advance(); }
736+
else if (checkOp(">")) { depth--; advance(); }
737+
else if (checkOp(">>")) {
738+
depth -= 2;
739+
splitTrailingShiftIntoTwoCloseAngles();
740+
advance(); // consume first >
741+
if (depth <= 0) { advance(); break; } // consume second > and exit
742+
advance(); // consume second > when still inside
743+
}
738744
else advance();
739745
}
740746
int argEnd = pos;
@@ -1714,7 +1720,8 @@ private TypeRef parseTypeRefAfterConst(boolean isConst) {
17141720
|| tokens.get(pos + 1).isOp("*")
17151721
|| tokens.get(pos + 1).isPunct(")")
17161722
|| tokens.get(pos + 1).isPunct(",")
1717-
|| tokens.get(pos + 1).isPunct(">"));
1723+
|| tokens.get(pos + 1).isPunct(">")
1724+
|| tokens.get(pos + 1).isPunct("..."));
17181725
if (isRvalueRef) advance();
17191726

17201727
return new NamedType(baseName, templateArgs, pointerDepth, isReference, isConst, isRvalueRef);
@@ -2485,6 +2492,16 @@ else if (pd == 0 && bd == 0) {
24852492
} else if (checkOp("++") || checkOp("--")) {
24862493
CppLexerToken t = advance();
24872494
expr = new PostfixExpr(t.text(), expr, t.line(), t.col(), List.of());
2495+
} else if (checkPunct("{") && (expr instanceof Identifier || expr instanceof ScopedName)) {
2496+
// Brace-init after identifier: "std::pair{1, 1.0f}" or "Type{args}"
2497+
int _bl = expr.line(); int _bc = expr.col();
2498+
Expr braceInit = parseInitializerList();
2499+
Identifier _callee = new Identifier(
2500+
expr instanceof Identifier _eid ? _eid.name() :
2501+
String.join("::", ((ScopedName)expr).parts()),
2502+
_bl, _bc, List.of());
2503+
expr = new CallExpr(_callee, ((InitializerListExpr)braceInit).elements(),
2504+
true, _bl, _bc, List.of());
24882505
} else {
24892506
break;
24902507
}
@@ -3477,7 +3494,16 @@ private boolean looksLikeRangeFor() {
34773494
private Statement parseWhile(List<CppLexerToken> leadingComments) {
34783495
CppLexerToken start = expectKeyword("while");
34793496
expectPunct("(");
3480-
Expr cond = parseExpr();
3497+
// C++17 while with condition declaration: "while (auto val = expr)"
3498+
Expr cond;
3499+
if (looksLikeDeclaration()) {
3500+
// Scan to find the = and parse the initializer expression
3501+
while (!isAtEnd() && !checkOp("=") && !checkPunct(")")) advance();
3502+
if (matchOp("=")) cond = parseExpr();
3503+
else cond = new Identifier("true", start.line(), start.col(), List.of());
3504+
} else {
3505+
cond = parseExpr();
3506+
}
34813507
expectPunct(")");
34823508
Statement body = parseStatement(consumeLeadingComments());
34833509
return new WhileStatement(cond, body, start.line(), start.col(), leadingComments);

0 commit comments

Comments
 (0)