Resolved #45, Exports region removed

This commit is contained in:
2023-01-13 16:12:44 +00:00
parent 0649a141dd
commit 3498baad9b
12 changed files with 23 additions and 296 deletions

View File

@@ -129,11 +129,6 @@ void freeASTNodeCustom(ASTNode* node, bool freeSelf) {
freeLiteral(node->import.identifier);
freeLiteral(node->import.alias);
break;
case AST_NODE_EXPORT:
freeLiteral(node->export.identifier);
freeLiteral(node->export.alias);
break;
}
if (freeSelf) {
@@ -371,13 +366,3 @@ void emitASTNodeImport(ASTNode** nodeHandle, Literal identifier, Literal alias)
*nodeHandle = tmp;
}
void emitASTNodeExport(ASTNode** nodeHandle, Literal identifier, Literal alias) {
ASTNode* tmp = ALLOCATE(ASTNode, 1);
tmp->type = AST_NODE_EXPORT;
tmp->export.identifier = copyLiteral(identifier);
tmp->export.alias = copyLiteral(alias);
*nodeHandle = tmp;
}

View File

@@ -32,8 +32,7 @@ typedef enum ASTNodeType {
AST_NODE_POSTFIX_INCREMENT, //increment a variable
AST_NODE_PREFIX_DECREMENT, //decrement a variable
AST_NODE_POSTFIX_DECREMENT, //decrement a variable
AST_NODE_IMPORT, //import a variable
AST_NODE_EXPORT, //export a variable
AST_NODE_IMPORT, //import a library
} ASTNodeType;
//literals
@@ -219,9 +218,8 @@ typedef struct NodePostfixDecrement {
Literal identifier;
} NodePostfixDecrement;
//import/export a variable
//import a library
void emitASTNodeImport(ASTNode** nodeHandle, Literal identifier, Literal alias);
void emitASTNodeExport(ASTNode** nodeHandle, Literal identifier, Literal alias);
typedef struct NodeImport {
ASTNodeType type;
@@ -229,12 +227,6 @@ typedef struct NodeImport {
Literal alias;
} NodeImport;
typedef struct NodeExport {
ASTNodeType type;
Literal identifier;
Literal alias;
} NodeExport;
union _node {
ASTNodeType type;
NodeLiteral atomic;
@@ -260,7 +252,6 @@ union _node {
NodePostfixIncrement postfixIncrement;
NodePostfixDecrement postfixDecrement;
NodeImport import;
NodeExport export;
};
TOY_API void freeASTNode(ASTNode* node);

View File

@@ -846,16 +846,6 @@ static Opcode writeCompilerWithJumps(Compiler* compiler, ASTNode* node, void* br
}
break;
case AST_NODE_EXPORT: {
//push the identifier, and the alias
writeLiteralToCompiler(compiler, node->import.identifier);
writeLiteralToCompiler(compiler, node->import.alias);
//push the import opcode
compiler->bytecode[compiler->count++] = (unsigned char)OP_EXPORT; //1 byte
}
break;
case AST_NODE_INDEX: {
//pass to the child nodes, then embed the opcode

View File

@@ -1227,8 +1227,6 @@ bool callLiteralFn(Interpreter* interpreter, Literal func, LiteralArray* argumen
inner.depth = interpreter->depth + 1;
inner.panic = false;
initLiteralArray(&inner.stack);
inner.exports = interpreter->exports;
inner.exportTypes = interpreter->exportTypes;
inner.hooks = interpreter->hooks;
setInterpreterPrint(&inner, interpreter->printOutput);
setInterpreterAssert(&inner, interpreter->assertOutput);
@@ -1473,7 +1471,16 @@ static bool execImport(Interpreter* interpreter) {
Literal identifier = popLiteralArray(&interpreter->stack);
//access the hooks
if (existsLiteralDictionary(interpreter->hooks, identifier)) {
if (!existsLiteralDictionary(interpreter->hooks, identifier)) {
interpreter->errorOutput("Unknown library name in import statement: ");
printLiteralCustom(identifier, interpreter->errorOutput);
interpreter->errorOutput("\"\n");
freeLiteral(alias);
freeLiteral(identifier);
return false;
}
Literal func = getLiteralDictionary(interpreter->hooks, identifier);
if (!IS_FUNCTION_NATIVE(func)) {
@@ -1497,77 +1504,6 @@ static bool execImport(Interpreter* interpreter) {
return true;
}
Literal lit = getLiteralDictionary(interpreter->exports, identifier);
Literal type = getLiteralDictionary(interpreter->exportTypes, identifier);
//use the alias
if (!IS_NULL(alias)) {
if (!declareScopeVariable(interpreter->scope, alias, type)) {
interpreter->errorOutput("Can't redefine the variable \"");
printLiteralCustom(alias, interpreter->errorOutput);
interpreter->errorOutput("\"\n");
freeLiteral(lit);
freeLiteral(type);
freeLiteral(alias);
freeLiteral(identifier);
return false;
}
setScopeVariable(interpreter->scope, alias, lit, false);
}
//use the original identifier
else {
if (!declareScopeVariable(interpreter->scope, identifier, type)) {
interpreter->errorOutput("Can't redefine the variable \"");
printLiteralCustom(identifier, interpreter->errorOutput);
interpreter->errorOutput("\"\n");
freeLiteral(lit);
freeLiteral(type);
freeLiteral(alias);
freeLiteral(identifier);
return false;
}
setScopeVariable(interpreter->scope, identifier, lit, false);
}
//cleanup
freeLiteral(lit);
freeLiteral(type);
freeLiteral(alias);
freeLiteral(identifier);
return true;
}
static bool execExport(Interpreter* interpreter) {
Literal alias = popLiteralArray(&interpreter->stack);
Literal identifier = popLiteralArray(&interpreter->stack);
Literal lit = TO_NULL_LITERAL;
getScopeVariable(interpreter->scope, identifier, &lit);
Literal type = getScopeType(interpreter->scope, identifier);
if (!IS_NULL(alias)) {
setLiteralDictionary(interpreter->exports, alias, lit);
setLiteralDictionary(interpreter->exportTypes, alias, type);
}
else {
setLiteralDictionary(interpreter->exports, identifier, lit);
setLiteralDictionary(interpreter->exportTypes, identifier, type);
}
//cleanup
freeLiteral(lit);
freeLiteral(type);
freeLiteral(alias);
freeLiteral(identifier);
return true;
}
static bool execIndex(Interpreter* interpreter, bool assignIntermediate) {
//assume -> compound, first, second, third are all on the stack
@@ -2087,12 +2023,6 @@ static void execInterpreter(Interpreter* interpreter) {
}
break;
case OP_EXPORT:
if (!execExport(interpreter)) {
return;
}
break;
case OP_INDEX:
if (!execIndex(interpreter, false)) {
return;
@@ -2401,11 +2331,6 @@ static void readInterpreterSections(Interpreter* interpreter) {
//exposed functions
void initInterpreter(Interpreter* interpreter) {
//NOTE: separate initialization for exports
interpreter->exports = ALLOCATE(LiteralDictionary, 1);
initLiteralDictionary(interpreter->exports);
interpreter->exportTypes = ALLOCATE(LiteralDictionary, 1);
initLiteralDictionary(interpreter->exportTypes);
interpreter->hooks = ALLOCATE(LiteralDictionary, 1);
initLiteralDictionary(interpreter->hooks);
@@ -2520,26 +2445,6 @@ void freeInterpreter(Interpreter* interpreter) {
interpreter->scope = popScope(interpreter->scope);
}
//BUGFIX: handle scopes/types in the exports
for (int i = 0; i < interpreter->exports->capacity; i++) {
if (IS_FUNCTION(interpreter->exports->entries[i].key)) {
popScope(AS_FUNCTION(interpreter->exports->entries[i].key).scope);
AS_FUNCTION(interpreter->exports->entries[i].key).scope = NULL;
}
if (IS_FUNCTION(interpreter->exports->entries[i].value)) {
popScope(AS_FUNCTION(interpreter->exports->entries[i].value).scope);
AS_FUNCTION(interpreter->exports->entries[i].value).scope = NULL;
}
}
freeLiteralDictionary(interpreter->exports);
FREE(LiteralDictionary, interpreter->exports);
interpreter->exports = NULL;
freeLiteralDictionary(interpreter->exportTypes);
FREE(LiteralDictionary, interpreter->exportTypes);
interpreter->exportTypes = NULL;
freeLiteralDictionary(interpreter->hooks);
FREE(LiteralDictionary, interpreter->hooks);
interpreter->hooks = NULL;

View File

@@ -21,8 +21,7 @@ typedef struct Interpreter {
Scope* scope;
LiteralArray stack;
LiteralDictionary* exports; //read-write - interface with Toy from C - this is a pointer, since it works at a script-level
LiteralDictionary* exportTypes;
//Library APIs
LiteralDictionary* hooks;
//debug outputs

View File

@@ -46,7 +46,7 @@ typedef enum Opcode {
OP_TYPE_OF, //get the type of a variable
OP_IMPORT,
OP_EXPORT,
OP_EXPORT_removed,
//for indexing
OP_INDEX,

View File

@@ -1321,37 +1321,6 @@ static void importStmt(Parser* parser, ASTNode** nodeHandle) {
freeLiteral(alias);
}
static void exportStmt(Parser* parser, ASTNode** nodeHandle) {
//read the identifier
ASTNode* node = NULL;
advance(parser);
identifier(parser, &node);
if (node == NULL) {
return;
}
Literal idn = copyLiteral(node->atomic.literal);
freeASTNode(node);
Literal alias = TO_NULL_LITERAL;
if (match(parser, TOKEN_AS)) {
ASTNode* node;
advance(parser);
identifier(parser, &node);
alias = copyLiteral(node->atomic.literal);
freeASTNode(node);
}
emitASTNodeExport(nodeHandle, idn, alias);
consume(parser, TOKEN_SEMICOLON, "Expected ';' at end of export statement");
freeLiteral(idn);
freeLiteral(alias);
}
//precedence functions
static void expressionStmt(Parser* parser, ASTNode** nodeHandle) {
//BUGFIX: check for empty statements
@@ -1431,12 +1400,6 @@ static void statement(Parser* parser, ASTNode** nodeHandle) {
return;
}
//export
if (match(parser, TOKEN_EXPORT)) {
exportStmt(parser, nodeHandle);
return;
}
//default
expressionStmt(parser, nodeHandle);
}

View File

@@ -5,8 +5,8 @@
#include <stdint.h>
#define TOY_VERSION_MAJOR 0
#define TOY_VERSION_MINOR 6
#define TOY_VERSION_PATCH 5
#define TOY_VERSION_MINOR 7
#define TOY_VERSION_PATCH 0
#define TOY_VERSION_BUILD __DATE__ " " __TIME__
//platform-specific specifications

View File

@@ -1,52 +0,0 @@
//test basic import/export
{
var variable: int = 42;
export variable as field;
}
{
import field as value;
assert value == 42, "import/export failed";
}
//test functions using import/export
{
fn f() {
import field;
assert field == 42, "import in function failed";
}
}
//test importing/exporting of functions
{
fn func() {
return 69;
}
export func;
}
{
import func;
assert func() == 69, "import/export of functions failed";
}
//test that variables retain their types with the typeof keyword
{
var t: type = int;
export t;
}
{
import t;
assert typeof t == type, "type retention failed";
}
print "All good";

View File

@@ -1,11 +0,0 @@
//test exports
var field: int = 42;
fn function() {
return 69;
}
export field;
export function;
print "All good";

View File

@@ -1,10 +0,0 @@
//test imports
import field;
//import function;
//assert field == 42, "import field failed";
//assert function() == 69, "import function failed";
print "All good";

View File

@@ -186,7 +186,6 @@ int main() {
"dot-chaining.toy",
"dottify-bugfix.toy",
"functions.toy",
"imports-and-exports.toy",
"index-arrays.toy",
"index-dictionaries.toy",
"index-strings.toy",
@@ -212,38 +211,6 @@ int main() {
}
}
{
//read source
size_t dummy;
size_t exportSize, importSize;
char* exportSource = readFile("scripts/separate-exports.toy", &dummy);
char* importSource = readFile("scripts/separate-imports.toy", &dummy);
//compile
unsigned char* exportBinary = compileString(exportSource, &exportSize);
unsigned char* importBinary = compileString(importSource, &importSize);
//run the interpreter over both binaries
Interpreter interpreter;
initInterpreter(&interpreter);
//NOTE: supress print output for testing
setInterpreterPrint(&interpreter, noPrintFn);
setInterpreterAssert(&interpreter, noAssertFn);
runInterpreter(&interpreter, exportBinary, exportSize); //automatically frees the binary data
resetInterpreter(&interpreter);
runInterpreter(&interpreter, importBinary, importSize); //automatically frees the binary data
freeInterpreter(&interpreter);
//cleanup
free((void*)exportSource);
free((void*)importSource);
}
//1, to allow for the assertion test
if (ignoredAssertions > 1) {
fprintf(stderr, ERROR "Assertions hidden: %d\n", ignoredAssertions);