Allow number indexing of struct fields.

Better error messages on failed struct access.
This commit is contained in:
Sage Vaillancourt 2022-04-13 16:57:06 -04:00 committed by Sage Vaillancourt
parent 80255af52e
commit e326af38f8
2 changed files with 14 additions and 5 deletions

View File

@ -307,13 +307,22 @@ Object structAccess(Object* params, unused int length, unused struct Environment
Object field = params[1];
struct StructDef* structDef = getStructAt(structo.structObject->definition);
for (int i = 0; i < structDef->fieldCount; i++) {
if (strcmp(field.string, structDef->names[i]) == 0) {
return cloneObject(structo.structObject->fields[i]);
if (isStringy(field)) {
for (int i = 0; i < structDef->fieldCount; i++) {
if (strcmp(field.string, structDef->names[i]) == 0) {
return cloneObject(structo.structObject->fields[i]);
}
}
throw(NULL_PARSE, "Could not find struct field named `%s`", field.string);
}
if (isNumber(field)) {
if (structDef->fieldCount < field.number || field.number < 0) {
throw(NULL_PARSE, "Could not find struct field at index %ld. Struct `%s` has %d fields.", field.number, structDef->name, structDef->fieldCount);
}
return cloneObject(structo.structObject->fields[field.number]);
}
throw(NULL_PARSE, "Could not find field named `%s`", field.string);
throw(BAD_PARAMS, "Struct fields should be indexed with a string or a number, but received a %s", getTypeName(&field));
}
Result parse(struct Slice* slices)

View File

@ -122,7 +122,7 @@ fn(def, "def",
);
tfn(structAccess, "poss",
({ expect(isStruct), expect(isStringy), anyType }),
({ expect(isStruct), anyType, anyType }),
"Get the value of a struct's field",
"(struct Post (title body))\n "
"(def p (Post \"This is a title\" \"This is the body\"))\n "