From e326af38f85f9b186997bdc36842f7c08ca62614 Mon Sep 17 00:00:00 2001 From: Sage Vaillancourt Date: Wed, 13 Apr 2022 16:57:06 -0400 Subject: [PATCH] Allow number indexing of struct fields. Better error messages on failed struct access. --- src/pebblisp.c | 17 +++++++++++++---- src/pebblisp.h | 2 +- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/src/pebblisp.c b/src/pebblisp.c index 4ccf682..e02a695 100644 --- a/src/pebblisp.c +++ b/src/pebblisp.c @@ -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) diff --git a/src/pebblisp.h b/src/pebblisp.h index fefad61..079992e 100644 --- a/src/pebblisp.h +++ b/src/pebblisp.h @@ -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 "