Another one bites the dust!

This commit is contained in:
2022-08-29 16:25:53 +10:00
parent d055e9dc94
commit 08c8e7e3e6
3 changed files with 189 additions and 21 deletions

View File

@@ -31,7 +31,9 @@ static int writeLiteralTypeToCacheOpt(LiteralArray* literalCache, Literal litera
for (int i = 0; i < AS_TYPE(literal).count; i++) { for (int i = 0; i < AS_TYPE(literal).count; i++) {
//write the values to the cache, and the indexes to the store //write the values to the cache, and the indexes to the store
int subIndex = writeLiteralTypeToCacheOpt(literalCache, ((Literal*)(AS_TYPE(literal).subtypes))[i], false); int subIndex = writeLiteralTypeToCacheOpt(literalCache, ((Literal*)(AS_TYPE(literal).subtypes))[i], false);
pushLiteralArray(store, TO_INTEGER_LITERAL(subIndex)); Literal lit = TO_INTEGER_LITERAL(subIndex);
pushLiteralArray(store, lit);
freeLiteral(lit);
} }
//push the store to the cache, tweaking the type //push the store to the cache, tweaking the type
@@ -77,14 +79,18 @@ static int writeNodeCompoundToCache(Compiler* compiler, Node* node) {
key = pushLiteralArray(&compiler->literalCache, node->compound.nodes[i].pair.left->atomic.literal); key = pushLiteralArray(&compiler->literalCache, node->compound.nodes[i].pair.left->atomic.literal);
} }
pushLiteralArray(store, TO_INTEGER_LITERAL(key)); Literal literal = TO_INTEGER_LITERAL(key);
pushLiteralArray(store, literal);
freeLiteral(literal);
} }
break; break;
case NODE_COMPOUND: { case NODE_COMPOUND: {
int key = writeNodeCompoundToCache(compiler, node->compound.nodes[i].pair.left); int key = writeNodeCompoundToCache(compiler, node->compound.nodes[i].pair.left);
pushLiteralArray(store, TO_INTEGER_LITERAL(key)); Literal literal = TO_INTEGER_LITERAL(key);
pushLiteralArray(store, literal);
freeLiteral(literal);
} }
break; break;
@@ -102,14 +108,18 @@ static int writeNodeCompoundToCache(Compiler* compiler, Node* node) {
val = pushLiteralArray(&compiler->literalCache, node->compound.nodes[i].pair.right->atomic.literal); val = pushLiteralArray(&compiler->literalCache, node->compound.nodes[i].pair.right->atomic.literal);
} }
pushLiteralArray(store, TO_INTEGER_LITERAL(val)); Literal literal = TO_INTEGER_LITERAL(val);
pushLiteralArray(store, literal);
freeLiteral(literal);
} }
break; break;
case NODE_COMPOUND: { case NODE_COMPOUND: {
int val = writeNodeCompoundToCache(compiler, node->compound.nodes[i].pair.right); int val = writeNodeCompoundToCache(compiler, node->compound.nodes[i].pair.right);
pushLiteralArray(store, TO_INTEGER_LITERAL(val)); Literal literal = TO_INTEGER_LITERAL(val);
pushLiteralArray(store, literal);
freeLiteral(literal);
} }
break; break;
@@ -120,7 +130,9 @@ static int writeNodeCompoundToCache(Compiler* compiler, Node* node) {
} }
//push the store to the cache, with instructions about how pack it //push the store to the cache, with instructions about how pack it
index = pushLiteralArray(&compiler->literalCache, TO_DICTIONARY_LITERAL(store)); //WARNING: pushed as a dictionary, so below can recognize it Literal literal = TO_DICTIONARY_LITERAL(store);
index = pushLiteralArray(&compiler->literalCache, literal); //WARNING: pushed as a dictionary, so below can recognize it
freeLiteral(literal);
} }
else if (node->compound.literalType == LITERAL_ARRAY) { else if (node->compound.literalType == LITERAL_ARRAY) {
//ensure each literal value is in the cache, individually //ensure each literal value is in the cache, individually
@@ -133,14 +145,18 @@ static int writeNodeCompoundToCache(Compiler* compiler, Node* node) {
val = pushLiteralArray(&compiler->literalCache, node->compound.nodes[i].atomic.literal); val = pushLiteralArray(&compiler->literalCache, node->compound.nodes[i].atomic.literal);
} }
pushLiteralArray(store, TO_INTEGER_LITERAL(val)); Literal literal = TO_INTEGER_LITERAL(val);
pushLiteralArray(store, literal);
freeLiteral(literal);
} }
break; break;
case NODE_COMPOUND: { case NODE_COMPOUND: {
int val = writeNodeCompoundToCache(compiler, &node->compound.nodes[i]); int val = writeNodeCompoundToCache(compiler, &node->compound.nodes[i]);
index = pushLiteralArray(store, TO_INTEGER_LITERAL(val)); Literal literal = TO_INTEGER_LITERAL(val);
index = pushLiteralArray(store, literal);
freeLiteral(literal);
} }
break; break;
@@ -151,7 +167,9 @@ static int writeNodeCompoundToCache(Compiler* compiler, Node* node) {
} }
//push the store to the cache, with instructions about how pack it //push the store to the cache, with instructions about how pack it
index = pushLiteralArray(&compiler->literalCache, TO_ARRAY_LITERAL(store)); Literal literal = TO_ARRAY_LITERAL(store);
index = pushLiteralArray(&compiler->literalCache, literal);
freeLiteral(literal);
} }
else { else {
fprintf(stderr, ERROR "[Internal] Unrecognized compound type in writeNodeCompoundToCache()" RESET); fprintf(stderr, ERROR "[Internal] Unrecognized compound type in writeNodeCompoundToCache()" RESET);
@@ -172,8 +190,13 @@ static int writeNodeCollectionToCache(Compiler* compiler, Node* node) {
int identifierIndex = pushLiteralArray(&compiler->literalCache, node->fnCollection.nodes[i].varDecl.identifier); //store without duplication optimisation int identifierIndex = pushLiteralArray(&compiler->literalCache, node->fnCollection.nodes[i].varDecl.identifier); //store without duplication optimisation
int typeIndex = writeLiteralTypeToCacheOpt(&compiler->literalCache, node->fnCollection.nodes[i].varDecl.typeLiteral, false); int typeIndex = writeLiteralTypeToCacheOpt(&compiler->literalCache, node->fnCollection.nodes[i].varDecl.typeLiteral, false);
pushLiteralArray(store, TO_INTEGER_LITERAL(identifierIndex)); Literal identifierLiteral = TO_INTEGER_LITERAL(identifierIndex);
pushLiteralArray(store, TO_INTEGER_LITERAL(typeIndex)); pushLiteralArray(store, identifierLiteral);
freeLiteral(identifierLiteral);
Literal typeLiteral = TO_INTEGER_LITERAL(typeIndex);
pushLiteralArray(store, typeLiteral);
freeLiteral(typeLiteral);
} }
break; break;
@@ -181,7 +204,9 @@ static int writeNodeCollectionToCache(Compiler* compiler, Node* node) {
//write each piece of the declaration to the cache //write each piece of the declaration to the cache
int typeIndex = writeLiteralTypeToCacheOpt(&compiler->literalCache, node->fnCollection.nodes[i].atomic.literal, false); int typeIndex = writeLiteralTypeToCacheOpt(&compiler->literalCache, node->fnCollection.nodes[i].atomic.literal, false);
pushLiteralArray(store, TO_INTEGER_LITERAL(typeIndex)); Literal typeLiteral = TO_INTEGER_LITERAL(typeIndex);
pushLiteralArray(store, typeLiteral);
freeLiteral(typeLiteral);
} }
break; break;
@@ -192,7 +217,11 @@ static int writeNodeCollectionToCache(Compiler* compiler, Node* node) {
} }
//store the store //store the store
return pushLiteralArray(&compiler->literalCache, TO_ARRAY_LITERAL(store)); Literal literal = TO_ARRAY_LITERAL(store);
int storeIndex = pushLiteralArray(&compiler->literalCache, literal);
freeLiteral(literal);
return storeIndex;
} }
static int writeLiteralToCompiler(Compiler* compiler, Literal literal) { static int writeLiteralToCompiler(Compiler* compiler, Literal literal) {
@@ -414,22 +443,24 @@ static void writeCompilerWithJumps(Compiler* compiler, Node* node, void* breakAd
} }
//push the argument COUNT to the top of the stack //push the argument COUNT to the top of the stack
int argumentsCount = findLiteralIndex(&compiler->literalCache, TO_INTEGER_LITERAL(node->fnCall.arguments->fnCollection.count)); Literal argumentsCountLiteral = TO_INTEGER_LITERAL(node->fnCall.arguments->fnCollection.count);
if (argumentsCount < 0) { int argumentsCountIndex = findLiteralIndex(&compiler->literalCache, argumentsCountLiteral);
argumentsCount = pushLiteralArray(&compiler->literalCache, TO_INTEGER_LITERAL(node->fnCall.arguments->fnCollection.count)); if (argumentsCountIndex < 0) {
argumentsCountIndex = pushLiteralArray(&compiler->literalCache, argumentsCountLiteral);
} }
freeLiteral(argumentsCountLiteral);
if (argumentsCount >= 256) { if (argumentsCountIndex >= 256) {
//push a "long" index //push a "long" index
compiler->bytecode[compiler->count++] = OP_LITERAL_LONG; //1 byte compiler->bytecode[compiler->count++] = OP_LITERAL_LONG; //1 byte
*((unsigned short*)(compiler->bytecode + compiler->count)) = (unsigned short)argumentsCount; //2 bytes *((unsigned short*)(compiler->bytecode + compiler->count)) = (unsigned short)argumentsCountIndex; //2 bytes
compiler->count += sizeof(unsigned short); compiler->count += sizeof(unsigned short);
} }
else { else {
//push the index //push the index
compiler->bytecode[compiler->count++] = OP_LITERAL; //1 byte compiler->bytecode[compiler->count++] = OP_LITERAL; //1 byte
compiler->bytecode[compiler->count++] = (unsigned char)argumentsCount; //1 byte compiler->bytecode[compiler->count++] = (unsigned char)argumentsCountIndex; //1 byte
} }
//call the function //call the function
@@ -586,7 +617,9 @@ static void writeCompilerWithJumps(Compiler* compiler, Node* node, void* breakAd
compiler->bytecode[compiler->count++] = OP_JUMP; //1 byte compiler->bytecode[compiler->count++] = OP_JUMP; //1 byte
//push to the breakAddresses array //push to the breakAddresses array
pushLiteralArray((LiteralArray*)breakAddressesPtr, TO_INTEGER_LITERAL(compiler->count)); Literal literal = TO_INTEGER_LITERAL(compiler->count);
pushLiteralArray((LiteralArray*)breakAddressesPtr, literal);
freeLiteral(literal);
compiler->count += sizeof(unsigned short); //2 bytes compiler->count += sizeof(unsigned short); //2 bytes
} }
@@ -602,7 +635,9 @@ static void writeCompilerWithJumps(Compiler* compiler, Node* node, void* breakAd
compiler->bytecode[compiler->count++] = OP_JUMP; //1 byte compiler->bytecode[compiler->count++] = OP_JUMP; //1 byte
//push to the continueAddresses array //push to the continueAddresses array
pushLiteralArray((LiteralArray*)continueAddressesPtr, TO_INTEGER_LITERAL(compiler->count)); Literal literal = TO_INTEGER_LITERAL(compiler->count);
pushLiteralArray((LiteralArray*)continueAddressesPtr, literal);
freeLiteral(literal);
compiler->count += sizeof(unsigned short); //2 bytes compiler->count += sizeof(unsigned short); //2 bytes
} }

View File

@@ -72,6 +72,21 @@ Literal copyLiteral(Literal original) {
return lit; return lit;
} }
case LITERAL_TYPE_INTERMEDIATE: {
LiteralArray* array = ALLOCATE(LiteralArray, 1);
initLiteralArray(array);
//copy each element
for (int i = 0; i < AS_ARRAY(original)->count; i++) {
pushLiteralArray(array, copyLiteral(AS_ARRAY(original)->literals[i]));
}
Literal ret = TO_ARRAY_LITERAL(array);
ret.type = LITERAL_TYPE_INTERMEDIATE;
return ret;
}
case LITERAL_FUNCTION_INTERMEDIATE: //caries a compiler
case LITERAL_FUNCTION_NATIVE: case LITERAL_FUNCTION_NATIVE:
//no copying possible //no copying possible
return original; return original;

118
test/test_compiler.c Normal file
View File

@@ -0,0 +1,118 @@
#include "lexer.h"
#include "parser.h"
#include "compiler.h"
#include "console_colors.h"
#include "memory.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//IO functions
char* readFile(char* path, size_t* fileSize) {
FILE* file = fopen(path, "rb");
if (file == NULL) {
fprintf(stderr, ERROR "Could not open file \"%s\"\n" RESET, path);
exit(-1);
}
fseek(file, 0L, SEEK_END);
*fileSize = ftell(file);
rewind(file);
char* buffer = (char*)malloc(*fileSize + 1);
if (buffer == NULL) {
fprintf(stderr, ERROR "Not enough memory to read \"%s\"\n" RESET, path);
exit(-1);
}
size_t bytesRead = fread(buffer, sizeof(char), *fileSize, file);
buffer[*fileSize] = '\0'; //NOTE: fread doesn't append this
if (bytesRead < *fileSize) {
fprintf(stderr, ERROR "Could not read file \"%s\"\n" RESET, path);
exit(-1);
}
fclose(file);
return buffer;
}
int main() {
{
//test init & free
Compiler compiler;
initCompiler(&compiler);
freeCompiler(&compiler);
}
{
//source
char* source = "print null;";
//test basic compilation & collation
Lexer lexer;
Parser parser;
Compiler compiler;
initLexer(&lexer, source);
initParser(&parser, &lexer);
initCompiler(&compiler);
Node* node = scanParser(&parser);
//write
writeCompiler(&compiler, node);
//collate
int size = 0;
unsigned char* bytecode = collateCompiler(&compiler, &size);
//cleanup
FREE_ARRAY(unsigned char, bytecode, size);
freeNode(node);
freeParser(&parser);
freeCompiler(&compiler);
}
{
//source
size_t sourceLength = 0;
char* source = readFile("sample_code.toy", &sourceLength);
//test basic compilation & collation
Lexer lexer;
Parser parser;
Compiler compiler;
initLexer(&lexer, source);
initParser(&parser, &lexer);
initCompiler(&compiler);
Node* node = scanParser(&parser);
//write
writeCompiler(&compiler, node);
//collate
int size = 0;
unsigned char* bytecode = collateCompiler(&compiler, &size);
//cleanup
FREE_ARRAY(char, source, sourceLength);
FREE_ARRAY(unsigned char, bytecode, size);
freeNode(node);
freeParser(&parser);
freeCompiler(&compiler);
}
printf(NOTICE "All good\n" RESET);
return 0;
}