Added types and constness

Fixed #144
This commit is contained in:
2024-11-02 11:39:14 +11:00
parent 3ad53c5e0e
commit 7173f7770f
14 changed files with 266 additions and 44 deletions

View File

@@ -255,7 +255,7 @@ int test_type_emission(Toy_Bucket** bucketHandle) {
{
//build the AST
Toy_Ast* ast = NULL;
Toy_String* name = Toy_createNameStringLength(bucketHandle, "foobar", 6, TOY_VALUE_NULL);
Toy_String* name = Toy_createNameStringLength(bucketHandle, "foobar", 6, TOY_VALUE_ANY, false);
Toy_private_emitAstVariableDeclaration(bucketHandle, &ast, name, NULL);
@@ -284,7 +284,7 @@ int test_type_emission(Toy_Bucket** bucketHandle) {
//build the AST
Toy_Ast* ast = NULL;
Toy_Ast* right = NULL;
Toy_String* name = Toy_createNameStringLength(bucketHandle, "foobar", 6, TOY_VALUE_INTEGER);
Toy_String* name = Toy_createNameStringLength(bucketHandle, "foobar", 6, TOY_VALUE_INTEGER, false);
Toy_private_emitAstValue(bucketHandle, &right, TOY_VALUE_FROM_INTEGER(69));
Toy_private_emitAstVariableAssignment(bucketHandle, &ast, name, TOY_AST_FLAG_ASSIGN, right);
@@ -310,7 +310,7 @@ int test_type_emission(Toy_Bucket** bucketHandle) {
//build the AST
Toy_Ast* ast = NULL;
Toy_Ast* right = NULL;
Toy_String* name = Toy_createNameStringLength(bucketHandle, "foobar", 6, TOY_VALUE_INTEGER);
Toy_String* name = Toy_createNameStringLength(bucketHandle, "foobar", 6, TOY_VALUE_INTEGER, false);
Toy_private_emitAstVariableAccess(bucketHandle, &ast, name);
//check if it worked

View File

@@ -829,7 +829,115 @@ int test_routine_keywords(Toy_Bucket** bucketHandle) {
*(int*)(code + 4) != 42 ||
*((unsigned char*)(code + 8)) != TOY_OPCODE_DECLARE ||
*((unsigned char*)(code + 9)) != TOY_VALUE_NULL || //NOTE: will change in future
*((unsigned char*)(code + 9)) != TOY_VALUE_ANY ||
*((unsigned char*)(code + 10)) != 6 || //strlen
*((unsigned char*)(code + 11)) != 0 ||
*(unsigned int*)(code + 12) != 0 || //the jump index
*((unsigned char*)(code + 16)) != TOY_OPCODE_RETURN ||
*((unsigned char*)(code + 17)) != 0 ||
*((unsigned char*)(code + 18)) != 0 ||
*((unsigned char*)(code + 19)) != 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 + 20;
//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], "foobar" ) != 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);
}
//var declare (with type)
{
//setup
const char* source = "var foobar: int = 42;";
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] != 8 || //data size
header[4] != 0 || //subs size
// header[??] != ?? || //params address
header[5] != 32 || //code address
header[6] != 52 || //jumps address
header[7] != 56 || //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_INTEGER ||
*((unsigned char*)(code + 2)) != 0 ||
*((unsigned char*)(code + 3)) != 0 ||
*(int*)(code + 4) != 42 ||
*((unsigned char*)(code + 8)) != TOY_OPCODE_DECLARE ||
*((unsigned char*)(code + 9)) != TOY_VALUE_INTEGER ||
*((unsigned char*)(code + 10)) != 6 || //strlen
*((unsigned char*)(code + 11)) != 0 ||

View File

@@ -304,8 +304,8 @@ int test_scope_elements() {
Toy_Bucket* bucket = Toy_allocateBucket(TOY_BUCKET_IDEAL);
Toy_Scope* scope = Toy_pushScope(&bucket, NULL);
Toy_String* hello1 = Toy_createNameStringLength(&bucket, "hello", 5, TOY_VALUE_NULL);
Toy_String* hello2 = Toy_createNameStringLength(&bucket, "hello", 5, TOY_VALUE_NULL);
Toy_String* hello1 = Toy_createNameStringLength(&bucket, "hello", 5, TOY_VALUE_ANY, false);
Toy_String* hello2 = Toy_createNameStringLength(&bucket, "hello", 5, TOY_VALUE_ANY, false);
//check nothing is here
if (Toy_isDeclaredScope(scope, hello2)) {
@@ -389,7 +389,7 @@ int test_scope_elements() {
Toy_Bucket* bucket = Toy_allocateBucket(TOY_BUCKET_IDEAL);
Toy_Scope* scope = Toy_pushScope(&bucket, NULL);
Toy_String* hello = Toy_createNameStringLength(&bucket, "hello", 5, TOY_VALUE_NULL);
Toy_String* hello = Toy_createNameStringLength(&bucket, "hello", 5, TOY_VALUE_ANY, false);
//declare and push
Toy_declareScope(scope, hello, TOY_VALUE_FROM_INTEGER(42));

View File

@@ -106,7 +106,7 @@ int test_string_allocation() {
Toy_Bucket* bucket = Toy_allocateBucket(1024);
const char* cstring = "Hello world";
Toy_String* str = Toy_createNameStringLength(&bucket, cstring, strlen(cstring), TOY_VALUE_NULL);
Toy_String* str = Toy_createNameStringLength(&bucket, cstring, strlen(cstring), TOY_VALUE_UNKNOWN, false);
//shallow and deep
Toy_String* shallow = Toy_copyString(str);
@@ -652,9 +652,9 @@ int test_string_equality() {
{
//setup
Toy_Bucket* bucket = Toy_allocateBucket(1024);
Toy_String* helloWorldOne = Toy_createNameStringLength(&bucket, "Hello world", strlen("Hello world"), TOY_VALUE_NULL);
Toy_String* helloWorldTwo = Toy_createNameStringLength(&bucket, "Hello world", strlen("Hello world"), TOY_VALUE_NULL);
Toy_String* helloEveryone = Toy_createNameStringLength(&bucket, "Hello everyone", strlen("Hello everyone"), TOY_VALUE_NULL); //TODO: compare types?
Toy_String* helloWorldOne = Toy_createNameStringLength(&bucket, "Hello world", strlen("Hello world"), TOY_VALUE_UNKNOWN, false);
Toy_String* helloWorldTwo = Toy_createNameStringLength(&bucket, "Hello world", strlen("Hello world"), TOY_VALUE_UNKNOWN, false);
Toy_String* helloEveryone = Toy_createNameStringLength(&bucket, "Hello everyone", strlen("Hello everyone"), TOY_VALUE_UNKNOWN, false); //TODO: compare types?
int result = 0; //for print the errors

View File

@@ -330,7 +330,7 @@ int test_scope(Toy_Bucket** bucketHandle) {
Toy_runVM(&vm);
//check the final state of the stack
Toy_String* key = Toy_createNameStringLength(bucketHandle, "foobar", 6, TOY_VALUE_NULL);
Toy_String* key = Toy_createNameStringLength(bucketHandle, "foobar", 6, TOY_VALUE_ANY, false);
if (vm.stack == NULL ||
vm.stack->count != 0 ||
@@ -377,7 +377,7 @@ int test_scope(Toy_Bucket** bucketHandle) {
Toy_runVM(&vm);
//check the final state of the stack
Toy_String* key = Toy_createNameStringLength(bucketHandle, "foobar", 6, TOY_VALUE_NULL);
Toy_String* key = Toy_createNameStringLength(bucketHandle, "foobar", 6, TOY_VALUE_UNKNOWN, false);
if (vm.stack == NULL ||
vm.stack->count != 0 ||

View File

@@ -52,4 +52,19 @@ print !false; //true
//precedence
print true && false || true; //TODO: a warning is needed for this
//TODO: type casting
//types
var a: int;
var b: int = 42;
a = 69;
b = 8891;
print a;
print b;
//constants
var c: int const = 42;
print c;
//TODO: type casting