Added console colors, tweaked help menu

This commit is contained in:
2022-08-09 13:51:03 +01:00
parent 6d5549fc8e
commit 9603baeb0a
6 changed files with 117 additions and 65 deletions

View File

@@ -27,3 +27,10 @@ print "Back to the outer scope.";
assert true, "This won't be seen"; assert true, "This won't be seen";
assert false, "This is an error"; assert false, "This is an error";
//var arr : [int] = [1, 2, 3, 42];
//var dict : [string, int] = ["hello": 1, "world":2];

View File

@@ -20,78 +20,90 @@ void initCommand(int argc, const char* argv[]) {
command.optimize = 1; command.optimize = 1;
for (int i = 1; i < argc; i++) { //start at 1 to skip the program name for (int i = 1; i < argc; i++) { //start at 1 to skip the program name
command.error = true; //error state by default, set to false by successful flags
if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) { if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) {
command.help = true; command.help = true;
command.error = false;
continue; continue;
} }
if (!strcmp(argv[i], "-v") || !strcmp(argv[i], "--version")) { if (!strcmp(argv[i], "-v") || !strcmp(argv[i], "--version")) {
command.version = true; command.version = true;
command.error = false;
continue; continue;
} }
//binary file check at the end if (!strcmp(argv[i], "-d") || !strcmp(argv[i], "--debug")) {
command.verbose = true;
command.error = false;
continue;
}
if (!strncmp(argv[i], "-O", 2)) {
sscanf(argv[i], "-O%d", &command.optimize);
command.error = false;
continue;
}
if ((!strcmp(argv[i], "-f") || !strcmp(argv[i], "--sourcefile")) && i + 1 < argc) { if ((!strcmp(argv[i], "-f") || !strcmp(argv[i], "--sourcefile")) && i + 1 < argc) {
command.sourcefile = (char*)argv[i + 1]; command.sourcefile = (char*)argv[i + 1];
i++; i++;
continue; command.error = false;
}
if ((!strcmp(argv[i], "-c") || !strcmp(argv[i], "--compile")) && i + 1 < argc) {
command.compilefile = (char*)argv[i + 1];
i++;
continue;
}
if ((!strcmp(argv[i], "-o") || !strcmp(argv[i], "--output")) && i + 1 < argc) {
command.outfile = (char*)argv[i + 1];
i++;
continue; continue;
} }
if ((!strcmp(argv[i], "-i") || !strcmp(argv[i], "--input")) && i + 1 < argc) { if ((!strcmp(argv[i], "-i") || !strcmp(argv[i], "--input")) && i + 1 < argc) {
command.source = (char*)argv[i + 1]; command.source = (char*)argv[i + 1];
i++; i++;
command.error = false;
continue; continue;
} }
if (!strcmp(argv[i], "-d") || !strcmp(argv[i], "--debug")) { if ((!strcmp(argv[i], "-c") || !strcmp(argv[i], "--compile")) && i + 1 < argc) {
command.verbose = true; command.compilefile = (char*)argv[i + 1];
i++;
command.error = false;
continue; continue;
} }
if (!strncmp(argv[i], "-O", 2)) { if ((!strcmp(argv[i], "-o") || !strcmp(argv[i], "--output")) && i + 1 < argc) {
sscanf(argv[i], "-O%d", &command.optimize); command.outfile = (char*)argv[i + 1];
i++;
command.error = false;
continue; continue;
} }
//option without a flag = binary input //option without a flag + ending in .tb = binary input
if (i < argc) { if (i < argc) {
command.binaryfile = (char*)argv[i]; if (strncmp(&(argv[i][strlen(argv[i]) - 3]), ".tb", 3) == 0) {
continue; command.binaryfile = (char*)argv[i];
command.error = false;
continue;
}
} }
command.error = true; //don't keep reading in an error state
return;
} }
} }
void usageCommand(int argc, const char* argv[]) { void usageCommand(int argc, const char* argv[]) {
printf("Usage: %s [<filename> | -h | -v | [-OX][-d][-f file | -i source | -c file [-o outfile]]]\n\n", argv[0]); printf("Usage: %s [<file.tb> | -h | -v | [-d][-OX][-f file | -i source | -c file [-o outfile]]]\n\n", argv[0]);
} }
void helpCommand(int argc, const char* argv[]) { void helpCommand(int argc, const char* argv[]) {
usageCommand(argc, argv); usageCommand(argc, argv);
printf("<filename>\t\t\tBinary input file in tb format, must be version %d.%d.%d.\n\n", TOY_VERSION_MAJOR, TOY_VERSION_MINOR, TOY_VERSION_PATCH); printf("<file.tb>\t\t\tBinary input file in tb format, must be version %d.%d.%d.\n\n", TOY_VERSION_MAJOR, TOY_VERSION_MINOR, TOY_VERSION_PATCH);
printf("-h\t| --help\t\tShow this help then exit.\n\n"); printf("-h\t| --help\t\tShow this help then exit.\n\n");
printf("-v\t| --version\t\tShow version and copyright information then exit.\n\n"); printf("-v\t| --version\t\tShow version and copyright information then exit.\n\n");
printf("-f\t| --file filename\tParse, compile and execute the source file.\n\n");
printf("-c\t| --compile filename\tParse and compile the specified source file into an output file.\n\n");
printf("-o\t| --output filename\tName of the file compiled with --compile (default: out.tb).\n\n");
printf("-i\t| --input source\tParse, compile and execute this given string of source code.\n\n");
printf("-d\t| --debug\t\tBe verbose when operating.\n\n"); printf("-d\t| --debug\t\tBe verbose when operating.\n\n");
printf("-OX\t\t\t\tUse level X optimization (default 1)\n\n"); printf("-OX\t\t\t\tUse level X optimization (default 1)\n\n");
printf("-f\t| --file filename\tParse, compile and execute the source file.\n\n");
printf("-i\t| --input source\tParse, compile and execute this given string of source code.\n\n");
printf("-c\t| --compile filename\tParse and compile the specified source file into an output file.\n\n");
printf("-o\t| --output filename\tName of the file compiled with --compile (default: out.tb).\n\n");
} }
void copyrightCommand(int argc, const char* argv[]) { void copyrightCommand(int argc, const char* argv[]) {

30
source/console_colors.h Normal file
View File

@@ -0,0 +1,30 @@
#pragma once
//NOTE: you need both font AND background for these to work
//fonts color
#define FONT_BLACK "\033[30;"
#define FONT_RED "\033[31;"
#define FONT_GREEN "\033[32;"
#define FONT_YELLOW "\033[33;"
#define FONT_BLUE "\033[34;"
#define FONT_PURPLE "\033[35;"
#define FONT_DGREEN "\033[6;"
#define FONT_WHITE "\033[7;"
#define FONT_CYAN "\x1b[36m"
//background color
#define BACK_BLACK "40m"
#define BACK_RED "41m"
#define BACK_GREEN "42m"
#define BACK_YELLOW "43m"
#define BACK_BLUE "44m"
#define BACK_PURPLE "45m"
#define BACK_DGREEN "46m"
#define BACK_WHITE "47m"
//useful
#define NOTICE FONT_GREEN BACK_BLACK
#define WARN FONT_YELLOW BACK_BLACK
#define ERROR FONT_RED BACK_BLACK
#define RESET "\033[0m"

View File

@@ -1,4 +1,5 @@
#include "interpreter.h" #include "interpreter.h"
#include "console_colors.h"
#include "common.h" #include "common.h"
#include "memory.h" #include "memory.h"
@@ -310,17 +311,15 @@ void runInterpreter(Interpreter* interpreter) {
const unsigned char minor = readByte(interpreter->bytecode, &interpreter->count); const unsigned char minor = readByte(interpreter->bytecode, &interpreter->count);
const unsigned char patch = readByte(interpreter->bytecode, &interpreter->count); const unsigned char patch = readByte(interpreter->bytecode, &interpreter->count);
if (command.verbose) { if (major != TOY_VERSION_MAJOR || minor != TOY_VERSION_MINOR || patch != TOY_VERSION_PATCH) {
if (major != TOY_VERSION_MAJOR || minor != TOY_VERSION_MINOR || patch != TOY_VERSION_PATCH) { printf(ERROR "Error: interpreter/bytecode version mismatch\n" RESET);
printf("Warning: interpreter/bytecode version mismatch\n");
}
} }
const char* build = readString(interpreter->bytecode, &interpreter->count); const char* build = readString(interpreter->bytecode, &interpreter->count);
if (command.verbose) { if (command.verbose) {
if (strncmp(build, TOY_VERSION_BUILD, strlen(TOY_VERSION_BUILD))) { if (strncmp(build, TOY_VERSION_BUILD, strlen(TOY_VERSION_BUILD))) {
printf("Warning: interpreter/bytecode build mismatch\n"); printf(WARN "Warning: interpreter/bytecode build mismatch\n" RESET);
} }
} }
@@ -330,7 +329,7 @@ void runInterpreter(Interpreter* interpreter) {
const short literalCount = readShort(interpreter->bytecode, &interpreter->count); const short literalCount = readShort(interpreter->bytecode, &interpreter->count);
if (command.verbose) { if (command.verbose) {
printf("Reading %d literals\n", literalCount); printf(NOTICE "Reading %d literals\n" RESET, literalCount);
} }
for (int i = 0; i < literalCount; i++) { for (int i = 0; i < literalCount; i++) {
@@ -393,7 +392,7 @@ void runInterpreter(Interpreter* interpreter) {
//code section //code section
if (command.verbose) { if (command.verbose) {
printf("executing bytecode\n"); printf(NOTICE "executing bytecode\n" RESET);
} }
execInterpreter(interpreter); execInterpreter(interpreter);

View File

@@ -1,8 +1,10 @@
#include "lexer.h" #include "lexer.h"
#include "console_colors.h"
#include "keyword_types.h" #include "keyword_types.h"
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <ctype.h>
//static generic utility functions //static generic utility functions
static void cleanLexer(Lexer* lexer) { static void cleanLexer(Lexer* lexer) {
@@ -122,6 +124,7 @@ static Token makeToken(Lexer* lexer, TokenType type) {
token.length = 1; token.length = 1;
token.line = lexer->line; token.line = lexer->line;
//BUG #10: this shows TOKEN_EOF twice due to the overarching structure of the program - can't be fixed
if (command.verbose) { if (command.verbose) {
printf("tok:"); printf("tok:");
printToken(&token); printToken(&token);
@@ -297,9 +300,15 @@ Token scanLexer(Lexer* lexer) {
} }
} }
static void trim(char** s, int* l) { //all this to remove a newline?
*l = strlen(*s);
while( isspace(( (*((unsigned char**)(s)))[(*l) - 1] )) ) (*l)--;
while(**s && isspace( **(unsigned char**)(s)) ) { (*s)++; (*l)--; }
}
void printToken(Token* token) { void printToken(Token* token) {
if (token->type == TOKEN_ERROR) { if (token->type == TOKEN_ERROR) {
printf("Error\t%d\t%.*s\n", token->line, token->length, token->lexeme); printf(ERROR "Error\t%d\t%.*s\n" RESET, token->line, token->length, token->lexeme);
return; return;
} }
@@ -313,7 +322,10 @@ void printToken(Token* token) {
if (keyword != NULL) { if (keyword != NULL) {
printf("%s", keyword); printf("%s", keyword);
} else { } else {
printf("-"); char* str = token->lexeme;
int length = 0;
trim(&str, &length);
printf("%.*s", length, token->lexeme);
} }
} }

View File

@@ -1,4 +1,5 @@
#include "debug.h" #include "debug.h"
#include "console_colors.h"
#include "lexer.h" #include "lexer.h"
#include "parser.h" #include "parser.h"
@@ -189,17 +190,6 @@ void repl() {
freeInterpreter(&interpreter); freeInterpreter(&interpreter);
} }
void debug() {
LiteralDictionary dictionary;
initLiteralDictionary(&dictionary);
setLiteralDictionary(&dictionary, TO_IDENTIFIER_LITERAL("variable", MASK_INTEGER), TO_INTEGER_LITERAL(2));
printLiteral( getLiteralDictionary(&dictionary, TO_IDENTIFIER_LITERAL("variable", MASK_INTEGER)) );
freeLiteralDictionary(&dictionary);
}
//entry point //entry point
int main(int argc, const char* argv[]) { int main(int argc, const char* argv[]) {
initCommand(argc, argv); initCommand(argc, argv);
@@ -220,15 +210,9 @@ int main(int argc, const char* argv[]) {
return 0; return 0;
} }
//print this until the interpreter meets the specification //TODO: remove this when the interpreter meets the specification
if (command.verbose) { if (command.verbose) {
printf("Warning! This interpreter is a work in progress, it does not yet meet the %d.%d.%d specification.\n", TOY_VERSION_MAJOR, TOY_VERSION_MINOR, TOY_VERSION_PATCH); printf(WARN "Warning! This interpreter is a work in progress, it does not yet meet the %d.%d.%d specification.\n" RESET, TOY_VERSION_MAJOR, TOY_VERSION_MINOR, TOY_VERSION_PATCH);
}
//run binary
if (command.binaryfile) {
runBinaryFile(command.binaryfile);
return 0;
} }
//run source file //run source file
@@ -237,22 +221,30 @@ int main(int argc, const char* argv[]) {
return 0; return 0;
} }
//compile source file
if (command.compilefile) {
size_t size = 0;
char* source = readFile(command.compilefile, &size);
unsigned char* tb = compileString(source, &size);
writeFile(command.outfile, tb, size);
return 0;
}
//run from stdin //run from stdin
if (command.source) { if (command.source) {
runSource(command.source); runSource(command.source);
return 0; return 0;
} }
// debug(); //compile source file
if (command.compilefile && command.outfile) {
size_t size = 0;
char* source = readFile(command.compilefile, &size);
unsigned char* tb = compileString(source, &size);
if (!tb) {
return 1;
}
writeFile(command.outfile, tb, size);
return 0;
}
//run binary
if (command.binaryfile) {
runBinaryFile(command.binaryfile);
return 0;
}
repl(); repl();
return 0; return 0;