diff --git a/docs/TODO.txt b/docs/TODO.txt index 0a266d8..3bc560e 100644 --- a/docs/TODO.txt +++ b/docs/TODO.txt @@ -15,15 +15,17 @@ DONE: increment & decrement operators DONE: store compound types in variables DONE: += -= *= /= %= operators DONE: && and || operators +DONE: functions are invoked by calling their names +DONE: function arguments can have specified types +DONE: function returns can have specified types +DONE: closures are explicitly supported -TODO: functions take a number of parameters -TODO: functions can return any number of values -TODO: function arguments can have specified types -TODO: function returns can have specified types -TODO: functions are invoked by calling their names +TODO: functions take a set number of parameters +TODO: functions can return a set number of values TODO: functions are first-class citizens TODO: functions last argument can be a rest parameter +TODO: check for wrong number of function parameters TODO: Nullish types TODO: A way to check the type of a variable (typeOf keyword) diff --git a/scripts/function.toy b/scripts/function.toy index 4ffba62..ef50ac4 100644 --- a/scripts/function.toy +++ b/scripts/function.toy @@ -1,5 +1,5 @@ - -fn name(param1: string, param2: string): string { +/* +fn name(param1: string, param2: string, param3): string { print "foobar"; print param1; return param2; @@ -10,3 +10,42 @@ var result = name("hello world", "goodnight world"); print "fizz"; print result; print "buzz"; + + +*/ + +/* +fn outer() { + fn inner() { + print "foo"; + } + + inner(); + + return inner; +} + +var handle = outer(); + +handle(); //breaks +*/ + + +fn make() { + var counter = 0; + + fn count() { + return counter++; + } + + return count; +} + +var tally = make(); + +print tally(); +print tally(); +print tally(); +print tally(); +print tally(); + diff --git a/source/interpreter.c b/source/interpreter.c index 2117e14..7c4b8e2 100644 --- a/source/interpreter.c +++ b/source/interpreter.c @@ -823,7 +823,7 @@ static bool execFnCall(Interpreter* interpreter) { Literal ret = popLiteralArray(&returns); //check the return types - if (AS_TYPE(returnArray->literals[i]).typeOf != ret.type) { + if (returnArray->count > 0 && AS_TYPE(returnArray->literals[i]).typeOf != ret.type) { printf(ERROR "ERROR: bad type found in return value\n" RESET); //free, and skip out @@ -1066,7 +1066,6 @@ static void execInterpreter(Interpreter* interpreter) { } } - static void readInterpreterSections(Interpreter* interpreter) { //data section const short literalCount = readShort(interpreter->bytecode, &interpreter->count); diff --git a/source/literal_dictionary.c b/source/literal_dictionary.c index 76c0e08..d37c6ac 100644 --- a/source/literal_dictionary.c +++ b/source/literal_dictionary.c @@ -22,7 +22,7 @@ static void setEntryValues(_entry* entry, Literal key, Literal value) { else if (IS_IDENTIFIER(key)) { entry->key = TO_IDENTIFIER_LITERAL( copyString(AS_IDENTIFIER(key), STRLEN_I(key)) ); } - + else { freeLiteral(entry->key); //for types entry->key = key; @@ -38,7 +38,18 @@ static void setEntryValues(_entry* entry, Literal key, Literal value) { buffer[STRLEN(value)] = '\0'; entry->value = TO_STRING_LITERAL(buffer); } - + + //OR take ownership of the copied function + else if (IS_FUNCTION(value)) { + unsigned char* buffer = ALLOCATE(unsigned char, value.as.function.length); + memcpy(buffer, AS_FUNCTION(value), value.as.function.length); + + entry->value = TO_FUNCTION_LITERAL(buffer, value.as.function.length); + + //save the scope + entry->value.as.function.scope = value.as.function.scope; + } + else { entry->value = value; }