Fixed nagging issues, read more
* A segfault from the inspector * multiple returns no longer a goal * Cleaned up the 'URGENT' comment tags * Narrowed down what is needed for alpha
This commit is contained in:
@@ -385,5 +385,3 @@ int inspect_read(unsigned char* bytecode, unsigned int pc, unsigned int jumps_ad
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//TODO: Check if strings are reused in the bytecode
|
||||
+20
-5
@@ -321,8 +321,6 @@ int repl(const char* filepath, bool verbose) {
|
||||
char inputBuffer[INPUT_BUFFER_SIZE];
|
||||
memset(inputBuffer, 0, INPUT_BUFFER_SIZE);
|
||||
|
||||
Toy_Bucket* bucket = Toy_allocateBucket(TOY_BUCKET_IDEAL); //TODO: gc this
|
||||
|
||||
Toy_VM vm;
|
||||
Toy_initVM(&vm);
|
||||
|
||||
@@ -347,14 +345,16 @@ int repl(const char* filepath, bool verbose) {
|
||||
}
|
||||
|
||||
//parse the input, prep the VM for execution
|
||||
Toy_Bucket* bucket = Toy_allocateBucket(TOY_BUCKET_IDEAL);
|
||||
Toy_Lexer lexer;
|
||||
Toy_bindLexer(&lexer, inputBuffer);
|
||||
Toy_Parser parser;
|
||||
Toy_bindParser(&parser, &lexer);
|
||||
Toy_Ast* ast = Toy_scanParser(&bucket, &parser); //Ast is in the bucket, so it doesn't need to be freed
|
||||
Toy_Ast* ast = Toy_scanParser(&bucket, &parser);
|
||||
|
||||
//parsing error, retry
|
||||
if (parser.error) {
|
||||
if (parser.error || ast == NULL) {
|
||||
Toy_freeBucket(&bucket);
|
||||
printf("%s> ", prompt); //shows the terminal prompt
|
||||
continue;
|
||||
}
|
||||
@@ -364,6 +364,12 @@ int repl(const char* filepath, bool verbose) {
|
||||
}
|
||||
|
||||
unsigned char* bytecode = Toy_compileToBytecode(ast);
|
||||
Toy_freeBucket(&bucket); //no need to for the GC here
|
||||
|
||||
if (bytecode == NULL) {
|
||||
printf("%s> ", prompt);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (verbose) {
|
||||
inspect_bytecode(bytecode);
|
||||
@@ -408,7 +414,6 @@ int repl(const char* filepath, bool verbose) {
|
||||
|
||||
//cleanup all memory
|
||||
Toy_freeVM(&vm);
|
||||
Toy_freeBucket(&bucket);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -479,6 +484,12 @@ int main(int argc, const char* argv[]) {
|
||||
Toy_Bucket* bucket = Toy_allocateBucket(TOY_BUCKET_IDEAL);
|
||||
Toy_Ast* ast = Toy_scanParser(&bucket, &parser);
|
||||
|
||||
if (ast == NULL) {
|
||||
Toy_freeBucket(&bucket);
|
||||
free(source);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (cmd.verbose) {
|
||||
inspect_ast(ast);
|
||||
}
|
||||
@@ -487,6 +498,10 @@ int main(int argc, const char* argv[]) {
|
||||
Toy_freeBucket(&bucket);
|
||||
free(source);
|
||||
|
||||
if (bytecode == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (cmd.verbose) {
|
||||
inspect_bytecode(bytecode);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
|
||||
/*
|
||||
fn swap(a, b) {
|
||||
return b, a;
|
||||
}
|
||||
@@ -9,11 +8,4 @@ var b = 69;
|
||||
var c;
|
||||
var d;
|
||||
|
||||
//BUG: still causes a segfault
|
||||
c, d = swap(a, b);
|
||||
|
||||
*/
|
||||
|
||||
|
||||
{ var str = "Hello"; var i = 0; while (i < 100) { str = str .. " World"; i++; } }
|
||||
|
||||
|
||||
+19
-15
@@ -9,13 +9,17 @@
|
||||
//if set, used for delegating to user-defined code
|
||||
static Toy_OpaqueAttributeHandler opaqueAttributeCallback = NULL;
|
||||
|
||||
//NOTE: there is no need to call 'Toy_freeValue' on the arguments, as the VM assumes you don't
|
||||
//utils
|
||||
#define MATCH_VALUE_AND_CSTRING(value, cstring) \
|
||||
((TOY_VALUE_AS_STRING(value)->info.length == strlen(cstring)) && \
|
||||
(strncmp(cstring, TOY_VALUE_AS_STRING(value)->leaf.data, TOY_VALUE_AS_STRING(value)->info.length) == 0))
|
||||
|
||||
//NOTE: there is no need to call 'Toy_freeValue' on the arguments, as the VM assumes you don't
|
||||
Toy_Value Toy_private_handleStringAttributes(Toy_VM* vm, Toy_Value compound, Toy_Value attribute) {
|
||||
if (strncmp(TOY_VALUE_AS_STRING(attribute)->leaf.data, "length", 6) == 0) {
|
||||
if (MATCH_VALUE_AND_CSTRING(attribute, "length")) {
|
||||
return TOY_VALUE_FROM_INTEGER(TOY_VALUE_AS_STRING(compound)->info.length);
|
||||
}
|
||||
else if (strncmp(TOY_VALUE_AS_STRING(attribute)->leaf.data, "asUpper", 7) == 0) {
|
||||
else if (MATCH_VALUE_AND_CSTRING(attribute, "asUpper")) {
|
||||
char* buffer = Toy_getStringRaw(TOY_VALUE_AS_STRING(compound));
|
||||
for (int i = 0; buffer[i] != '\0'; i++) {
|
||||
buffer[i] = toupper(buffer[i]);
|
||||
@@ -24,7 +28,7 @@ Toy_Value Toy_private_handleStringAttributes(Toy_VM* vm, Toy_Value compound, Toy
|
||||
free(buffer);
|
||||
return TOY_VALUE_FROM_STRING(str);
|
||||
}
|
||||
else if (strncmp(TOY_VALUE_AS_STRING(attribute)->leaf.data, "asLower", 7) == 0) {
|
||||
else if (MATCH_VALUE_AND_CSTRING(attribute, "asLower")) {
|
||||
char* buffer = Toy_getStringRaw(TOY_VALUE_AS_STRING(compound));
|
||||
for (int i = 0; buffer[i] != '\0'; i++) {
|
||||
buffer[i] = tolower(buffer[i]);
|
||||
@@ -116,7 +120,7 @@ static void attr_arrayForEach(Toy_VM* vm) {
|
||||
Toy_declareScope(subVM.scope, Toy_copyString(name), paramType, Toy_copyValue(&subVM.memoryBucket, array->data[iterator]), true);
|
||||
Toy_freeString(name);
|
||||
|
||||
Toy_runVM(&subVM); //TODO: could use a 'map'-style method by storing the results
|
||||
Toy_runVM(&subVM);
|
||||
|
||||
Toy_resetVM(&subVM, false, true);
|
||||
}
|
||||
@@ -148,22 +152,22 @@ static void attr_arraySort(Toy_VM* vm) {
|
||||
}
|
||||
|
||||
Toy_Value Toy_private_handleArrayAttributes(Toy_VM* vm, Toy_Value compound, Toy_Value attribute) {
|
||||
if (strncmp(TOY_VALUE_AS_STRING(attribute)->leaf.data, "length", 6) == 0) {
|
||||
if (MATCH_VALUE_AND_CSTRING(attribute, "length")) {
|
||||
return TOY_VALUE_FROM_INTEGER(TOY_VALUE_AS_ARRAY(compound)->count);
|
||||
}
|
||||
else if (strncmp(TOY_VALUE_AS_STRING(attribute)->leaf.data, "pushBack", 8) == 0) {
|
||||
else if (MATCH_VALUE_AND_CSTRING(attribute, "pushBack")) {
|
||||
Toy_Function* fn = Toy_createFunctionFromCallback(&vm->memoryBucket, attr_arrayPushBack);
|
||||
return TOY_VALUE_FROM_FUNCTION(fn);
|
||||
}
|
||||
else if (strncmp(TOY_VALUE_AS_STRING(attribute)->leaf.data, "popBack", 7) == 0) {
|
||||
else if (MATCH_VALUE_AND_CSTRING(attribute, "popBack")) {
|
||||
Toy_Function* fn = Toy_createFunctionFromCallback(&vm->memoryBucket, attr_arrayPopBack);
|
||||
return TOY_VALUE_FROM_FUNCTION(fn);
|
||||
}
|
||||
else if (strncmp(TOY_VALUE_AS_STRING(attribute)->leaf.data, "forEach", 7) == 0) {
|
||||
else if (MATCH_VALUE_AND_CSTRING(attribute, "forEach")) {
|
||||
Toy_Function* fn = Toy_createFunctionFromCallback(&vm->memoryBucket, attr_arrayForEach);
|
||||
return TOY_VALUE_FROM_FUNCTION(fn);
|
||||
}
|
||||
else if (strncmp(TOY_VALUE_AS_STRING(attribute)->leaf.data, "sort", 4) == 0) {
|
||||
else if (MATCH_VALUE_AND_CSTRING(attribute, "sort")) {
|
||||
Toy_Function* fn = Toy_createFunctionFromCallback(&vm->memoryBucket, attr_arraySort);
|
||||
return TOY_VALUE_FROM_FUNCTION(fn);
|
||||
}
|
||||
@@ -224,22 +228,22 @@ static void attr_tableForEach(Toy_VM* vm) {
|
||||
}
|
||||
|
||||
Toy_Value Toy_private_handleTableAttributes(Toy_VM* vm, Toy_Value compound, Toy_Value attribute) {
|
||||
if (strncmp(TOY_VALUE_AS_STRING(attribute)->leaf.data, "length", 6) == 0) {
|
||||
if (MATCH_VALUE_AND_CSTRING(attribute, "length")) {
|
||||
return TOY_VALUE_FROM_INTEGER(TOY_VALUE_AS_ARRAY(compound)->count);
|
||||
}
|
||||
else if (strncmp(TOY_VALUE_AS_STRING(attribute)->leaf.data, "insert", 6) == 0) {
|
||||
else if (MATCH_VALUE_AND_CSTRING(attribute, "insert")) {
|
||||
Toy_Function* fn = Toy_createFunctionFromCallback(&vm->memoryBucket, attr_tableInsert);
|
||||
return TOY_VALUE_FROM_FUNCTION(fn);
|
||||
}
|
||||
else if (strncmp(TOY_VALUE_AS_STRING(attribute)->leaf.data, "hasKey", 6) == 0) {
|
||||
else if (MATCH_VALUE_AND_CSTRING(attribute, "hasKey")) {
|
||||
Toy_Function* fn = Toy_createFunctionFromCallback(&vm->memoryBucket, attr_tableHasKey);
|
||||
return TOY_VALUE_FROM_FUNCTION(fn);
|
||||
}
|
||||
else if (strncmp(TOY_VALUE_AS_STRING(attribute)->leaf.data, "remove", 6) == 0) {
|
||||
else if (MATCH_VALUE_AND_CSTRING(attribute, "remove")) {
|
||||
Toy_Function* fn = Toy_createFunctionFromCallback(&vm->memoryBucket, attr_tableRemove);
|
||||
return TOY_VALUE_FROM_FUNCTION(fn);
|
||||
}
|
||||
else if (strncmp(TOY_VALUE_AS_STRING(attribute)->leaf.data, "forEach", 7) == 0) { //URGENT: compare the contents AND length of these strings
|
||||
else if (MATCH_VALUE_AND_CSTRING(attribute, "forEach")) {
|
||||
Toy_Function* fn = Toy_createFunctionFromCallback(&vm->memoryBucket, attr_tableForEach);
|
||||
return TOY_VALUE_FROM_FUNCTION(fn);
|
||||
}
|
||||
|
||||
@@ -820,9 +820,6 @@ static unsigned int writeInstructionVarDeclare(Toy_Bytecode** mb, Toy_AstVarDecl
|
||||
static unsigned int writeInstructionAssign(Toy_Bytecode** mb, Toy_AstVarAssign ast, bool chainedAssignment) {
|
||||
unsigned int result = 0;
|
||||
|
||||
//BUG: flip the order of target & value, to allow chained assignment AND multiple return values
|
||||
//do I need multiple return values?
|
||||
|
||||
//target is a variable name
|
||||
if (ast.target->type == TOY_AST_VALUE && TOY_VALUE_IS_STRING(ast.target->value.value)) {
|
||||
//name string
|
||||
|
||||
+1
-1
@@ -1066,7 +1066,7 @@ static void makeStmt(Toy_Bucket** bucketHandle, Toy_Parser* parser, Toy_Ast** ro
|
||||
return;
|
||||
}
|
||||
|
||||
//TODO: for-pre-clause-post-then
|
||||
//URGENT: for-pre-clause-post-then
|
||||
|
||||
//break
|
||||
else if (match(parser, TOY_TOKEN_KEYWORD_BREAK)) {
|
||||
|
||||
@@ -494,7 +494,6 @@ Toy_String* Toy_stringifyValue(Toy_Bucket** bucketHandle, Toy_Value value) {
|
||||
return Toy_copyString(value.as.string);
|
||||
|
||||
case TOY_VALUE_ARRAY: {
|
||||
//TODO: concat + free is definitely a performance nightmare, could make an append function?
|
||||
Toy_Array* ptr = value.as.array;
|
||||
|
||||
//if array is empty, skip below
|
||||
|
||||
+8
-23
@@ -394,15 +394,8 @@ static void processInvoke(Toy_VM* vm) {
|
||||
|
||||
//extract and store any results
|
||||
if (resultCount > 0) {
|
||||
Toy_Array* results = Toy_extractResultsFromVM(vm, &subVM, resultCount);
|
||||
|
||||
for (unsigned int i = 0; i < results->count; i++) {
|
||||
//NOTE: since the results array is being immediately freed, just push each element without a call to copy
|
||||
Toy_pushStack(&vm->stack, results->data[i]);
|
||||
}
|
||||
|
||||
//a bit naughty
|
||||
free(results);
|
||||
Toy_Value result = Toy_getReturnValueFromVM(vm, &subVM);
|
||||
Toy_pushStack(&vm->stack, result);
|
||||
}
|
||||
|
||||
//cleanup
|
||||
@@ -1104,7 +1097,7 @@ void Toy_resetVM(Toy_VM* vm, bool preserveScope, bool preserveStack) {
|
||||
|
||||
//not sure how often to call teh GC
|
||||
if (vm->memoryBucket) {
|
||||
Toy_collectBucketGarbage(&vm->memoryBucket); //URGENT: call GC after a certain number of bucket links allocated
|
||||
Toy_collectBucketGarbage(&vm->memoryBucket); //WONTFIX: call GC after a certain number of bucket links allocated
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1189,19 +1182,11 @@ void Toy_freeVM(Toy_VM* vm) {
|
||||
}
|
||||
}
|
||||
|
||||
Toy_Array* Toy_extractResultsFromVM(Toy_VM* parentVM, Toy_VM* subVM, unsigned int resultCount) {
|
||||
if (subVM->stack->count != resultCount) {
|
||||
fprintf(stderr, TOY_CC_ERROR "ERROR: Too %s results requested from VM, exiting\n" TOY_CC_RESET, subVM->stack->count < resultCount ? "many":"few");
|
||||
exit(-1);
|
||||
Toy_Value Toy_getReturnValueFromVM(Toy_VM* parentVM, Toy_VM* subVM) {
|
||||
if (subVM->stack->count > 0) {
|
||||
return Toy_copyValue(&parentVM->memoryBucket, subVM->stack->data[subVM->stack->count-1]);
|
||||
}
|
||||
|
||||
Toy_Array* results = Toy_resizeArray(NULL, resultCount);
|
||||
|
||||
const unsigned int offset = subVM->stack->count - resultCount; //first element to extract
|
||||
|
||||
for (/* EMPTY */; results->count < resultCount; results->count++) {
|
||||
results->data[results->count] = Toy_copyValue(&parentVM->memoryBucket, subVM->stack->data[offset + results->count]);
|
||||
else {
|
||||
return TOY_VALUE_FROM_NULL();
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
+1
-1
@@ -51,5 +51,5 @@ void Toy_bindVM(Toy_VM* vm, unsigned char* bytecode, Toy_Scope* parentScope);
|
||||
TOY_API unsigned int Toy_runVM(Toy_VM* vm);
|
||||
TOY_API void Toy_freeVM(Toy_VM* vm);
|
||||
|
||||
TOY_API Toy_Array* Toy_extractResultsFromVM(Toy_VM* parentVM, Toy_VM* subVM, unsigned int resultCount);
|
||||
TOY_API Toy_Value Toy_getReturnValueFromVM(Toy_VM* parentVM, Toy_VM* subVM);
|
||||
|
||||
|
||||
@@ -24,5 +24,3 @@ print a;
|
||||
var b = [];
|
||||
|
||||
print b;
|
||||
|
||||
//TODO: utility functions are needed, see toy_array.h
|
||||
@@ -609,6 +609,7 @@ int main(void) {
|
||||
|
||||
//TODO: references
|
||||
//TODO: type coersions
|
||||
//TODO: opaques?
|
||||
|
||||
return total;
|
||||
}
|
||||
Reference in New Issue
Block a user