mirror of
https://github.com/krgamestudios/Toy.git
synced 2026-04-15 14:54:07 +10:00
String literals are being parsed, compiled and printed, read more
Strings, due to their potentially large size, are stored outside of a routine's code section, in the data section. To access the correct string, you must read the jump index, then the real address from the jump table - and extra layer of indirection will result in more flexible data down the road, I hope. Other changes include: * Added string concat operator .. * Added TOY_STRING_MAX_LENGTH * Strings can't be created or concatenated longer than the max length * The parser will display a warning if the bucket is too small for a string at max length, but it will continue * Added TOY_BUCKET_IDEAL to correspend with max string length * The bucket now allocates an address that is 4-byte aligned * Fixed missing entries in the parser rule table * Corrected some failing TOY_BITNESS tests
This commit is contained in:
@@ -318,6 +318,105 @@ int test_routine_expressions(Toy_Bucket** bucketHandle) {
|
||||
free(buffer);
|
||||
}
|
||||
|
||||
//produce a string value
|
||||
{
|
||||
//setup
|
||||
const char* source = "\"Hello world!\";";
|
||||
Toy_Lexer lexer;
|
||||
Toy_Parser parser;
|
||||
|
||||
Toy_bindLexer(&lexer, source);
|
||||
Toy_bindParser(&parser, &lexer);
|
||||
Toy_Ast* ast = Toy_scanParser(bucketHandle, &parser);
|
||||
|
||||
//run
|
||||
void* buffer = Toy_compileRoutine(ast);
|
||||
int len = ((int*)buffer)[0];
|
||||
|
||||
//check header
|
||||
int* header = (int*)buffer;
|
||||
|
||||
if (header[0] != 64 || //total size
|
||||
header[1] != 0 || //param size
|
||||
header[2] != 4 || //jumps size
|
||||
header[3] != 16 || //data size
|
||||
header[4] != 0 || //subs size
|
||||
|
||||
// header[??] != ?? || //params address
|
||||
header[5] != 32 || //code address
|
||||
header[6] != 44 || //jumps address
|
||||
header[7] != 48 || //data address
|
||||
// header[??] != ?? || //subs address
|
||||
|
||||
false)
|
||||
{
|
||||
fprintf(stderr, TOY_CC_ERROR "ERROR: failed to produce the expected routine header, source: %s\n" TOY_CC_RESET, source);
|
||||
|
||||
//cleanup and return
|
||||
free(buffer);
|
||||
return -1;
|
||||
}
|
||||
|
||||
void* code = buffer + 32; //8 values in the header, each 4 bytes
|
||||
|
||||
//check code
|
||||
if (
|
||||
//code start
|
||||
*((unsigned char*)(code + 0)) != TOY_OPCODE_READ ||
|
||||
*((unsigned char*)(code + 1)) != TOY_VALUE_STRING ||
|
||||
*((unsigned char*)(code + 2)) != 0 ||
|
||||
*((unsigned char*)(code + 3)) != 0 ||
|
||||
*(unsigned int*)(code + 4) != 0 || //the jump index
|
||||
*((unsigned char*)(code + 8)) != TOY_OPCODE_RETURN ||
|
||||
*((unsigned char*)(code + 9)) != 0 ||
|
||||
*((unsigned char*)(code + 10)) != 0 ||
|
||||
*((unsigned char*)(code + 11)) != 0 ||
|
||||
|
||||
false)
|
||||
{
|
||||
fprintf(stderr, TOY_CC_ERROR "ERROR: failed to produce the expected routine code, source: %s\n" TOY_CC_RESET, source);
|
||||
|
||||
//cleanup and return
|
||||
free(buffer);
|
||||
return -1;
|
||||
}
|
||||
|
||||
void* jumps = code + 12;
|
||||
|
||||
//check jumps
|
||||
if (
|
||||
//code start
|
||||
*(unsigned int*)(jumps + 0) != 0 || //the address relative to the start of the data section
|
||||
|
||||
false)
|
||||
{
|
||||
fprintf(stderr, TOY_CC_ERROR "ERROR: failed to produce the expected routine jumps, source: %s\n" TOY_CC_RESET, source);
|
||||
|
||||
//cleanup and return
|
||||
free(buffer);
|
||||
return -1;
|
||||
}
|
||||
|
||||
void* data = jumps + 4;
|
||||
|
||||
//check data
|
||||
if (
|
||||
//data start (the end of the data is padded to the nearest multiple of 4)
|
||||
strcmp( ((char*)data) + ((unsigned int*)jumps)[0], "Hello world!" ) != 0 ||
|
||||
|
||||
false)
|
||||
{
|
||||
fprintf(stderr, TOY_CC_ERROR "ERROR: failed to produce the expected routine data, source: %s\n" TOY_CC_RESET, source);
|
||||
|
||||
//cleanup and return
|
||||
free(buffer);
|
||||
return -1;
|
||||
}
|
||||
|
||||
//cleanup
|
||||
free(buffer);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -686,7 +785,7 @@ int main() {
|
||||
int total = 0, res = 0;
|
||||
|
||||
{
|
||||
Toy_Bucket* bucket = Toy_allocateBucket(sizeof(Toy_Ast) * 32);
|
||||
Toy_Bucket* bucket = Toy_allocateBucket(TOY_BUCKET_IDEAL);
|
||||
res = test_routine_expressions(&bucket);
|
||||
Toy_freeBucket(&bucket);
|
||||
if (res == 0) {
|
||||
@@ -696,7 +795,7 @@ int main() {
|
||||
}
|
||||
|
||||
{
|
||||
Toy_Bucket* bucket = Toy_allocateBucket(sizeof(Toy_Ast) * 32);
|
||||
Toy_Bucket* bucket = Toy_allocateBucket(TOY_BUCKET_IDEAL);
|
||||
res = test_routine_binary(&bucket);
|
||||
Toy_freeBucket(&bucket);
|
||||
if (res == 0) {
|
||||
@@ -706,7 +805,7 @@ int main() {
|
||||
}
|
||||
|
||||
{
|
||||
Toy_Bucket* bucket = Toy_allocateBucket(sizeof(Toy_Ast) * 32);
|
||||
Toy_Bucket* bucket = Toy_allocateBucket(TOY_BUCKET_IDEAL);
|
||||
res = test_routine_keywords(&bucket);
|
||||
Toy_freeBucket(&bucket);
|
||||
if (res == 0) {
|
||||
@@ -716,4 +815,4 @@ int main() {
|
||||
}
|
||||
|
||||
return total;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user