While and for loops are working

This commit is contained in:
2022-08-20 13:27:47 +01:00
parent 975ed41d14
commit f5e060051e
4 changed files with 116 additions and 12 deletions

View File

@@ -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;
}
}

View File

@@ -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)

View File

@@ -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

View File

@@ -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";