mirror of
https://github.com/krgamestudios/Toy.git
synced 2026-04-15 14:54:07 +10:00
Added console colors, tweaked help menu
This commit is contained in:
@@ -27,3 +27,10 @@ print "Back to the outer scope.";
|
||||
assert true, "This won't be seen";
|
||||
assert false, "This is an error";
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//var arr : [int] = [1, 2, 3, 42];
|
||||
//var dict : [string, int] = ["hello": 1, "world":2];
|
||||
|
||||
@@ -20,78 +20,90 @@ void initCommand(int argc, const char* argv[]) {
|
||||
command.optimize = 1;
|
||||
|
||||
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")) {
|
||||
command.help = true;
|
||||
command.error = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!strcmp(argv[i], "-v") || !strcmp(argv[i], "--version")) {
|
||||
command.version = true;
|
||||
command.error = false;
|
||||
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) {
|
||||
command.sourcefile = (char*)argv[i + 1];
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
|
||||
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++;
|
||||
command.error = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((!strcmp(argv[i], "-i") || !strcmp(argv[i], "--input")) && i + 1 < argc) {
|
||||
command.source = (char*)argv[i + 1];
|
||||
i++;
|
||||
command.error = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!strcmp(argv[i], "-d") || !strcmp(argv[i], "--debug")) {
|
||||
command.verbose = true;
|
||||
if ((!strcmp(argv[i], "-c") || !strcmp(argv[i], "--compile")) && i + 1 < argc) {
|
||||
command.compilefile = (char*)argv[i + 1];
|
||||
i++;
|
||||
command.error = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!strncmp(argv[i], "-O", 2)) {
|
||||
sscanf(argv[i], "-O%d", &command.optimize);
|
||||
if ((!strcmp(argv[i], "-o") || !strcmp(argv[i], "--output")) && i + 1 < argc) {
|
||||
command.outfile = (char*)argv[i + 1];
|
||||
i++;
|
||||
command.error = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
//option without a flag = binary input
|
||||
//option without a flag + ending in .tb = binary input
|
||||
if (i < argc) {
|
||||
if (strncmp(&(argv[i][strlen(argv[i]) - 3]), ".tb", 3) == 0) {
|
||||
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[]) {
|
||||
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[]) {
|
||||
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("-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("-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[]) {
|
||||
|
||||
30
source/console_colors.h
Normal file
30
source/console_colors.h
Normal 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"
|
||||
@@ -1,4 +1,5 @@
|
||||
#include "interpreter.h"
|
||||
#include "console_colors.h"
|
||||
|
||||
#include "common.h"
|
||||
#include "memory.h"
|
||||
@@ -310,17 +311,15 @@ void runInterpreter(Interpreter* interpreter) {
|
||||
const unsigned char minor = 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) {
|
||||
printf("Warning: interpreter/bytecode version mismatch\n");
|
||||
}
|
||||
printf(ERROR "Error: interpreter/bytecode version mismatch\n" RESET);
|
||||
}
|
||||
|
||||
const char* build = readString(interpreter->bytecode, &interpreter->count);
|
||||
|
||||
if (command.verbose) {
|
||||
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);
|
||||
|
||||
if (command.verbose) {
|
||||
printf("Reading %d literals\n", literalCount);
|
||||
printf(NOTICE "Reading %d literals\n" RESET, literalCount);
|
||||
}
|
||||
|
||||
for (int i = 0; i < literalCount; i++) {
|
||||
@@ -393,7 +392,7 @@ void runInterpreter(Interpreter* interpreter) {
|
||||
|
||||
//code section
|
||||
if (command.verbose) {
|
||||
printf("executing bytecode\n");
|
||||
printf(NOTICE "executing bytecode\n" RESET);
|
||||
}
|
||||
|
||||
execInterpreter(interpreter);
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
#include "lexer.h"
|
||||
#include "console_colors.h"
|
||||
#include "keyword_types.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
//static generic utility functions
|
||||
static void cleanLexer(Lexer* lexer) {
|
||||
@@ -122,6 +124,7 @@ static Token makeToken(Lexer* lexer, TokenType type) {
|
||||
token.length = 1;
|
||||
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) {
|
||||
printf("tok:");
|
||||
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) {
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -313,7 +322,10 @@ void printToken(Token* token) {
|
||||
if (keyword != NULL) {
|
||||
printf("%s", keyword);
|
||||
} else {
|
||||
printf("-");
|
||||
char* str = token->lexeme;
|
||||
int length = 0;
|
||||
trim(&str, &length);
|
||||
printf("%.*s", length, token->lexeme);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include "debug.h"
|
||||
#include "console_colors.h"
|
||||
|
||||
#include "lexer.h"
|
||||
#include "parser.h"
|
||||
@@ -189,17 +190,6 @@ void repl() {
|
||||
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
|
||||
int main(int argc, const char* argv[]) {
|
||||
initCommand(argc, argv);
|
||||
@@ -220,15 +210,9 @@ int main(int argc, const char* argv[]) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
//print this until the interpreter meets the specification
|
||||
//TODO: remove this when the interpreter meets the specification
|
||||
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);
|
||||
}
|
||||
|
||||
//run binary
|
||||
if (command.binaryfile) {
|
||||
runBinaryFile(command.binaryfile);
|
||||
return 0;
|
||||
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 source file
|
||||
@@ -237,22 +221,30 @@ int main(int argc, const char* argv[]) {
|
||||
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
|
||||
if (command.source) {
|
||||
runSource(command.source);
|
||||
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();
|
||||
|
||||
return 0;
|
||||
|
||||
Reference in New Issue
Block a user