Closures work

This commit is contained in:
2022-08-26 03:54:58 +01:00
parent 0c67ce6476
commit ffc50ceafb
4 changed files with 62 additions and 11 deletions

View File

@@ -15,15 +15,17 @@ DONE: increment & decrement operators
DONE: store compound types in variables DONE: store compound types in variables
DONE: += -= *= /= %= operators DONE: += -= *= /= %= operators
DONE: && and || 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 take a set number of parameters
TODO: functions can return any number of values TODO: functions can return a set 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 are first-class citizens TODO: functions are first-class citizens
TODO: functions last argument can be a rest parameter TODO: functions last argument can be a rest parameter
TODO: check for wrong number of function parameters
TODO: Nullish types TODO: Nullish types
TODO: A way to check the type of a variable (typeOf keyword) TODO: A way to check the type of a variable (typeOf keyword)

View File

@@ -1,5 +1,5 @@
/*
fn name(param1: string, param2: string): string { fn name(param1: string, param2: string, param3): string {
print "foobar"; print "foobar";
print param1; print param1;
return param2; return param2;
@@ -10,3 +10,42 @@ var result = name("hello world", "goodnight world");
print "fizz"; print "fizz";
print result; print result;
print "buzz"; 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();

View File

@@ -823,7 +823,7 @@ static bool execFnCall(Interpreter* interpreter) {
Literal ret = popLiteralArray(&returns); Literal ret = popLiteralArray(&returns);
//check the return types //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); printf(ERROR "ERROR: bad type found in return value\n" RESET);
//free, and skip out //free, and skip out
@@ -1066,7 +1066,6 @@ static void execInterpreter(Interpreter* interpreter) {
} }
} }
static void readInterpreterSections(Interpreter* interpreter) { static void readInterpreterSections(Interpreter* interpreter) {
//data section //data section
const short literalCount = readShort(interpreter->bytecode, &interpreter->count); const short literalCount = readShort(interpreter->bytecode, &interpreter->count);

View File

@@ -39,6 +39,17 @@ static void setEntryValues(_entry* entry, Literal key, Literal value) {
entry->value = TO_STRING_LITERAL(buffer); 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 { else {
entry->value = value; entry->value = value;
} }