mirror of
https://github.com/krgamestudios/Toy.git
synced 2026-04-15 14:54:07 +10:00
Variables now persist between statements
This commit is contained in:
@@ -18,11 +18,11 @@ static void stderrWrapper(const char* output) {
|
|||||||
fprintf(stderr, "\n"); //default new line
|
fprintf(stderr, "\n"); //default new line
|
||||||
}
|
}
|
||||||
|
|
||||||
void initInterpreter(Interpreter* interpreter, unsigned char* bytecode, int length) {
|
void initInterpreter(Interpreter* interpreter) {
|
||||||
initLiteralArray(&interpreter->literalCache);
|
initLiteralArray(&interpreter->literalCache);
|
||||||
interpreter->scope = pushScope(NULL);
|
interpreter->scope = pushScope(NULL);
|
||||||
interpreter->bytecode = bytecode;
|
interpreter->bytecode = NULL;
|
||||||
interpreter->length = length;
|
interpreter->length = 0;
|
||||||
interpreter->count = 0;
|
interpreter->count = 0;
|
||||||
|
|
||||||
initLiteralArray(&interpreter->stack);
|
initLiteralArray(&interpreter->stack);
|
||||||
@@ -286,6 +286,9 @@ static bool execVarDecl(Interpreter* interpreter, bool lng) {
|
|||||||
Literal type = interpreter->literalCache.literals[typeIndex];
|
Literal type = interpreter->literalCache.literals[typeIndex];
|
||||||
|
|
||||||
if (!declareScopeVariable(interpreter->scope, identifier, type)) {
|
if (!declareScopeVariable(interpreter->scope, identifier, type)) {
|
||||||
|
printf("Can't redefine the variable \"");;
|
||||||
|
printLiteral(identifier);
|
||||||
|
printf("\"\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -353,7 +356,7 @@ static void execInterpreter(Interpreter* interpreter) {
|
|||||||
interpreter->scope = popScope(interpreter->scope);
|
interpreter->scope = popScope(interpreter->scope);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
//TODO: type declarations
|
//TODO: custom type declarations
|
||||||
|
|
||||||
case OP_VAR_DECL:
|
case OP_VAR_DECL:
|
||||||
case OP_VAR_DECL_LONG:
|
case OP_VAR_DECL_LONG:
|
||||||
@@ -372,12 +375,22 @@ static void execInterpreter(Interpreter* interpreter) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void runInterpreter(Interpreter* interpreter) {
|
void runInterpreter(Interpreter* interpreter, unsigned char* bytecode, int length) {
|
||||||
|
//prep the bytecode
|
||||||
|
interpreter->bytecode = bytecode;
|
||||||
|
interpreter->length = length;
|
||||||
|
interpreter->count = 0;
|
||||||
|
|
||||||
if (!interpreter->bytecode) {
|
if (!interpreter->bytecode) {
|
||||||
printf(ERROR "Error: No valid bytecode given\n" RESET);
|
printf(ERROR "Error: No valid bytecode given\n" RESET);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//prep the literal cache
|
||||||
|
if (interpreter->literalCache.count > 0) {
|
||||||
|
freeLiteralArray(&interpreter->literalCache); //automatically inits
|
||||||
|
}
|
||||||
|
|
||||||
//header section
|
//header section
|
||||||
const unsigned char major = readByte(interpreter->bytecode, &interpreter->count);
|
const unsigned char major = readByte(interpreter->bytecode, &interpreter->count);
|
||||||
const unsigned char minor = readByte(interpreter->bytecode, &interpreter->count);
|
const unsigned char minor = readByte(interpreter->bytecode, &interpreter->count);
|
||||||
@@ -515,7 +528,7 @@ void runInterpreter(Interpreter* interpreter) {
|
|||||||
pushLiteralArray(&interpreter->literalCache, identifier);
|
pushLiteralArray(&interpreter->literalCache, identifier);
|
||||||
|
|
||||||
if (command.verbose) {
|
if (command.verbose) {
|
||||||
printf("(identifier %s (%d))\n", AS_IDENTIFIER(identifier), identifier.as.identifier.hash);
|
printf("(identifier %s (hash: %x))\n", AS_IDENTIFIER(identifier), identifier.as.identifier.hash);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -21,16 +21,16 @@ typedef struct Interpreter {
|
|||||||
LiteralArray stack;
|
LiteralArray stack;
|
||||||
|
|
||||||
//output
|
//output
|
||||||
// LiteralDictionary exports; //read-write - interface with Toy from C
|
// LiteralDictionary exports; //TODO: read-write - interface with Toy from C
|
||||||
PrintFn printOutput;
|
PrintFn printOutput;
|
||||||
PrintFn assertOutput;
|
PrintFn assertOutput;
|
||||||
} Interpreter;
|
} Interpreter;
|
||||||
|
|
||||||
void initInterpreter(Interpreter* interpreter, unsigned char* bytecode, int length);
|
void initInterpreter(Interpreter* interpreter);
|
||||||
void freeInterpreter(Interpreter* interpreter);
|
void freeInterpreter(Interpreter* interpreter);
|
||||||
|
|
||||||
//utilities for the host program
|
//utilities for the host program
|
||||||
void setInterpreterPrint(Interpreter* interpreter, PrintFn printOutput);
|
void setInterpreterPrint(Interpreter* interpreter, PrintFn printOutput);
|
||||||
void setInterpreterAssert(Interpreter* interpreter, PrintFn assertOutput);
|
void setInterpreterAssert(Interpreter* interpreter, PrintFn assertOutput);
|
||||||
|
|
||||||
void runInterpreter(Interpreter* interpreter);
|
void runInterpreter(Interpreter* interpreter, unsigned char* bytecode, int length);
|
||||||
|
|||||||
@@ -821,6 +821,10 @@ static void varDecl(Parser* parser, Node** nodeHandle) {
|
|||||||
if (match(parser, TOKEN_ASSIGN)) {
|
if (match(parser, TOKEN_ASSIGN)) {
|
||||||
expression(parser, &expressionNode);
|
expression(parser, &expressionNode);
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
//values are null by default
|
||||||
|
emitNodeLiteral(&expressionNode, TO_NULL_LITERAL);
|
||||||
|
}
|
||||||
|
|
||||||
//TODO: static type checking?
|
//TODO: static type checking?
|
||||||
|
|
||||||
|
|||||||
@@ -103,8 +103,8 @@ unsigned char* compileString(char* source, size_t* size) {
|
|||||||
|
|
||||||
void runBinary(unsigned char* tb, size_t size) {
|
void runBinary(unsigned char* tb, size_t size) {
|
||||||
Interpreter interpreter;
|
Interpreter interpreter;
|
||||||
initInterpreter(&interpreter, tb, size);
|
initInterpreter(&interpreter);
|
||||||
runInterpreter(&interpreter);
|
runInterpreter(&interpreter, tb, size);
|
||||||
freeInterpreter(&interpreter);
|
freeInterpreter(&interpreter);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -143,6 +143,7 @@ void repl() {
|
|||||||
memset(input, 0, size);
|
memset(input, 0, size);
|
||||||
|
|
||||||
Interpreter interpreter; //persist the interpreter for the scopes
|
Interpreter interpreter; //persist the interpreter for the scopes
|
||||||
|
initInterpreter(&interpreter);
|
||||||
|
|
||||||
for(;;) {
|
for(;;) {
|
||||||
printf("> ");
|
printf("> ");
|
||||||
@@ -178,9 +179,7 @@ void repl() {
|
|||||||
unsigned char* tb = collateCompiler(&compiler, &size);
|
unsigned char* tb = collateCompiler(&compiler, &size);
|
||||||
|
|
||||||
//run the bytecode
|
//run the bytecode
|
||||||
initInterpreter(&interpreter, tb, size);
|
runInterpreter(&interpreter, tb, size);
|
||||||
runInterpreter(&interpreter);
|
|
||||||
freeInterpreter(&interpreter); //TODO: option to retain the scopes
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//clean up this iteration
|
//clean up this iteration
|
||||||
|
|||||||
@@ -44,17 +44,17 @@ Scope* popScope(Scope* scope) {
|
|||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
#include <stdio.h>
|
||||||
//returns false if error
|
//returns false if error
|
||||||
bool declareScopeVariable(Scope* scope, Literal key, Literal type) {
|
bool declareScopeVariable(Scope* scope, Literal key, Literal type) {
|
||||||
//store the type, for later checking on assignment
|
|
||||||
setLiteralDictionary(&scope->types, key, type);
|
|
||||||
|
|
||||||
//don't redefine a variable within this scope
|
//don't redefine a variable within this scope
|
||||||
if (existsLiteralDictionary(&scope->variables, key)) {
|
if (existsLiteralDictionary(&scope->variables, key)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//store the type, for later checking on assignment
|
||||||
|
setLiteralDictionary(&scope->types, key, type);
|
||||||
|
|
||||||
setLiteralDictionary(&scope->variables, key, TO_NULL_LITERAL);
|
setLiteralDictionary(&scope->variables, key, TO_NULL_LITERAL);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user