Added constant folding for strings, tweaked some error messages

This commit is contained in:
2023-02-04 09:50:29 +00:00
parent 57c16d2ede
commit 8d278077b1
6 changed files with 34 additions and 17 deletions

View File

@@ -59,7 +59,9 @@ void repl() {
while(node != NULL) {
//pack up and restart
if (node->type == TOY_AST_NODE_ERROR) {
printf(TOY_CC_ERROR "error node detected\n" TOY_CC_RESET);
if (Toy_commandLine.verbose) {
printf(TOY_CC_ERROR "Error node detected\n" TOY_CC_RESET);
}
error = true;
Toy_freeASTNode(node);
break;
@@ -103,7 +105,7 @@ int main(int argc, const char* argv[]) {
Toy_freeLiteral(driveLiteral);
Toy_freeLiteral(pathLiteral);
//Toy_commandLine specific actions
//command line specific actions
if (Toy_commandLine.error) {
Toy_usageCommandLine(argc, argv);
return 0;
@@ -121,7 +123,7 @@ int main(int argc, const char* argv[]) {
//version
if (Toy_commandLine.verbose) {
printf(TOY_CC_NOTICE "Toy Programming Language Version %d.%d.%d\n" TOY_CC_RESET, TOY_VERSION_MAJOR, TOY_VERSION_MINOR, TOY_VERSION_PATCH);
printf(TOY_CC_NOTICE "Toy Programming Language Version %d.%d.%d, built '%s'\n" TOY_CC_RESET, TOY_VERSION_MAJOR, TOY_VERSION_MINOR, TOY_VERSION_PATCH, TOY_VERSION_BUILD);
}
//run source file

View File

@@ -22,7 +22,7 @@
#endif
#ifndef TOY_EXPORT
//for processing the Toy_commandLine line arguments
//for processing the command line arguments
typedef struct {
bool error;
bool help;

View File

@@ -279,7 +279,7 @@ static Toy_Opcode Toy_writeCompilerWithJumps(Toy_Compiler* compiler, Toy_ASTNode
break;
case TOY_AST_NODE_UNARY: {
//pass to the child node, then embed the unary Toy_commandLine (print, negate, etc.)
//pass to the child node, then embed the unary command (print, negate, etc.)
Toy_Opcode override = Toy_writeCompilerWithJumps(compiler, node->unary.child, breakAddressesPtr, continueAddressesPtr, jumpOffsets, rootNode);
if (override != TOY_OP_EOF) {//compensate for indexing & dot notation being screwy
@@ -292,7 +292,7 @@ static Toy_Opcode Toy_writeCompilerWithJumps(Toy_Compiler* compiler, Toy_ASTNode
//all infixes come here
case TOY_AST_NODE_BINARY: {
//pass to the child nodes, then embed the binary Toy_commandLine (math, etc.)
//pass to the child nodes, then embed the binary command (math, etc.)
Toy_Opcode override = Toy_writeCompilerWithJumps(compiler, node->binary.left, breakAddressesPtr, continueAddressesPtr, jumpOffsets, rootNode);
//special case for when indexing and assigning

View File

@@ -397,7 +397,7 @@ static bool execArithmetic(Toy_Interpreter* interpreter, Toy_Opcode opcode) {
//check for overflow
int totalLength = TOY_AS_STRING(lhs)->length + TOY_AS_STRING(rhs)->length;
if (totalLength > TOY_MAX_STRING_LENGTH) {
interpreter->errorOutput("Can't concatenate these strings (result is too long)\n");
interpreter->errorOutput("Can't concatenate these strings, result is too long (error found in interpreter)\n");
return false;
}
@@ -445,7 +445,7 @@ static bool execArithmetic(Toy_Interpreter* interpreter, Toy_Opcode opcode) {
case TOY_OP_DIVISION:
case TOY_OP_VAR_DIVISION_ASSIGN:
if (TOY_AS_INTEGER(rhs) == 0) {
interpreter->errorOutput("Can't divide by zero (error found in interpreter)");
interpreter->errorOutput("Can't divide by zero (error found in interpreter)\n");
return false;
}
Toy_pushLiteralArray(&interpreter->stack, TOY_TO_INTEGER_LITERAL( TOY_AS_INTEGER(lhs) / TOY_AS_INTEGER(rhs) ));
@@ -454,14 +454,14 @@ static bool execArithmetic(Toy_Interpreter* interpreter, Toy_Opcode opcode) {
case TOY_OP_MODULO:
case TOY_OP_VAR_MODULO_ASSIGN:
if (TOY_AS_INTEGER(rhs) == 0) {
interpreter->errorOutput("Can't modulo by zero (error found in interpreter)");
interpreter->errorOutput("Can't modulo by zero (error found in interpreter)\n");
return false;
}
Toy_pushLiteralArray(&interpreter->stack, TOY_TO_INTEGER_LITERAL( TOY_AS_INTEGER(lhs) % TOY_AS_INTEGER(rhs) ));
return true;
default:
interpreter->errorOutput("[internal] bad opcode argument passed to execArithmetic()");
interpreter->errorOutput("[internal] bad opcode argument passed to execArithmetic()\n");
return false;
}
}
@@ -492,14 +492,14 @@ static bool execArithmetic(Toy_Interpreter* interpreter, Toy_Opcode opcode) {
case TOY_OP_DIVISION:
case TOY_OP_VAR_DIVISION_ASSIGN:
if (TOY_AS_FLOAT(rhs) == 0) {
interpreter->errorOutput("Can't divide by zero (error found in interpreter)");
interpreter->errorOutput("Can't divide by zero (error found in interpreter)\n");
return false;
}
Toy_pushLiteralArray(&interpreter->stack, TOY_TO_FLOAT_LITERAL( TOY_AS_FLOAT(lhs) / TOY_AS_FLOAT(rhs) ));
return true;
default:
interpreter->errorOutput("[internal] bad opcode argument passed to execArithmetic()");
interpreter->errorOutput("[internal] bad opcode argument passed to execArithmetic()\n");
return false;
}
}
@@ -1558,7 +1558,7 @@ static bool execIndex(Toy_Interpreter* interpreter, bool assignIntermediate) {
Toy_pushLiteralArray(&arguments, first);
Toy_pushLiteralArray(&arguments, second);
Toy_pushLiteralArray(&arguments, third);
Toy_pushLiteralArray(&arguments, TOY_TO_NULL_LITERAL); //it expects an assignment Toy_commandLine
Toy_pushLiteralArray(&arguments, TOY_TO_NULL_LITERAL); //it expects an assignment command
Toy_pushLiteralArray(&arguments, TOY_TO_NULL_LITERAL); //it expects an assignment "opcode"
//leave the idn and compound on the stack
@@ -1688,7 +1688,7 @@ static bool execIndexAssign(Toy_Interpreter* interpreter) {
Toy_pushLiteralArray(&arguments, first);
Toy_pushLiteralArray(&arguments, second);
Toy_pushLiteralArray(&arguments, third);
Toy_pushLiteralArray(&arguments, assign); //it expects an assignment Toy_commandLine
Toy_pushLiteralArray(&arguments, assign); //it expects an assignment command
Toy_pushLiteralArray(&arguments, op); //it expects an assignment "opcode"
//call the _index function

View File

@@ -59,7 +59,7 @@ static void consume(Toy_Parser* parser, Toy_TokenType tokenType, const char* msg
static void synchronize(Toy_Parser* parser) {
#ifndef TOY_EXPORT
if (Toy_commandLine.verbose) {
fprintf(stderr, TOY_CC_ERROR "synchronizing\n" TOY_CC_RESET);
fprintf(stderr, TOY_CC_ERROR "Synchronizing input\n" TOY_CC_RESET);
}
#endif
@@ -982,6 +982,21 @@ static bool calcStaticBinaryArithmetic(Toy_Parser* parser, Toy_ASTNode** nodeHan
Toy_Literal rhs = (*nodeHandle)->binary.right->atomic.literal;
Toy_Literal result = TOY_TO_NULL_LITERAL;
//special case for string concatenation ONLY
if (TOY_IS_STRING(lhs) && TOY_IS_STRING(rhs)) {
//check for overflow
int totalLength = TOY_AS_STRING(lhs)->length + TOY_AS_STRING(rhs)->length;
if (totalLength > TOY_MAX_STRING_LENGTH) {
error(parser, parser->previous, "Can't concatenate these strings, result is too long (error found in constant folding)\n");
return false;
}
//concat the strings
char buffer[TOY_MAX_STRING_LENGTH];
snprintf(buffer, TOY_MAX_STRING_LENGTH, "%s%s", Toy_toCString(TOY_AS_STRING(lhs)), Toy_toCString(TOY_AS_STRING(rhs)));
result = TOY_TO_STRING_LITERAL(Toy_createRefStringLength(buffer, totalLength));
}
//type coersion
if (TOY_IS_FLOAT(lhs) && TOY_IS_INTEGER(rhs)) {
rhs = TOY_TO_FLOAT_LITERAL(TOY_AS_INTEGER(rhs));

View File

@@ -18,7 +18,7 @@
//test division prevention
{
var x = 0;
assert x ? 0 : 1 / x == 0, "Division by zero prevention failed";
assert (x ? 0 : 1 / x) == 0, "Division by zero prevention failed";
}
//test ambiguous syntax
@@ -29,7 +29,7 @@
var ddddd = 4;
var eeeeee = 5;
assert aa ? bbb ? cccc : ddddd : eeeeee, "Ambiguous syntax failed";
assert (aa ? bbb ? cccc : ddddd : eeeeee) == 3, "Ambiguous syntax failed";
}