mirror of
https://github.com/krgamestudios/Toy.git
synced 2026-04-15 23:04:08 +10:00
Resolved #25, Indexing an array with a non-integer causes an error
This commit is contained in:
@@ -336,9 +336,9 @@ int _index(Interpreter* interpreter, LiteralArray* arguments) {
|
|||||||
if (IS_ARRAY(compound)) {
|
if (IS_ARRAY(compound)) {
|
||||||
//array slice
|
//array slice
|
||||||
if (IS_NULL(op)) {
|
if (IS_NULL(op)) {
|
||||||
//parse out the booleans & their defaults
|
//parse out the blanks & their defaults
|
||||||
if (!IS_NULL(first)) {
|
if (!IS_NULL(first)) {
|
||||||
if (IS_BOOLEAN(first)) {
|
if (IS_INDEX_BLANK(first)) {
|
||||||
freeLiteral(first);
|
freeLiteral(first);
|
||||||
first = TO_INTEGER_LITERAL(0);
|
first = TO_INTEGER_LITERAL(0);
|
||||||
}
|
}
|
||||||
@@ -351,7 +351,7 @@ int _index(Interpreter* interpreter, LiteralArray* arguments) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!IS_NULL(second)) {
|
if (!IS_NULL(second)) {
|
||||||
if (IS_BOOLEAN(second)) {
|
if (IS_INDEX_BLANK(second)) {
|
||||||
freeLiteral(second);
|
freeLiteral(second);
|
||||||
second = TO_INTEGER_LITERAL(AS_ARRAY(compound)->count - 1);
|
second = TO_INTEGER_LITERAL(AS_ARRAY(compound)->count - 1);
|
||||||
}
|
}
|
||||||
@@ -363,7 +363,7 @@ int _index(Interpreter* interpreter, LiteralArray* arguments) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IS_NULL(third) || IS_BOOLEAN(third)) {
|
if (IS_NULL(third) || IS_INDEX_BLANK(third)) {
|
||||||
freeLiteral(third);
|
freeLiteral(third);
|
||||||
third = TO_INTEGER_LITERAL(1);
|
third = TO_INTEGER_LITERAL(1);
|
||||||
}
|
}
|
||||||
@@ -442,9 +442,9 @@ int _index(Interpreter* interpreter, LiteralArray* arguments) {
|
|||||||
|
|
||||||
//array slice assignment
|
//array slice assignment
|
||||||
if (IS_STRING(op) && equalsRefStringCString(AS_STRING(op), "=")) {
|
if (IS_STRING(op) && equalsRefStringCString(AS_STRING(op), "=")) {
|
||||||
//parse out the booleans & their defaults
|
//parse out the blanks & their defaults
|
||||||
if (!IS_NULL(first)) {
|
if (!IS_NULL(first)) {
|
||||||
if (IS_BOOLEAN(first)) {
|
if (IS_INDEX_BLANK(first)) {
|
||||||
freeLiteral(first);
|
freeLiteral(first);
|
||||||
first = TO_INTEGER_LITERAL(0);
|
first = TO_INTEGER_LITERAL(0);
|
||||||
}
|
}
|
||||||
@@ -457,7 +457,7 @@ int _index(Interpreter* interpreter, LiteralArray* arguments) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!IS_NULL(second)) {
|
if (!IS_NULL(second)) {
|
||||||
if (IS_BOOLEAN(second)) {
|
if (IS_INDEX_BLANK(second)) {
|
||||||
freeLiteral(second);
|
freeLiteral(second);
|
||||||
second = TO_INTEGER_LITERAL(AS_INTEGER(first));
|
second = TO_INTEGER_LITERAL(AS_INTEGER(first));
|
||||||
}
|
}
|
||||||
@@ -469,7 +469,7 @@ int _index(Interpreter* interpreter, LiteralArray* arguments) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IS_NULL(third) || IS_BOOLEAN(third)) {
|
if (IS_NULL(third) || IS_INDEX_BLANK(third)) {
|
||||||
freeLiteral(third);
|
freeLiteral(third);
|
||||||
third = TO_INTEGER_LITERAL(1);
|
third = TO_INTEGER_LITERAL(1);
|
||||||
}
|
}
|
||||||
@@ -656,9 +656,9 @@ int _index(Interpreter* interpreter, LiteralArray* arguments) {
|
|||||||
if (IS_STRING(compound)) {
|
if (IS_STRING(compound)) {
|
||||||
//string slice
|
//string slice
|
||||||
if (IS_NULL(op)) {
|
if (IS_NULL(op)) {
|
||||||
//parse out the booleans & their defaults
|
//parse out the blanks & their defaults
|
||||||
if (!IS_NULL(first)) {
|
if (!IS_NULL(first)) {
|
||||||
if (IS_BOOLEAN(first)) {
|
if (IS_INDEX_BLANK(first)) {
|
||||||
freeLiteral(first);
|
freeLiteral(first);
|
||||||
first = TO_INTEGER_LITERAL(0);
|
first = TO_INTEGER_LITERAL(0);
|
||||||
}
|
}
|
||||||
@@ -672,7 +672,7 @@ int _index(Interpreter* interpreter, LiteralArray* arguments) {
|
|||||||
|
|
||||||
int compoundLength = AS_STRING(compound)->length;
|
int compoundLength = AS_STRING(compound)->length;
|
||||||
if (!IS_NULL(second)) {
|
if (!IS_NULL(second)) {
|
||||||
if (IS_BOOLEAN(second)) {
|
if (IS_INDEX_BLANK(second)) {
|
||||||
freeLiteral(second);
|
freeLiteral(second);
|
||||||
second = TO_INTEGER_LITERAL(compoundLength);
|
second = TO_INTEGER_LITERAL(compoundLength);
|
||||||
}
|
}
|
||||||
@@ -684,7 +684,7 @@ int _index(Interpreter* interpreter, LiteralArray* arguments) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IS_NULL(third) || IS_BOOLEAN(third)) {
|
if (IS_NULL(third) || IS_INDEX_BLANK(third)) {
|
||||||
freeLiteral(third);
|
freeLiteral(third);
|
||||||
third = TO_INTEGER_LITERAL(1);
|
third = TO_INTEGER_LITERAL(1);
|
||||||
}
|
}
|
||||||
@@ -769,9 +769,9 @@ int _index(Interpreter* interpreter, LiteralArray* arguments) {
|
|||||||
|
|
||||||
//string slice assignment
|
//string slice assignment
|
||||||
else if (IS_STRING(op) && equalsRefStringCString(AS_STRING(op), "=")) {
|
else if (IS_STRING(op) && equalsRefStringCString(AS_STRING(op), "=")) {
|
||||||
//parse out the booleans & their defaults
|
//parse out the blanks & their defaults
|
||||||
if (!IS_NULL(first)) {
|
if (!IS_NULL(first)) {
|
||||||
if (IS_BOOLEAN(first)) {
|
if (IS_INDEX_BLANK(first)) {
|
||||||
freeLiteral(first);
|
freeLiteral(first);
|
||||||
first = TO_INTEGER_LITERAL(0);
|
first = TO_INTEGER_LITERAL(0);
|
||||||
}
|
}
|
||||||
@@ -785,7 +785,7 @@ int _index(Interpreter* interpreter, LiteralArray* arguments) {
|
|||||||
|
|
||||||
int compoundLength = AS_STRING(compound)->length;
|
int compoundLength = AS_STRING(compound)->length;
|
||||||
if (!IS_NULL(second)) {
|
if (!IS_NULL(second)) {
|
||||||
if (IS_BOOLEAN(second)) {
|
if (IS_INDEX_BLANK(second)) {
|
||||||
freeLiteral(second);
|
freeLiteral(second);
|
||||||
second = TO_INTEGER_LITERAL(compoundLength);
|
second = TO_INTEGER_LITERAL(compoundLength);
|
||||||
}
|
}
|
||||||
@@ -797,7 +797,7 @@ int _index(Interpreter* interpreter, LiteralArray* arguments) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IS_NULL(third) || IS_BOOLEAN(third)) {
|
if (IS_NULL(third) || IS_INDEX_BLANK(third)) {
|
||||||
freeLiteral(third);
|
freeLiteral(third);
|
||||||
third = TO_INTEGER_LITERAL(1);
|
third = TO_INTEGER_LITERAL(1);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1176,6 +1176,11 @@ static unsigned char* collateCompilerHeaderOpt(Compiler* compiler, int* size, bo
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case LITERAL_INDEX_BLANK:
|
||||||
|
emitByte(&collation, &capacity, &count, LITERAL_INDEX_BLANK);
|
||||||
|
//blank has no following value
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
fprintf(stderr, ERROR "[internal] Unknown literal type encountered within literal cache: %d\n" RESET, compiler->literalCache.literals[i].type);
|
fprintf(stderr, ERROR "[internal] Unknown literal type encountered within literal cache: %d\n" RESET, compiler->literalCache.literals[i].type);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|||||||
@@ -1563,7 +1563,22 @@ static bool execIndex(Interpreter* interpreter, bool assignIntermediate) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//call the _index function
|
//call the _index function
|
||||||
_index(interpreter, &arguments);
|
if (_index(interpreter, &arguments) < 0) {
|
||||||
|
interpreter->errorOutput("Something went wrong while indexing: ");
|
||||||
|
printLiteralCustom(idn, interpreter->errorOutput);
|
||||||
|
interpreter->errorOutput("\n");
|
||||||
|
|
||||||
|
//clean up
|
||||||
|
freeLiteral(third);
|
||||||
|
freeLiteral(second);
|
||||||
|
freeLiteral(first);
|
||||||
|
freeLiteral(compound);
|
||||||
|
if (freeIdn) {
|
||||||
|
freeLiteral(idn);
|
||||||
|
}
|
||||||
|
freeLiteralArray(&arguments);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
//clean up
|
//clean up
|
||||||
freeLiteral(third);
|
freeLiteral(third);
|
||||||
@@ -1667,7 +1682,7 @@ static bool execIndexAssign(Interpreter* interpreter) {
|
|||||||
pushLiteralArray(&arguments, op); //it expects an assignment "opcode"
|
pushLiteralArray(&arguments, op); //it expects an assignment "opcode"
|
||||||
|
|
||||||
//call the _index function
|
//call the _index function
|
||||||
if (_index(interpreter, &arguments) == -1) {
|
if (_index(interpreter, &arguments) < 0) {
|
||||||
//clean up
|
//clean up
|
||||||
freeLiteral(assign);
|
freeLiteral(assign);
|
||||||
freeLiteral(third);
|
freeLiteral(third);
|
||||||
@@ -1715,7 +1730,25 @@ static bool execIndexAssign(Interpreter* interpreter) {
|
|||||||
pushLiteralArray(&arguments, result);
|
pushLiteralArray(&arguments, result);
|
||||||
pushLiteralArray(&arguments, op);
|
pushLiteralArray(&arguments, op);
|
||||||
|
|
||||||
_index(interpreter, &arguments);
|
if (_index(interpreter, &arguments) < 0) {
|
||||||
|
interpreter->errorOutput("Something went wrong while indexing: ");
|
||||||
|
printLiteralCustom(idn, interpreter->errorOutput);
|
||||||
|
interpreter->errorOutput("\n");
|
||||||
|
|
||||||
|
//clean up
|
||||||
|
freeLiteral(assign);
|
||||||
|
freeLiteral(third);
|
||||||
|
freeLiteral(second);
|
||||||
|
freeLiteral(first);
|
||||||
|
freeLiteral(compound);
|
||||||
|
if (freeIdn) {
|
||||||
|
freeLiteral(idn);
|
||||||
|
}
|
||||||
|
freeLiteral(op);
|
||||||
|
freeLiteralArray(&arguments);
|
||||||
|
freeLiteral(result);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
freeLiteral(result);
|
freeLiteral(result);
|
||||||
result = popLiteralArray(&interpreter->stack);
|
result = popLiteralArray(&interpreter->stack);
|
||||||
@@ -2240,6 +2273,17 @@ static void readInterpreterSections(Interpreter* interpreter) {
|
|||||||
freeLiteral(typeLiteral);
|
freeLiteral(typeLiteral);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case LITERAL_INDEX_BLANK:
|
||||||
|
//read the blank
|
||||||
|
pushLiteralArray(&interpreter->literalCache, TO_INDEX_BLANK_LITERAL);
|
||||||
|
|
||||||
|
#ifndef TOY_EXPORT
|
||||||
|
if (command.verbose) {
|
||||||
|
printf("(blank)\n");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -206,6 +206,7 @@ Literal copyLiteral(Literal original) {
|
|||||||
|
|
||||||
case LITERAL_FUNCTION_INTERMEDIATE: //caries a compiler
|
case LITERAL_FUNCTION_INTERMEDIATE: //caries a compiler
|
||||||
case LITERAL_FUNCTION_NATIVE:
|
case LITERAL_FUNCTION_NATIVE:
|
||||||
|
case LITERAL_INDEX_BLANK:
|
||||||
//no copying possible
|
//no copying possible
|
||||||
return original;
|
return original;
|
||||||
|
|
||||||
@@ -333,6 +334,9 @@ bool literalsAreEqual(Literal lhs, Literal rhs) {
|
|||||||
fprintf(stderr, ERROR "[internal] Can't compare intermediate functions\n" RESET);
|
fprintf(stderr, ERROR "[internal] Can't compare intermediate functions\n" RESET);
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
case LITERAL_INDEX_BLANK:
|
||||||
|
return false;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
//should never be seen
|
//should never be seen
|
||||||
fprintf(stderr, ERROR "[internal] Unrecognized literal type in equality: %d\n" RESET, lhs.type);
|
fprintf(stderr, ERROR "[internal] Unrecognized literal type in equality: %d\n" RESET, lhs.type);
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ typedef enum {
|
|||||||
LITERAL_FUNCTION_INTERMEDIATE, //used to process functions in the compiler only
|
LITERAL_FUNCTION_INTERMEDIATE, //used to process functions in the compiler only
|
||||||
LITERAL_FUNCTION_ARG_REST, //used to process function rest parameters only
|
LITERAL_FUNCTION_ARG_REST, //used to process function rest parameters only
|
||||||
LITERAL_FUNCTION_NATIVE, //for handling native functions only
|
LITERAL_FUNCTION_NATIVE, //for handling native functions only
|
||||||
|
LITERAL_INDEX_BLANK, //for blank indexing i.e. arr[:]
|
||||||
} LiteralType;
|
} LiteralType;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@@ -104,6 +105,10 @@ typedef struct {
|
|||||||
#define TO_TYPE_LITERAL(value, c) ((Literal){ LITERAL_TYPE, { .type.typeOf = value, .type.constant = c, .type.subtypes = NULL, .type.capacity = 0, .type.count = 0 }})
|
#define TO_TYPE_LITERAL(value, c) ((Literal){ LITERAL_TYPE, { .type.typeOf = value, .type.constant = c, .type.subtypes = NULL, .type.capacity = 0, .type.count = 0 }})
|
||||||
#define TO_OPAQUE_LITERAL(value, t) ((Literal){ LITERAL_OPAQUE, { .opaque.ptr = value, .opaque.tag = t }})
|
#define TO_OPAQUE_LITERAL(value, t) ((Literal){ LITERAL_OPAQUE, { .opaque.ptr = value, .opaque.tag = t }})
|
||||||
|
|
||||||
|
//BUGFIX: For blank indexing
|
||||||
|
#define IS_INDEX_BLANK(value) ((value).type == LITERAL_INDEX_BLANK)
|
||||||
|
#define TO_INDEX_BLANK_LITERAL ((Literal){LITERAL_INDEX_BLANK, { .integer = 0 }})
|
||||||
|
|
||||||
TOY_API void freeLiteral(Literal literal);
|
TOY_API void freeLiteral(Literal literal);
|
||||||
|
|
||||||
#define IS_TRUTHY(x) _isTruthy(x)
|
#define IS_TRUTHY(x) _isTruthy(x)
|
||||||
|
|||||||
@@ -726,9 +726,9 @@ static Opcode indexAccess(Parser* parser, ASTNode** nodeHandle) { //TODO: fix in
|
|||||||
ASTNode* third = NULL;
|
ASTNode* third = NULL;
|
||||||
|
|
||||||
//booleans indicate blank slice indexing
|
//booleans indicate blank slice indexing
|
||||||
emitASTNodeLiteral(&first, TO_BOOLEAN_LITERAL(true));
|
emitASTNodeLiteral(&first, TO_INDEX_BLANK_LITERAL);
|
||||||
emitASTNodeLiteral(&second, TO_BOOLEAN_LITERAL(true));
|
emitASTNodeLiteral(&second, TO_INDEX_BLANK_LITERAL);
|
||||||
emitASTNodeLiteral(&third, TO_BOOLEAN_LITERAL(true));
|
emitASTNodeLiteral(&third, TO_INDEX_BLANK_LITERAL);
|
||||||
|
|
||||||
bool readFirst = false; //pattern matching is bullcrap
|
bool readFirst = false; //pattern matching is bullcrap
|
||||||
|
|
||||||
|
|||||||
7
test/scripts/mustfail/index-arrays-non-integer.toy
Normal file
7
test/scripts/mustfail/index-arrays-non-integer.toy
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
var a: [int] = [1, 2, 3];
|
||||||
|
print a[a];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
print "All good";
|
||||||
@@ -130,6 +130,7 @@ int main() {
|
|||||||
"declare-types-array.toy",
|
"declare-types-array.toy",
|
||||||
"declare-types-dictionary-key.toy",
|
"declare-types-dictionary-key.toy",
|
||||||
"declare-types-dictionary-value.toy",
|
"declare-types-dictionary-value.toy",
|
||||||
|
"index-arrays-non-integer.toy",
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user