mirror of
https://github.com/krgamestudios/Toy.git
synced 2026-04-15 23:04:08 +10:00
While and for loops are working
This commit is contained in:
@@ -149,7 +149,7 @@ void writeCompiler(Compiler* compiler, Node* node) {
|
||||
if (compiler->capacity < compiler->count + 1) {
|
||||
int oldCapacity = compiler->capacity;
|
||||
|
||||
compiler->capacity = GROW_CAPACITY(oldCapacity);
|
||||
compiler->capacity = GROW_CAPACITY_FAST(oldCapacity);
|
||||
compiler->bytecode = GROW_ARRAY(unsigned char, compiler->bytecode, oldCapacity, compiler->capacity);
|
||||
}
|
||||
|
||||
@@ -322,13 +322,63 @@ void writeCompiler(Compiler* compiler, Node* node) {
|
||||
}
|
||||
break;
|
||||
|
||||
// case NODE_PATH_WHILE: {
|
||||
// //cache the jump point
|
||||
// int jumpToBeginning = compiler->count;
|
||||
// compiler->count += sizeof(unsigned short); //2 bytes
|
||||
case NODE_PATH_WHILE: {
|
||||
//cache the jump point
|
||||
unsigned short jumpFromEnd = compiler->count;
|
||||
|
||||
// //
|
||||
// }
|
||||
//process the condition
|
||||
writeCompiler(compiler, node->path.condition);
|
||||
|
||||
//if false, jump to end
|
||||
compiler->bytecode[compiler->count++] = OP_IF_FALSE_JUMP; //1 byte
|
||||
unsigned short jumpToEnd = compiler->count;
|
||||
compiler->count += sizeof(unsigned short); //2 bytes
|
||||
|
||||
//write the body
|
||||
writeCompiler(compiler, node->path.thenPath);
|
||||
|
||||
//jump to condition
|
||||
compiler->bytecode[compiler->count++] = OP_JUMP; //1 byte
|
||||
compiler->bytecode[compiler->count] = jumpFromEnd;
|
||||
compiler->count += sizeof(unsigned short); //2 bytes
|
||||
|
||||
//jump from condition
|
||||
compiler->bytecode[jumpToEnd] = compiler->count;
|
||||
}
|
||||
break;
|
||||
|
||||
case NODE_PATH_FOR: {
|
||||
compiler->bytecode[compiler->count++] = OP_SCOPE_BEGIN; //1 byte
|
||||
|
||||
//initial setup
|
||||
writeCompiler(compiler, node->path.preClause);
|
||||
|
||||
//conditional
|
||||
unsigned short jumpFromEnd = compiler->count;
|
||||
writeCompiler(compiler, node->path.condition);
|
||||
|
||||
//if false jump to end
|
||||
compiler->bytecode[compiler->count++] = OP_IF_FALSE_JUMP; //1 byte
|
||||
unsigned short jumpToEnd = compiler->count;
|
||||
compiler->count += sizeof(unsigned short); //2 bytes
|
||||
|
||||
//write the body
|
||||
compiler->bytecode[compiler->count++] = OP_SCOPE_BEGIN; //1 byte
|
||||
writeCompiler(compiler, node->path.thenPath);
|
||||
compiler->bytecode[compiler->count++] = OP_SCOPE_END; //1 byte
|
||||
|
||||
//evaluate third clause, restart
|
||||
writeCompiler(compiler, node->path.postClause);
|
||||
|
||||
compiler->bytecode[compiler->count++] = OP_JUMP; //1 byte
|
||||
compiler->bytecode[compiler->count] = jumpFromEnd;
|
||||
compiler->count += sizeof(unsigned short); //2 bytes
|
||||
|
||||
compiler->bytecode[jumpToEnd] = compiler->count;
|
||||
|
||||
compiler->bytecode[compiler->count++] = OP_SCOPE_END; //1 byte
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#define ALLOCATE(type, count) ((type*)reallocate(NULL, 0, sizeof(type) * (count)))
|
||||
#define FREE(type, pointer) reallocate(pointer, sizeof(type), 0)
|
||||
#define GROW_CAPACITY(capacity) ((capacity) < 8 ? 8 : (capacity) * 2)
|
||||
#define GROW_CAPACITY_FAST(capacity) ((capacity) < 32 ? 32 : (capacity) * 2)
|
||||
#define GROW_ARRAY(type, pointer, oldCount, count) (type*)reallocate((type*)pointer, sizeof(type) * (oldCount), sizeof(type) * (count))
|
||||
#define SHRINK_ARRAY(type, pointer, oldCount, count) (type*)reallocate((type*)pointer, sizeof(type) * (oldCount), sizeof(type) * (count))
|
||||
#define FREE_ARRAY(type, pointer, oldCount) reallocate((type*)pointer, sizeof(type) * (oldCount), 0)
|
||||
|
||||
@@ -925,11 +925,11 @@ static void ifStmt(Parser* parser, Node** nodeHandle) {
|
||||
Node* elsePath = NULL;
|
||||
|
||||
//read the condition
|
||||
consume(parser, TOKEN_PAREN_LEFT, "Expected '(' at end of if statement");
|
||||
consume(parser, TOKEN_PAREN_LEFT, "Expected '(' at beginning of if clause");
|
||||
parsePrecedence(parser, &condition, PREC_TERNARY);
|
||||
|
||||
//read the then path
|
||||
consume(parser, TOKEN_PAREN_RIGHT, "Expected ')' at end of if statement");
|
||||
consume(parser, TOKEN_PAREN_RIGHT, "Expected ')' at end of if clause");
|
||||
thenPath = ALLOCATE(Node, 1);
|
||||
declaration(parser, &thenPath);
|
||||
|
||||
@@ -944,11 +944,45 @@ static void ifStmt(Parser* parser, Node** nodeHandle) {
|
||||
}
|
||||
|
||||
static void whileStmt(Parser* parser, Node** nodeHandle) {
|
||||
//
|
||||
Node* condition = NULL;
|
||||
Node* thenPath = NULL;
|
||||
|
||||
//read the condition
|
||||
consume(parser, TOKEN_PAREN_LEFT, "Expected '(' at beginning of while clause");
|
||||
parsePrecedence(parser, &condition, PREC_TERNARY);
|
||||
|
||||
//read the then path
|
||||
consume(parser, TOKEN_PAREN_RIGHT, "Expected ')' at end of while clause");
|
||||
thenPath = ALLOCATE(Node, 1);
|
||||
declaration(parser, &thenPath);
|
||||
|
||||
freeNode(*nodeHandle); //free the initial node
|
||||
emitNodePath(nodeHandle, NODE_PATH_WHILE, NULL, NULL, condition, thenPath, NULL);
|
||||
}
|
||||
|
||||
static void forStmt(Parser* parser, Node** nodeHandle) {
|
||||
//
|
||||
Node* preClause = ALLOCATE(Node, 1);
|
||||
Node* postClause = NULL;
|
||||
Node* condition = NULL;
|
||||
Node* thenPath = ALLOCATE(Node, 1);
|
||||
|
||||
//read the clauses
|
||||
consume(parser, TOKEN_PAREN_LEFT, "Expected '(' at beginning of for clause");
|
||||
declaration(parser, &preClause);
|
||||
|
||||
parsePrecedence(parser, &condition, PREC_TERNARY);
|
||||
|
||||
consume(parser, TOKEN_SEMICOLON, "Expected ';' after condition of for clause");
|
||||
parsePrecedence(parser, &postClause, PREC_ASSIGNMENT);
|
||||
|
||||
consume(parser, TOKEN_PAREN_RIGHT, "Expected ')' at end of for clause");
|
||||
|
||||
//read the path
|
||||
thenPath = ALLOCATE(Node, 1);
|
||||
declaration(parser, &thenPath);
|
||||
|
||||
freeNode(*nodeHandle); //free the initial node
|
||||
emitNodePath(nodeHandle, NODE_PATH_FOR, preClause, postClause, condition, thenPath, NULL);
|
||||
}
|
||||
|
||||
//precedence functions
|
||||
|
||||
@@ -18,4 +18,23 @@ else {
|
||||
}
|
||||
|
||||
|
||||
print "All good";
|
||||
//test while loop
|
||||
var whileCounter = 0;
|
||||
while (whileCounter < 10) {
|
||||
whileCounter = whileCounter + 1;
|
||||
}
|
||||
|
||||
assert whileCounter == 10, "while-loop failed";
|
||||
|
||||
|
||||
//test for loop
|
||||
var forCache = 0;
|
||||
for (var i = 0; i < 20; i = i + 1) {
|
||||
forCache = i;
|
||||
}
|
||||
|
||||
assert forCache == 19, "for-loop failed";
|
||||
|
||||
|
||||
print "All good";
|
||||
|
||||
|
||||
Reference in New Issue
Block a user