feat(selfhost-diag): struct-literal refType, unknown named args, comma leniency, debug cleanup
This commit is contained in:
+10
-6
@@ -2168,6 +2168,7 @@ module Parser {
|
||||
parserParseTypeParams(p, d);
|
||||
|
||||
discard parserExpect(p, tkLBrace, "expected '{'");
|
||||
var lastWasComma: bool = false;
|
||||
while !parserCheck(p, tkRBrace) && parserPeek(p, 0) != tkEndOfFile {
|
||||
if fieldCount >= 256 {
|
||||
parserEmitDiag(p, line, col, "too many struct fields (max 255)");
|
||||
@@ -2176,14 +2177,16 @@ module Parser {
|
||||
if parserCheck(p, tkNewLine) { discard parserAdvance(p); continue; }
|
||||
if parserCheck(p, tkSemicolon) { discard parserAdvance(p); continue; }
|
||||
// Commas are also valid field separators (incl. trailing comma before '}')
|
||||
if parserCheck(p, tkComma) { discard parserAdvance(p); continue; }
|
||||
if parserCheck(p, tkComma) {
|
||||
if fieldCount == 0 || lastWasComma {
|
||||
parserEmitDiag(p, parserCurToken(p).line, parserCurToken(p).column, "expected field name");
|
||||
}
|
||||
lastWasComma = true;
|
||||
discard parserAdvance(p);
|
||||
continue;
|
||||
}
|
||||
let beforePos: int = p.pos;
|
||||
let fName: LexToken = parserExpectIdentOrKeyword(p, "expected field name");
|
||||
if fieldCount >= 250 && fieldCount <= 256 {
|
||||
PrintLine(String_Concat("RAW fieldCount=", bux_int_to_str(fieldCount as int64)));
|
||||
PrintLine(String_Concat("RAW fName=", fName.text));
|
||||
PrintLine(String_Concat("RAW pos=", bux_int_to_str(p.pos as int64)));
|
||||
}
|
||||
discard parserExpect(p, tkColon, "expected ':' in struct field");
|
||||
let fType: *TypeExpr = parserParseType(p);
|
||||
parserMatch(p, tkSemicolon);
|
||||
@@ -2196,6 +2199,7 @@ module Parser {
|
||||
d.fields[fieldCount].name = fName.text;
|
||||
d.fields[fieldCount].refFieldType = fType;
|
||||
fieldCount = fieldCount + 1;
|
||||
lastWasComma = false;
|
||||
}
|
||||
d.fieldCount = fieldCount;
|
||||
discard parserExpect(p, tkRBrace, "expected '}'");
|
||||
|
||||
@@ -360,6 +360,34 @@ module Sema {
|
||||
i = i + 1;
|
||||
}
|
||||
|
||||
// Report named args that match no parameter
|
||||
var checkArg: *ExprList = expr.callArgs;
|
||||
while checkArg != null as *ExprList {
|
||||
if !String_Eq(checkArg.argName, "") {
|
||||
var foundName: bool = false;
|
||||
var j: int = 0;
|
||||
while j < decl.paramCount {
|
||||
var pj: *Param = null as *Param;
|
||||
if j == 0 { pj = &decl.param0; }
|
||||
else if j == 1 { pj = &decl.param1; }
|
||||
else if j == 2 { pj = &decl.param2; }
|
||||
else if j == 3 { pj = &decl.param3; }
|
||||
else if j == 4 { pj = &decl.param4; }
|
||||
else if j == 5 { pj = &decl.param5; }
|
||||
else if j == 6 { pj = &decl.param6; }
|
||||
else if j == 7 { pj = &decl.param7; }
|
||||
else if j == 8 { pj = &decl.param8; }
|
||||
if String_Eq(checkArg.argName, pj.name) { foundName = true; }
|
||||
j = j + 1;
|
||||
}
|
||||
if !foundName {
|
||||
Sema_EmitError(sema, expr.line, expr.column,
|
||||
String_Concat("unknown argument name '", String_Concat(checkArg.argName, "'")));
|
||||
}
|
||||
}
|
||||
checkArg = checkArg.next;
|
||||
}
|
||||
|
||||
expr.callArgs = newFirst;
|
||||
expr.callArgCount = newCount;
|
||||
}
|
||||
@@ -1227,6 +1255,10 @@ module Sema {
|
||||
|
||||
// Struct init: TypeName { field: value, ... }
|
||||
if kind == ekStructInit {
|
||||
let te: *TypeExpr = bux_alloc(sizeof(TypeExpr)) as *TypeExpr;
|
||||
te.kind = tekNamed;
|
||||
te.typeName = expr.structName;
|
||||
expr.refType = te;
|
||||
return tyNamed;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user