Got scope-based variable shadowing working

This commit is contained in:
2022-08-14 21:32:13 +01:00
parent 4aa6f75ea7
commit 9e899f5974
5 changed files with 50 additions and 9 deletions

View File

@@ -37,6 +37,22 @@ print 1.0 / 2.0;
} }
print "Back to the outer scope."; print "Back to the outer scope.";
//test scope will delegate to higher scope
var a = 1;
{
a = 2;
print a;
}
print a;
//test scope will shadow higher scope on redefine
var b = 3;
{
var b = 4;
print b;
}
print b;
//test compounds, repeatedly //test compounds, repeatedly
print [1, 2, 3]; print [1, 2, 3];
print [4, 5]; print [4, 5];
@@ -69,4 +85,6 @@ assert x, "This won't be seen";
assert true, "This won't be seen"; assert true, "This won't be seen";
assert false, "This is a failed assert, and will end execution"; assert false, "This is a failed assert, and will end execution";
print "This will not be printed because of the above assert"; print "This will not be printed because of the above assert";
//TODO: use a proper assert-based version of this file

View File

@@ -1,2 +1,2 @@
var name : [string const, int] = ["foo" : 42];
var something = 0;

View File

@@ -6,6 +6,8 @@
#include "literal_array.h" #include "literal_array.h"
#include "literal_dictionary.h" #include "literal_dictionary.h"
#include "console_colors.h"
#include <stdio.h> #include <stdio.h>
void initCompiler(Compiler* compiler) { void initCompiler(Compiler* compiler) {
@@ -171,7 +173,7 @@ void writeCompiler(Compiler* compiler, Node* node) {
switch(node->type) { switch(node->type) {
//TODO: more types, like variables, etc. //TODO: more types, like variables, etc.
case NODE_ERROR: { case NODE_ERROR: {
fprintf(stderr, "[Internal] NODE_ERROR encountered in writeCompiler()"); fprintf(stderr, ERROR "[Internal] NODE_ERROR encountered in writeCompiler()\n" RESET);
compiler->bytecode[compiler->count++] = OP_EOF; //1 byte compiler->bytecode[compiler->count++] = OP_EOF; //1 byte
} }
break; break;
@@ -248,7 +250,7 @@ void writeCompiler(Compiler* compiler, Node* node) {
break; break;
case NODE_PAIR: case NODE_PAIR:
fprintf(stderr, "[Internal] NODE_PAIR encountered in writeCompiler()"); fprintf(stderr, ERROR "[Internal] NODE_PAIR encountered in writeCompiler()\n" RESET);
break; break;
case NODE_VAR_TYPES: { //TODO: the "type" keyword case NODE_VAR_TYPES: { //TODO: the "type" keyword

View File

@@ -195,7 +195,7 @@ void printNode(Node* node) {
printNode(&(node->block.nodes[i])); printNode(&(node->block.nodes[i]));
} }
printf("}\n"); printf("\n}\n");
break; break;
case NODE_COMPOUND: case NODE_COMPOUND:
@@ -229,5 +229,8 @@ void printNode(Node* node) {
printNode(node->varDecl.expression); printNode(node->varDecl.expression);
printf(")"); printf(")");
break; break;
default:
printf("[internal] unkown node type in printNode: %d\n", node->type);
} }
} }

View File

@@ -57,6 +57,10 @@ static void consume(Parser* parser, TokenType tokenType, const char* msg) {
} }
static void synchronize(Parser* parser) { static void synchronize(Parser* parser) {
if (command.verbose) {
printf(ERROR "synchronizing\n" RESET);
}
while (parser->current.type != TOKEN_EOF) { while (parser->current.type != TOKEN_EOF) {
switch(parser->current.type) { switch(parser->current.type) {
//these tokens can start a line //these tokens can start a line
@@ -244,7 +248,7 @@ static Opcode string(Parser* parser, Node** nodeHandle, bool canBeAssigned) {
} }
static Opcode grouping(Parser* parser, Node** nodeHandle, bool canBeAssigned) { static Opcode grouping(Parser* parser, Node** nodeHandle, bool canBeAssigned) {
//handle three diffent types of groupings: (), {}, [] //handle groupings with ()
switch(parser->previous.type) { switch(parser->previous.type) {
case TOKEN_PAREN_LEFT: { case TOKEN_PAREN_LEFT: {
Node* tmpNode = NULL; Node* tmpNode = NULL;
@@ -685,11 +689,19 @@ static void blockStmt(Parser* parser, Node** nodeHandle) {
//use the next node in sequence //use the next node in sequence
(*nodeHandle)->block.nodes[(*nodeHandle)->block.count].type = NODE_ERROR; //BUGFIX: so freeing won't break the damn thing (*nodeHandle)->block.nodes[(*nodeHandle)->block.count].type = NODE_ERROR; //BUGFIX: so freeing won't break the damn thing
Node* ptr = &((*nodeHandle)->block.nodes[(*nodeHandle)->block.count++]); Node* ptr = &((*nodeHandle)->block.nodes[(*nodeHandle)->block.count]);
//process the grammar rule for this line //process the grammar rule for this line
declaration(parser, &ptr); declaration(parser, &ptr);
//BUGFIX: if ptr has been re-assigned, copy the new value into the block's child
if (&((*nodeHandle)->block.nodes[(*nodeHandle)->block.count]) != ptr) {
((*nodeHandle)->block.nodes[(*nodeHandle)->block.count]) = *ptr;
FREE(Node, ptr);
}
(*nodeHandle)->block.count++;
// Ground floor: perfumery / Stationery and leather goods / Wigs and haberdashery / Kitchenware and food / Going up! // Ground floor: perfumery / Stationery and leather goods / Wigs and haberdashery / Kitchenware and food / Going up!
if (parser->panic) { if (parser->panic) {
return; return;
@@ -720,7 +732,13 @@ static void assertStmt(Parser* parser, Node** nodeHandle) {
//precedence functions //precedence functions
static void expressionStmt(Parser* parser, Node** nodeHandle) { static void expressionStmt(Parser* parser, Node** nodeHandle) {
expression(parser, nodeHandle); //BUGFIX: statements assume the node exists, expressions assume it doens't
Node* ptr = NULL;
expression(parser, &ptr);
**nodeHandle = *ptr;
FREE(Node, ptr); //BUGFIX: this thread of execution is nuts
consume(parser, TOKEN_SEMICOLON, "Expected ';' at the end of expression statement"); consume(parser, TOKEN_SEMICOLON, "Expected ';' at the end of expression statement");
} }