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);
|
parserParseTypeParams(p, d);
|
||||||
|
|
||||||
discard parserExpect(p, tkLBrace, "expected '{'");
|
discard parserExpect(p, tkLBrace, "expected '{'");
|
||||||
|
var lastWasComma: bool = false;
|
||||||
while !parserCheck(p, tkRBrace) && parserPeek(p, 0) != tkEndOfFile {
|
while !parserCheck(p, tkRBrace) && parserPeek(p, 0) != tkEndOfFile {
|
||||||
if fieldCount >= 256 {
|
if fieldCount >= 256 {
|
||||||
parserEmitDiag(p, line, col, "too many struct fields (max 255)");
|
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, tkNewLine) { discard parserAdvance(p); continue; }
|
||||||
if parserCheck(p, tkSemicolon) { discard parserAdvance(p); continue; }
|
if parserCheck(p, tkSemicolon) { discard parserAdvance(p); continue; }
|
||||||
// Commas are also valid field separators (incl. trailing comma before '}')
|
// 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 beforePos: int = p.pos;
|
||||||
let fName: LexToken = parserExpectIdentOrKeyword(p, "expected field name");
|
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");
|
discard parserExpect(p, tkColon, "expected ':' in struct field");
|
||||||
let fType: *TypeExpr = parserParseType(p);
|
let fType: *TypeExpr = parserParseType(p);
|
||||||
parserMatch(p, tkSemicolon);
|
parserMatch(p, tkSemicolon);
|
||||||
@@ -2196,6 +2199,7 @@ module Parser {
|
|||||||
d.fields[fieldCount].name = fName.text;
|
d.fields[fieldCount].name = fName.text;
|
||||||
d.fields[fieldCount].refFieldType = fType;
|
d.fields[fieldCount].refFieldType = fType;
|
||||||
fieldCount = fieldCount + 1;
|
fieldCount = fieldCount + 1;
|
||||||
|
lastWasComma = false;
|
||||||
}
|
}
|
||||||
d.fieldCount = fieldCount;
|
d.fieldCount = fieldCount;
|
||||||
discard parserExpect(p, tkRBrace, "expected '}'");
|
discard parserExpect(p, tkRBrace, "expected '}'");
|
||||||
|
|||||||
@@ -360,6 +360,34 @@ module Sema {
|
|||||||
i = i + 1;
|
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.callArgs = newFirst;
|
||||||
expr.callArgCount = newCount;
|
expr.callArgCount = newCount;
|
||||||
}
|
}
|
||||||
@@ -1227,6 +1255,10 @@ module Sema {
|
|||||||
|
|
||||||
// Struct init: TypeName { field: value, ... }
|
// Struct init: TypeName { field: value, ... }
|
||||||
if kind == ekStructInit {
|
if kind == ekStructInit {
|
||||||
|
let te: *TypeExpr = bux_alloc(sizeof(TypeExpr)) as *TypeExpr;
|
||||||
|
te.kind = tekNamed;
|
||||||
|
te.typeName = expr.structName;
|
||||||
|
expr.refType = te;
|
||||||
return tyNamed;
|
return tyNamed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user