mirror of
https://github.com/krgamestudios/Toy.git
synced 2026-04-15 23:04:08 +10:00
Got scope-based variable shadowing working
This commit is contained in:
@@ -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];
|
||||||
@@ -70,3 +86,5 @@ 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
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
var name : [string const, int] = ["foo" : 42];
|
|
||||||
var something = 0;
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -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");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user