diff --git a/docs/TODO.txt b/docs/TODO.txt index 959ac77..b977cb3 100644 --- a/docs/TODO.txt +++ b/docs/TODO.txt @@ -26,6 +26,8 @@ DONE: assert needs to kill the whole script, not just functions DONE: native functions DONE: global functions _get, _set, _push, _pop, _length, clear available DONE: change comma to colon in dictionary definition +DONE: Address circular references +TODO: are compounds shallow or deep copies? Deep copies TODO: slice and dot notation around the _index function @@ -33,13 +35,13 @@ TODO: ternary operator TODO: Nullish types TODO: A way to check the type of a variable (typeOf keyword) TODO: a = b = c = 1; ? -TODO: are compounds shallow or deep copies? -TODO: Address circular references? TODO: Assertion-based test scripts TODO: standard library TODO: external runner library TODO: document how it all works TODO: third output stream, for parser/compiler/interpreter errors TODO: better and more consistent error messages +TODO: maximum recursion/function depth + NOPE: functions return a set number of values \ No newline at end of file diff --git a/scripts/dot.toy b/scripts/dot.toy new file mode 100644 index 0000000..7a8effd --- /dev/null +++ b/scripts/dot.toy @@ -0,0 +1,71 @@ +/* + +//dot product +var a = [1, 2, 3]; +var b = [4, 5, 6]; + +assert _length(a) == _length(b), "lengths wrong"; + +var acc = 0; +for (var i = 0; i < _length(a); i++) { + acc += _get(a, i) * _get(b, i); +} + +print acc; + +*/ + +//matrix multiply +var c = [[4], [5], [6]]; //this is going t obe a 3x1 +var d = [[1, 2, 3]]; //this is going to be a 1x3 + +// c x d = 3x3 +// d x c = 1x1 + +//assume the args are matrices +fn matrix(first, second) { + //get the matrix size + var l1 = _length(first); //rows + var l2 = _length(_get(first, 0)); //cols + + var l3 = _length(second); //rows + var l4 = _length(_get(second, 0)); //cols + + //pre-allocate the matrix + var row = []; + for (var j = 0; j < l4; j++) { + _push(row, 0); + } + + var result = []; + for (var i = 0; i < l1; i++) { + _push(result, row); + } + + //assign the values + for (var i = 0; i < _length(first); i++) { + //select each element of "first" + var firstElement = _get(first, i); + + //for each element of second + for (var i2 = 0; i2 < _length(second); i2++) { + for (var j2 = 0; j2 < _length(_get(second, 0)); j2++) { + + var val = _get(_get(first, i), i2) * _get(_get(second, i2), j2); + + //TODO: needs better notation than this tmpRow variable + var tmpRow = _get(result, i); + _set(tmpRow, j2, val); + _set(result, i, tmpRow); + + //result[ i ][ j2 ] += first[i][i2] * second[i2][j2] + } + } + } + + return result; +} + +assert matrix(c, d) == [[4,8,12],[5,10,15],[6,12,18]], "Matrix multiplication failed"; + +print "All good"; \ No newline at end of file diff --git a/source/interpreter.c b/source/interpreter.c index cc8770f..392485d 100644 --- a/source/interpreter.c +++ b/source/interpreter.c @@ -190,7 +190,17 @@ int _get(Interpreter* interpreter, LiteralArray* arguments) { Literal obj = arguments->literals[0]; Literal key = arguments->literals[1]; - parseIdentifierToValue(interpreter, &obj); + bool freeObj = false; + if (IS_IDENTIFIER(obj)) { + parseIdentifierToValue(interpreter, &obj); + freeObj = true; + } + + bool freeKey = false; + if (IS_IDENTIFIER(key)) { + parseIdentifierToValue(interpreter, &key); + freeKey = true; + } switch(obj.type) { case LITERAL_ARRAY: { @@ -205,7 +215,15 @@ int _get(Interpreter* interpreter, LiteralArray* arguments) { } pushLiteralArray(&interpreter->stack, AS_ARRAY(obj)->literals[AS_INTEGER(key)]); - freeLiteral(obj); + + if (freeObj) { + freeLiteral(obj); + } + + if (freeKey) { + freeLiteral(key); + } + return 1; } @@ -213,7 +231,15 @@ int _get(Interpreter* interpreter, LiteralArray* arguments) { Literal dict = getLiteralDictionary(AS_DICTIONARY(obj), key); pushLiteralArray(&interpreter->stack, dict); freeLiteral(dict); - freeLiteral(obj); + + if (freeObj) { + freeLiteral(obj); + } + + if (freeKey) { + freeLiteral(key); + } + return 1; } @@ -241,7 +267,12 @@ int _push(Interpreter* interpreter, LiteralArray* arguments) { } parseIdentifierToValue(interpreter, &obj); - parseIdentifierToValue(interpreter, &val); + + bool freeVal = false; + if (IS_IDENTIFIER(val)) { + parseIdentifierToValue(interpreter, &val); + freeVal = true; + } switch(obj.type) { case LITERAL_ARRAY: { @@ -267,6 +298,10 @@ int _push(Interpreter* interpreter, LiteralArray* arguments) { freeLiteral(obj); + if (freeVal) { + freeLiteral(val); + } + return 0; } diff --git a/source/literal.c b/source/literal.c index 3ba347d..52edc04 100644 --- a/source/literal.c +++ b/source/literal.c @@ -362,7 +362,7 @@ int hashLiteral(Literal lit) { case LITERAL_ARRAY: { unsigned int res = 0; - for (int i = 0; i < AS_DICTIONARY(lit)->count; i++) { + for (int i = 0; i < AS_ARRAY(lit)->count; i++) { res += hashLiteral(AS_ARRAY(lit)->literals[i]); } return hash(res);