mirror of
https://github.com/krgamestudios/Toy.git
synced 2026-04-15 14:54:07 +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) {
|
if (compiler->capacity < compiler->count + 1) {
|
||||||
int oldCapacity = compiler->capacity;
|
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);
|
compiler->bytecode = GROW_ARRAY(unsigned char, compiler->bytecode, oldCapacity, compiler->capacity);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -322,13 +322,63 @@ void writeCompiler(Compiler* compiler, Node* node) {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// case NODE_PATH_WHILE: {
|
case NODE_PATH_WHILE: {
|
||||||
// //cache the jump point
|
//cache the jump point
|
||||||
// int jumpToBeginning = compiler->count;
|
unsigned short jumpFromEnd = compiler->count;
|
||||||
// compiler->count += sizeof(unsigned short); //2 bytes
|
|
||||||
|
|
||||||
// //
|
//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 ALLOCATE(type, count) ((type*)reallocate(NULL, 0, sizeof(type) * (count)))
|
||||||
#define FREE(type, pointer) reallocate(pointer, sizeof(type), 0)
|
#define FREE(type, pointer) reallocate(pointer, sizeof(type), 0)
|
||||||
#define GROW_CAPACITY(capacity) ((capacity) < 8 ? 8 : (capacity) * 2)
|
#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 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 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)
|
#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;
|
Node* elsePath = NULL;
|
||||||
|
|
||||||
//read the condition
|
//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);
|
parsePrecedence(parser, &condition, PREC_TERNARY);
|
||||||
|
|
||||||
//read the then path
|
//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);
|
thenPath = ALLOCATE(Node, 1);
|
||||||
declaration(parser, &thenPath);
|
declaration(parser, &thenPath);
|
||||||
|
|
||||||
@@ -944,11 +944,45 @@ static void ifStmt(Parser* parser, Node** nodeHandle) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void whileStmt(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) {
|
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
|
//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