mirror of
https://github.com/krgamestudios/Toy.git
synced 2026-04-15 14:54:07 +10:00
Renemed all variables to fit into a namespace
Basically, all Toy varaibles, functions, etc. are prepended with "Toy_", and macros are prepended with "TOY_". This is to reduce namespace pollution, which was an issue pointed out to be - blame @GyroVorbis. I've also bumped the minor version number - theoretically I should bump the major number, but I'm not quite ready for 1.0 yet.
This commit is contained in:
@@ -1,9 +1,9 @@
|
||||
#include "scope.h"
|
||||
#include "toy_scope.h"
|
||||
|
||||
#include "memory.h"
|
||||
#include "toy_memory.h"
|
||||
|
||||
//run up the ancestor chain, freeing anything with 0 references left
|
||||
static void freeAncestorChain(Scope* scope) {
|
||||
static void freeAncestorChain(Toy_Scope* scope) {
|
||||
scope->references--;
|
||||
|
||||
//free scope chain
|
||||
@@ -15,65 +15,65 @@ static void freeAncestorChain(Scope* scope) {
|
||||
return;
|
||||
}
|
||||
|
||||
freeLiteralDictionary(&scope->variables);
|
||||
freeLiteralDictionary(&scope->types);
|
||||
Toy_freeLiteralDictionary(&scope->variables);
|
||||
Toy_freeLiteralDictionary(&scope->types);
|
||||
|
||||
FREE(Scope, scope);
|
||||
TOY_FREE(Toy_Scope, scope);
|
||||
}
|
||||
|
||||
//return false if invalid type
|
||||
static bool checkType(Literal typeLiteral, Literal original, Literal value, bool constCheck) {
|
||||
static bool checkType(Toy_Literal typeLiteral, Toy_Literal original, Toy_Literal value, bool constCheck) {
|
||||
//for constants, fail if original != value
|
||||
if (constCheck && AS_TYPE(typeLiteral).constant && !literalsAreEqual(original, value)) {
|
||||
if (constCheck && TOY_AS_TYPE(typeLiteral).constant && !Toy_literalsAreEqual(original, value)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//for any types
|
||||
if (AS_TYPE(typeLiteral).typeOf == LITERAL_ANY) {
|
||||
if (TOY_AS_TYPE(typeLiteral).typeOf == TOY_LITERAL_ANY) {
|
||||
return true;
|
||||
}
|
||||
|
||||
//don't allow null types
|
||||
if (AS_TYPE(typeLiteral).typeOf == LITERAL_NULL) {
|
||||
if (TOY_AS_TYPE(typeLiteral).typeOf == TOY_LITERAL_NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//always allow null values
|
||||
if (IS_NULL(value)) {
|
||||
if (TOY_IS_NULL(value)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
//for each type, if a mismatch is found, return false
|
||||
if (AS_TYPE(typeLiteral).typeOf == LITERAL_BOOLEAN && !IS_BOOLEAN(value)) {
|
||||
if (TOY_AS_TYPE(typeLiteral).typeOf == TOY_LITERAL_BOOLEAN && !TOY_IS_BOOLEAN(value)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (AS_TYPE(typeLiteral).typeOf == LITERAL_INTEGER && !IS_INTEGER(value)) {
|
||||
if (TOY_AS_TYPE(typeLiteral).typeOf == TOY_LITERAL_INTEGER && !TOY_IS_INTEGER(value)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (AS_TYPE(typeLiteral).typeOf == LITERAL_FLOAT && !IS_FLOAT(value)) {
|
||||
if (TOY_AS_TYPE(typeLiteral).typeOf == TOY_LITERAL_FLOAT && !TOY_IS_FLOAT(value)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (AS_TYPE(typeLiteral).typeOf == LITERAL_STRING && !IS_STRING(value)) {
|
||||
if (TOY_AS_TYPE(typeLiteral).typeOf == TOY_LITERAL_STRING && !TOY_IS_STRING(value)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (AS_TYPE(typeLiteral).typeOf == LITERAL_ARRAY && !IS_ARRAY(value)) {
|
||||
if (TOY_AS_TYPE(typeLiteral).typeOf == TOY_LITERAL_ARRAY && !TOY_IS_ARRAY(value)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (IS_ARRAY(value)) {
|
||||
if (TOY_IS_ARRAY(value)) {
|
||||
//check value's type
|
||||
if (AS_TYPE(typeLiteral).typeOf != LITERAL_ARRAY) {
|
||||
if (TOY_AS_TYPE(typeLiteral).typeOf != TOY_LITERAL_ARRAY) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//if null, assume it's a new array variable that needs checking
|
||||
if (IS_NULL(original)) {
|
||||
for (int i = 0; i < AS_ARRAY(value)->count; i++) {
|
||||
if (!checkType( ((Literal*)(AS_TYPE(typeLiteral).subtypes))[0], TO_NULL_LITERAL, AS_ARRAY(value)->literals[i], constCheck)) {
|
||||
if (TOY_IS_NULL(original)) {
|
||||
for (int i = 0; i < TOY_AS_ARRAY(value)->count; i++) {
|
||||
if (!checkType( ((Toy_Literal*)(TOY_AS_TYPE(typeLiteral).subtypes))[0], TOY_TO_NULL_LITERAL, TOY_AS_ARRAY(value)->literals[i], constCheck)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -82,36 +82,36 @@ static bool checkType(Literal typeLiteral, Literal original, Literal value, bool
|
||||
}
|
||||
|
||||
//check children
|
||||
for (int i = 0; i < AS_ARRAY(value)->count; i++) {
|
||||
if (AS_ARRAY(original)->count <= i) {
|
||||
for (int i = 0; i < TOY_AS_ARRAY(value)->count; i++) {
|
||||
if (TOY_AS_ARRAY(original)->count <= i) {
|
||||
return true; //assume new entry pushed
|
||||
}
|
||||
|
||||
if (!checkType(((Literal*)(AS_TYPE(typeLiteral).subtypes))[0], AS_ARRAY(original)->literals[i], AS_ARRAY(value)->literals[i], constCheck)) {
|
||||
if (!checkType(((Toy_Literal*)(TOY_AS_TYPE(typeLiteral).subtypes))[0], TOY_AS_ARRAY(original)->literals[i], TOY_AS_ARRAY(value)->literals[i], constCheck)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (AS_TYPE(typeLiteral).typeOf == LITERAL_DICTIONARY && !IS_DICTIONARY(value)) {
|
||||
if (TOY_AS_TYPE(typeLiteral).typeOf == TOY_LITERAL_DICTIONARY && !TOY_IS_DICTIONARY(value)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (IS_DICTIONARY(value)) {
|
||||
if (TOY_IS_DICTIONARY(value)) {
|
||||
//check value's type
|
||||
if (AS_TYPE(typeLiteral).typeOf != LITERAL_DICTIONARY) {
|
||||
if (TOY_AS_TYPE(typeLiteral).typeOf != TOY_LITERAL_DICTIONARY) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//if null, assume it's a new dictionary variable that needs checking
|
||||
if (IS_NULL(original)) {
|
||||
for (int i = 0; i < AS_DICTIONARY(value)->capacity; i++) {
|
||||
if (TOY_IS_NULL(original)) {
|
||||
for (int i = 0; i < TOY_AS_DICTIONARY(value)->capacity; i++) {
|
||||
//check the type of key and value
|
||||
if (!checkType(((Literal*)(AS_TYPE(typeLiteral).subtypes))[0], TO_NULL_LITERAL, AS_DICTIONARY(value)->entries[i].key, constCheck)) {
|
||||
if (!checkType(((Toy_Literal*)(TOY_AS_TYPE(typeLiteral).subtypes))[0], TOY_TO_NULL_LITERAL, TOY_AS_DICTIONARY(value)->entries[i].key, constCheck)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!checkType(((Literal*)(AS_TYPE(typeLiteral).subtypes))[1], TO_NULL_LITERAL, AS_DICTIONARY(value)->entries[i].value, constCheck)) {
|
||||
if (!checkType(((Toy_Literal*)(TOY_AS_TYPE(typeLiteral).subtypes))[1], TOY_TO_NULL_LITERAL, TOY_AS_DICTIONARY(value)->entries[i].value, constCheck)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -120,17 +120,17 @@ static bool checkType(Literal typeLiteral, Literal original, Literal value, bool
|
||||
}
|
||||
|
||||
//check each child of value against the child of original
|
||||
for (int i = 0; i < AS_DICTIONARY(value)->capacity; i++) {
|
||||
if (IS_NULL(AS_DICTIONARY(value)->entries[i].key)) { //only non-tombstones
|
||||
for (int i = 0; i < TOY_AS_DICTIONARY(value)->capacity; i++) {
|
||||
if (TOY_IS_NULL(TOY_AS_DICTIONARY(value)->entries[i].key)) { //only non-tombstones
|
||||
continue;
|
||||
}
|
||||
|
||||
//find the internal child of original that matches this child of value
|
||||
_entry* ptr = NULL;
|
||||
Toy_private_entry* ptr = NULL;
|
||||
|
||||
for (int j = 0; j < AS_DICTIONARY(original)->capacity; j++) {
|
||||
if (literalsAreEqual(AS_DICTIONARY(original)->entries[j].key, AS_DICTIONARY(value)->entries[i].key)) {
|
||||
ptr = &AS_DICTIONARY(original)->entries[j];
|
||||
for (int j = 0; j < TOY_AS_DICTIONARY(original)->capacity; j++) {
|
||||
if (Toy_literalsAreEqual(TOY_AS_DICTIONARY(original)->entries[j].key, TOY_AS_DICTIONARY(value)->entries[i].key)) {
|
||||
ptr = &TOY_AS_DICTIONARY(original)->entries[j];
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -141,21 +141,21 @@ static bool checkType(Literal typeLiteral, Literal original, Literal value, bool
|
||||
}
|
||||
|
||||
//check the type of key and value
|
||||
if (!checkType(((Literal*)(AS_TYPE(typeLiteral).subtypes))[0], ptr->key, AS_DICTIONARY(value)->entries[i].key, constCheck)) {
|
||||
if (!checkType(((Toy_Literal*)(TOY_AS_TYPE(typeLiteral).subtypes))[0], ptr->key, TOY_AS_DICTIONARY(value)->entries[i].key, constCheck)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!checkType(((Literal*)(AS_TYPE(typeLiteral).subtypes))[1], ptr->value, AS_DICTIONARY(value)->entries[i].value, constCheck)) {
|
||||
if (!checkType(((Toy_Literal*)(TOY_AS_TYPE(typeLiteral).subtypes))[1], ptr->value, TOY_AS_DICTIONARY(value)->entries[i].value, constCheck)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (AS_TYPE(typeLiteral).typeOf == LITERAL_FUNCTION && !IS_FUNCTION(value)) {
|
||||
if (TOY_AS_TYPE(typeLiteral).typeOf == TOY_LITERAL_FUNCTION && !TOY_IS_FUNCTION(value)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (AS_TYPE(typeLiteral).typeOf == LITERAL_TYPE && !IS_TYPE(value)) {
|
||||
if (TOY_AS_TYPE(typeLiteral).typeOf == TOY_LITERAL_TYPE && !TOY_IS_TYPE(value)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -163,39 +163,39 @@ static bool checkType(Literal typeLiteral, Literal original, Literal value, bool
|
||||
}
|
||||
|
||||
//exposed functions
|
||||
Scope* pushScope(Scope* ancestor) {
|
||||
Scope* scope = ALLOCATE(Scope, 1);
|
||||
Toy_Scope* Toy_pushScope(Toy_Scope* ancestor) {
|
||||
Toy_Scope* scope = TOY_ALLOCATE(Toy_Scope, 1);
|
||||
scope->ancestor = ancestor;
|
||||
initLiteralDictionary(&scope->variables);
|
||||
initLiteralDictionary(&scope->types);
|
||||
Toy_initLiteralDictionary(&scope->variables);
|
||||
Toy_initLiteralDictionary(&scope->types);
|
||||
|
||||
//tick up all scope reference counts
|
||||
scope->references = 0;
|
||||
for (Scope* ptr = scope; ptr != NULL; ptr = ptr->ancestor) {
|
||||
for (Toy_Scope* ptr = scope; ptr != NULL; ptr = ptr->ancestor) {
|
||||
ptr->references++;
|
||||
}
|
||||
|
||||
return scope;
|
||||
}
|
||||
|
||||
Scope* popScope(Scope* scope) {
|
||||
Toy_Scope* Toy_popScope(Toy_Scope* scope) {
|
||||
if (scope == NULL) { //CAN pop a null
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Scope* ret = scope->ancestor;
|
||||
Toy_Scope* ret = scope->ancestor;
|
||||
|
||||
//BUGFIX: when freeing a scope, free the function's scopes manually
|
||||
for (int i = 0; i < scope->variables.capacity; i++) {
|
||||
//handle keys, just in case
|
||||
if (IS_FUNCTION(scope->variables.entries[i].key)) {
|
||||
popScope(AS_FUNCTION(scope->variables.entries[i].key).scope);
|
||||
AS_FUNCTION(scope->variables.entries[i].key).scope = NULL;
|
||||
if (TOY_IS_FUNCTION(scope->variables.entries[i].key)) {
|
||||
Toy_popScope(TOY_AS_FUNCTION(scope->variables.entries[i].key).scope);
|
||||
TOY_AS_FUNCTION(scope->variables.entries[i].key).scope = NULL;
|
||||
}
|
||||
|
||||
if (IS_FUNCTION(scope->variables.entries[i].value)) {
|
||||
popScope(AS_FUNCTION(scope->variables.entries[i].value).scope);
|
||||
AS_FUNCTION(scope->variables.entries[i].value).scope = NULL;
|
||||
if (TOY_IS_FUNCTION(scope->variables.entries[i].value)) {
|
||||
Toy_popScope(TOY_AS_FUNCTION(scope->variables.entries[i].value).scope);
|
||||
TOY_AS_FUNCTION(scope->variables.entries[i].value).scope = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -204,28 +204,28 @@ Scope* popScope(Scope* scope) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
Scope* copyScope(Scope* original) {
|
||||
Scope* scope = ALLOCATE(Scope, 1);
|
||||
Toy_Scope* Toy_copyScope(Toy_Scope* original) {
|
||||
Toy_Scope* scope = TOY_ALLOCATE(Toy_Scope, 1);
|
||||
scope->ancestor = original->ancestor;
|
||||
initLiteralDictionary(&scope->variables);
|
||||
initLiteralDictionary(&scope->types);
|
||||
Toy_initLiteralDictionary(&scope->variables);
|
||||
Toy_initLiteralDictionary(&scope->types);
|
||||
|
||||
//tick up all scope reference counts
|
||||
scope->references = 0;
|
||||
for (Scope* ptr = scope; ptr != NULL; ptr = ptr->ancestor) {
|
||||
for (Toy_Scope* ptr = scope; ptr != NULL; ptr = ptr->ancestor) {
|
||||
ptr->references++;
|
||||
}
|
||||
|
||||
//copy the contents of the dictionaries
|
||||
for (int i = 0; i < original->variables.capacity; i++) {
|
||||
if (!IS_NULL(original->variables.entries[i].key)) {
|
||||
setLiteralDictionary(&scope->variables, original->variables.entries[i].key, original->variables.entries[i].value);
|
||||
if (!TOY_IS_NULL(original->variables.entries[i].key)) {
|
||||
Toy_setLiteralDictionary(&scope->variables, original->variables.entries[i].key, original->variables.entries[i].value);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < original->types.capacity; i++) {
|
||||
if (!IS_NULL(original->types.entries[i].key)) {
|
||||
setLiteralDictionary(&scope->types, original->types.entries[i].key, original->types.entries[i].value);
|
||||
if (!TOY_IS_NULL(original->types.entries[i].key)) {
|
||||
Toy_setLiteralDictionary(&scope->types, original->types.entries[i].key, original->types.entries[i].value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -233,92 +233,92 @@ Scope* copyScope(Scope* original) {
|
||||
}
|
||||
|
||||
//returns false if error
|
||||
bool declareScopeVariable(Scope* scope, Literal key, Literal type) {
|
||||
bool Toy_declareScopeVariable(Toy_Scope* scope, Toy_Literal key, Toy_Literal type) {
|
||||
//don't redefine a variable within this scope
|
||||
if (existsLiteralDictionary(&scope->variables, key)) {
|
||||
if (Toy_existsLiteralDictionary(&scope->variables, key)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!IS_TYPE(type)) {
|
||||
if (!TOY_IS_TYPE(type)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//store the type, for later checking on assignment
|
||||
setLiteralDictionary(&scope->types, key, type);
|
||||
Toy_setLiteralDictionary(&scope->types, key, type);
|
||||
|
||||
setLiteralDictionary(&scope->variables, key, TO_NULL_LITERAL);
|
||||
Toy_setLiteralDictionary(&scope->variables, key, TOY_TO_NULL_LITERAL);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool isDelcaredScopeVariable(Scope* scope, Literal key) {
|
||||
bool Toy_isDelcaredScopeVariable(Toy_Scope* scope, Toy_Literal key) {
|
||||
if (scope == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//if it's not in this scope, keep searching up the chain
|
||||
if (!existsLiteralDictionary(&scope->variables, key)) {
|
||||
return isDelcaredScopeVariable(scope->ancestor, key);
|
||||
if (!Toy_existsLiteralDictionary(&scope->variables, key)) {
|
||||
return Toy_isDelcaredScopeVariable(scope->ancestor, key);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//return false if undefined, or can't be assigned
|
||||
bool setScopeVariable(Scope* scope, Literal key, Literal value, bool constCheck) {
|
||||
bool Toy_setScopeVariable(Toy_Scope* scope, Toy_Literal key, Toy_Literal value, bool constCheck) {
|
||||
//dead end
|
||||
if (scope == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//if it's not in this scope, keep searching up the chain
|
||||
if (!existsLiteralDictionary(&scope->variables, key)) {
|
||||
return setScopeVariable(scope->ancestor, key, value, constCheck);
|
||||
if (!Toy_existsLiteralDictionary(&scope->variables, key)) {
|
||||
return Toy_setScopeVariable(scope->ancestor, key, value, constCheck);
|
||||
}
|
||||
|
||||
//type checking
|
||||
Literal typeLiteral = getLiteralDictionary(&scope->types, key);
|
||||
Literal original = getLiteralDictionary(&scope->variables, key);
|
||||
Toy_Literal typeLiteral = Toy_getLiteralDictionary(&scope->types, key);
|
||||
Toy_Literal original = Toy_getLiteralDictionary(&scope->variables, key);
|
||||
|
||||
if (!checkType(typeLiteral, original, value, constCheck)) {
|
||||
freeLiteral(typeLiteral);
|
||||
freeLiteral(original);
|
||||
Toy_freeLiteral(typeLiteral);
|
||||
Toy_freeLiteral(original);
|
||||
return false;
|
||||
}
|
||||
|
||||
//actually assign
|
||||
setLiteralDictionary(&scope->variables, key, value);
|
||||
Toy_setLiteralDictionary(&scope->variables, key, value);
|
||||
|
||||
freeLiteral(typeLiteral);
|
||||
freeLiteral(original);
|
||||
Toy_freeLiteral(typeLiteral);
|
||||
Toy_freeLiteral(original);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool getScopeVariable(Scope* scope, Literal key, Literal* valueHandle) {
|
||||
bool Toy_getScopeVariable(Toy_Scope* scope, Toy_Literal key, Toy_Literal* valueHandle) {
|
||||
//dead end
|
||||
if (scope == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//if it's not in this scope, keep searching up the chain
|
||||
if (!existsLiteralDictionary(&scope->variables, key)) {
|
||||
return getScopeVariable(scope->ancestor, key, valueHandle);
|
||||
if (!Toy_existsLiteralDictionary(&scope->variables, key)) {
|
||||
return Toy_getScopeVariable(scope->ancestor, key, valueHandle);
|
||||
}
|
||||
|
||||
*valueHandle = getLiteralDictionary(&scope->variables, key);
|
||||
*valueHandle = Toy_getLiteralDictionary(&scope->variables, key);
|
||||
return true;
|
||||
}
|
||||
|
||||
Literal getScopeType(Scope* scope, Literal key) {
|
||||
Toy_Literal Toy_getScopeType(Toy_Scope* scope, Toy_Literal key) {
|
||||
//dead end
|
||||
if (scope == NULL) {
|
||||
return TO_NULL_LITERAL;
|
||||
return TOY_TO_NULL_LITERAL;
|
||||
}
|
||||
|
||||
//if it's not in this scope, keep searching up the chain
|
||||
if (!existsLiteralDictionary(&scope->types, key)) {
|
||||
return getScopeType(scope->ancestor, key);
|
||||
if (!Toy_existsLiteralDictionary(&scope->types, key)) {
|
||||
return Toy_getScopeType(scope->ancestor, key);
|
||||
}
|
||||
|
||||
return getLiteralDictionary(&scope->types, key);
|
||||
return Toy_getLiteralDictionary(&scope->types, key);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user