Fixed some indexing bugs

This commit is contained in:
2022-09-07 18:43:32 +01:00
parent 8f61575579
commit 9a55ff221a
7 changed files with 89 additions and 32 deletions

View File

@@ -8,6 +8,15 @@ This is the Toy programming language interpreter, written in C.
Special thanks to http://craftinginterpreters.com/ for their fantastic book that set me on this path. Special thanks to http://craftinginterpreters.com/ for their fantastic book that set me on this path.
## Nifty Features
* Simple C-like syntax
* Bytecode intermediate compilation
* `import` and `export` variables from the host program
* Optional, but robust type system
* functions and types are first-class citizens
* Fancy slice notation for strings, arrays and dictionaries (`print greeting[0:4:-1]; //prints "olleh"`)
## Building ## Building
Simply run make in the root directory. Simply run make in the root directory.
@@ -15,7 +24,7 @@ Simply run make in the root directory.
## Syntax ## Syntax
``` ```
import "standard"; //for a bunch of utility functions import standard; //for a bunch of utility functions
print "Hello world"; //"print" is a keyword print "Hello world"; //"print" is a keyword
@@ -36,13 +45,13 @@ fn makeCounter() { //declare a function like this
return counter; //closures are explicitly supported return counter; //closures are explicitly supported
} }
var counter = makeCounter(); var tally = makeCounter();
print counter(); //1 print tally(); //1
print counter(); //2 print tally(); //2
print counter(); //3 print tally(); //3
export makeCounter; //export this variable to the host program export tally; //export this variable to the host program
``` ```
# License # License

View File

@@ -2,14 +2,24 @@
var t: type = astype [int]; fn makeCounter() {
var u: type = astype [t]; var total: int = 0;
var a: u; fn counter(): int {
return ++total;
}
t = astype [float]; //redefnition return counter;
}
var b: u; var tally = makeCounter();
print typeof a; //<[<int>]> print tally(); //1
print typeof b; //<[<float>]> print tally(); //2
print tally(); //3
export tally;
//heck yeah!
import tally as tally2;
print tally2(); //4

View File

@@ -1,8 +1,22 @@
//test basic indexing
{
var week = ["monday", "tuesday", "wednesday", "thursday", "friday", "saturday", "sunday"];
assert week[1] == "tuesday", "basic indexing failed (single element)";
assert week[1:1] == ["tuesday"], "basic indexing failed (single element as array)";
assert week[:] == ["monday", "tuesday", "wednesday", "thursday", "friday", "saturday", "sunday"], "basic default indexing failed (first and second)";
assert week[::] == ["monday", "tuesday", "wednesday", "thursday", "friday", "saturday", "sunday"], "basic default indexing failed (first, second and third)";
}
//test basic replacement //test basic replacement
{ {
var week = ["monday", "tuesday", "wednesday", "thursday", "friday", "saturday", "sunday"]; var week = ["monday", "tuesday", "wednesday", "thursday", "friday", "saturday", "sunday"];
week[3] = "Holiday"; week[3:3] = "Holiday";
assert week == ["monday", "tuesday", "wednesday", "Holiday", "friday", "saturday", "sunday"], "basic replacement failed"; assert week == ["monday", "tuesday", "wednesday", "Holiday", "friday", "saturday", "sunday"], "basic replacement failed";
} }

View File

@@ -1,13 +1,24 @@
//test basic replacement //test basic indexing
var greeting: string = "hello world"; var greeting: string = "hello world";
assert greeting[1] == "e", "basic default index failed (first)";
assert greeting[:] == "hello world", "basic default index failed (first and second)";
assert greeting[::] == "hello world", "basic default index failed (first, second & third)";
assert greeting[0:4] == "hello", "basic indexing failed";
//test basic replacement
greeting[0:4] = "goodnight"; greeting[0:4] = "goodnight";
assert greeting == "goodnight world", "basic replacement failed"; assert greeting == "goodnight world", "basic replacement failed";
//test backwards string //test backwards string
assert greeting[::-1] == "dlrow thgindoog", "backwards string failed"; assert greeting[::-1] == "dlrow thgindoog", "backwards string failed";
assert greeting[11:15:-1] == "dlrow", "backwards indexed string failed";
//test string weird manipulation //test string weird manipulation

View File

@@ -1386,7 +1386,7 @@ static bool execIndex(Interpreter* interpreter) {
freeLiteral(second); freeLiteral(second);
freeLiteral(first); freeLiteral(first);
freeLiteral(compound); freeLiteral(compound);
freeLiteral(idn); //freeLiteral(idn); //since compound is freed, idn is still pointing there
return false; return false;
} }

View File

@@ -329,7 +329,7 @@ int _index(Interpreter* interpreter, LiteralArray* arguments) {
if (!IS_NULL(second)) { if (!IS_NULL(second)) {
if (IS_BOOLEAN(second)) { if (IS_BOOLEAN(second)) {
freeLiteral(second); freeLiteral(second);
second = TO_INTEGER_LITERAL(AS_ARRAY(compound)->count); second = TO_INTEGER_LITERAL(AS_ARRAY(compound)->count - 1);
} }
} }
@@ -387,10 +387,10 @@ int _index(Interpreter* interpreter, LiteralArray* arguments) {
LiteralArray* result = ALLOCATE(LiteralArray, 1); LiteralArray* result = ALLOCATE(LiteralArray, 1);
initLiteralArray(result); initLiteralArray(result);
int min = AS_INTEGER(third) > 0 ? 0 : AS_INTEGER(second) - 1; int min = AS_INTEGER(third) > 0 ? AS_INTEGER(first) : AS_INTEGER(second);
//copy compound into result //copy compound into result
for (int i = min; i >= 0 && i <= AS_ARRAY(compound)->count && i >= AS_INTEGER(first) && i < AS_INTEGER(second); i += AS_INTEGER(third)) { for (int i = min; i >= 0 && i <= AS_ARRAY(compound)->count && i >= AS_INTEGER(first) && i <= AS_INTEGER(second); i += AS_INTEGER(third)) {
Literal idx = TO_INTEGER_LITERAL(i); Literal idx = TO_INTEGER_LITERAL(i);
Literal tmp = getLiteralArray(AS_ARRAY(compound), idx); Literal tmp = getLiteralArray(AS_ARRAY(compound), idx);
pushLiteralArray(result, tmp); pushLiteralArray(result, tmp);
@@ -417,7 +417,7 @@ int _index(Interpreter* interpreter, LiteralArray* arguments) {
if (!IS_NULL(second)) { if (!IS_NULL(second)) {
if (IS_BOOLEAN(second)) { if (IS_BOOLEAN(second)) {
freeLiteral(second); freeLiteral(second);
second = TO_INTEGER_LITERAL(AS_ARRAY(compound)->count); second = TO_INTEGER_LITERAL(AS_INTEGER(first));
} }
} }
@@ -487,15 +487,20 @@ int _index(Interpreter* interpreter, LiteralArray* arguments) {
int min = AS_INTEGER(third) > 0 ? 0 : AS_ARRAY(assign)->count - 1; int min = AS_INTEGER(third) > 0 ? 0 : AS_ARRAY(assign)->count - 1;
for (int i = min; i >= 0 && i < AS_ARRAY(assign)->count; i += AS_INTEGER(third)) { if (IS_ARRAY(assign)) { //push elements of an assigned array
Literal idx = TO_INTEGER_LITERAL(i); for (int i = min; i >= 0 && i < AS_ARRAY(assign)->count; i += AS_INTEGER(third)) {
Literal tmp = getLiteralArray(AS_ARRAY(assign), idx); //backwards Literal idx = TO_INTEGER_LITERAL(i);
Literal tmp = getLiteralArray(AS_ARRAY(assign), idx); //backwards
//set result //set result
pushLiteralArray(result, tmp); pushLiteralArray(result, tmp);
freeLiteral(idx); freeLiteral(idx);
freeLiteral(tmp); freeLiteral(tmp);
}
}
else { //push just one element into the array
pushLiteralArray(result, assign);
} }
for (int i = AS_INTEGER(second) + 1; i < AS_ARRAY(compound)->count; i++) { for (int i = AS_INTEGER(second) + 1; i < AS_ARRAY(compound)->count; i++) {
@@ -649,11 +654,12 @@ int _index(Interpreter* interpreter, LiteralArray* arguments) {
//start building a new string from the old one //start building a new string from the old one
char* result = ALLOCATE(char, MAX_STRING_LENGTH); char* result = ALLOCATE(char, MAX_STRING_LENGTH);
int min = AS_INTEGER(third) > 0 ? AS_INTEGER(first) : AS_INTEGER(second) - 1; int lower = AS_INTEGER(third) > 0 ? AS_INTEGER(first) : AS_INTEGER(first) -1;
int min = AS_INTEGER(third) > 0 ? AS_INTEGER(first) : AS_INTEGER(second) -1;
//copy compound into result //copy compound into result
int resultIndex = 0; int resultIndex = 0;
for (int i = min; i >= AS_INTEGER(first) && i < AS_INTEGER(second); i += AS_INTEGER(third)) { for (int i = min; i >= lower && i <= AS_INTEGER(second); i += AS_INTEGER(third)) {
result[ resultIndex++ ] = AS_STRING(compound)[ i ]; result[ resultIndex++ ] = AS_STRING(compound)[ i ];
} }

View File

@@ -736,17 +736,24 @@ static Opcode indexAccess(Parser* parser, Node** nodeHandle) {
emitNodeLiteral(&second, TO_BOOLEAN_LITERAL(true)); emitNodeLiteral(&second, TO_BOOLEAN_LITERAL(true));
emitNodeLiteral(&third, TO_BOOLEAN_LITERAL(true)); emitNodeLiteral(&third, TO_BOOLEAN_LITERAL(true));
bool readFirst = false; //pattern matching is bullcrap
//eat the first //eat the first
if (!match(parser, TOKEN_COLON)) { if (!match(parser, TOKEN_COLON)) {
freeNode(first); freeNode(first);
parsePrecedence(parser, &first, PREC_TERNARY); parsePrecedence(parser, &first, PREC_TERNARY);
match(parser, TOKEN_COLON); match(parser, TOKEN_COLON);
readFirst = true;
} }
if (match(parser, TOKEN_BRACKET_RIGHT)) { if (match(parser, TOKEN_BRACKET_RIGHT)) {
freeNode(second);
if (readFirst) {
freeNode(second);
second = NULL;
}
freeNode(third); freeNode(third);
second = NULL;
third = NULL; third = NULL;
emitNodeIndex(nodeHandle, first, second, third); emitNodeIndex(nodeHandle, first, second, third);