HUGE Makefile updates!

This commit is contained in:
Scarlett
2025-03-28 20:38:21 -04:00
parent 982a8a0454
commit ad4f55c2bf
9 changed files with 242 additions and 405 deletions

View File

@ -6,8 +6,9 @@ CFLAGS :=
YACC := bison
TESTS-S1 := $(wildcard tests/sprint1/test/*.alpha)
TESTS-S3 := $(wildcard tests/sprint3/test/*.alpha)
TESTS-S2 := $(wildcard tests/sprint2/test/*.alpha)
TESTS-S3 := $(wildcard tests/sprint3/test/*.alpha)
TESTS-S4 := $(wildcard tests/sprint4/test/*.alpha)
compiler: clean runner
@ -33,22 +34,38 @@ runner: tmp/lex.yy.c tmp/runner.o tmp/symbol_table.o
debug: CFLAGS += -DDEBUG=1
debug: clean compiler
test: test-s1 test-s2 test-s3
test:
chmod +x ./check.sh
chmod +x ./test.sh
$(foreach test, $(TESTS-S1), (./$(EXE) -tok $(test) || true);)
./test.sh sp2
./test.sh sp3
./test.sh sp4
./check.sh
test-s1:
chmod +x ./check.sh
for test in $(TESTS-S1); do ./$(EXE) -tok $$test || echo "Test $$test failed but continuing"; done
./check.sh
chmod +x ./test.sh
$(foreach test, $(TESTS-S1), (./$(EXE) -tok $(test) || true);)
./check.sh sp1
test-s2:
chmod +x ./check.sh
for test in $(TESTS-S2); do ./$(EXE) -st $$test || echo "Test $$test failed but continuing"; done
./check.sh
chmod +x ./test.sh
./test.sh sp2
./check.sh sp2
test-s3:
chmod +x ./check.sh
for test in $(TESTS-S3); do ./$(EXE) -st $$test || echo "Test $$test failed but continuing"; done
./check.sh
chmod +x ./test.sh
./test.sh sp3
./check.sh sp3
test-s4:
chmod +x ./check.sh
chmod +x ./test.sh
./test.sh sp4
./check.sh sp4
clean:
rm -f *.o

View File

@ -5,34 +5,61 @@
# The Translators - Spring 2025 #
TOK_DIR="out"
NOCOLOR='\033[0m'
RED='\033[0;31m'
GREEN='\033[0;32m'
WHITE='\033[0m'
PURPLE='\033[0;35m'
ORANGE='\033[0;33m'
BLUE='\033[0;34m'
PURPLE='\033[0;35m'
CYAN='\033[0;36m'
LIGHTGRAY='\033[0;37m'
DARKGRAY='\033[1;30m'
LIGHTRED='\033[1;31m'
LIGHTGREEN='\033[1;32m'
YELLOW='\033[1;33m'
LIGHTBLUE='\033[1;34m'
LIGHTPURPLE='\033[1;35m'
LIGHTCYAN='\033[1;36m'
WHITE='\033[1;37m'
compare_files() {
local file="$1"
local filename=$(basename -- "$file")
filename="${filename%.*}"
local num=${filename:2:1}
local exp="./tests/sprint$num/expected/$filename.expected"
if [[ -f "$exp" ]]; then
diff -q "$file" "$exp" > /dev/null
if [[ $? -eq 0 ]]; then
echo -e "${GREEN}[✔] ${PURPLE}$filename ${WHITE}passed.${NOCOLOR}"
else
echo -e "\n${RED}[✘] ${PURPLE}$file ${WHITE}failed with an unexpected value...${NOCOLOR}"
diff --color=always "$file" "$exp"
echo -e ""
fi
else
echo -e "${ORANGE}[-] ${PURPLE}$filename ${WHITE}does not have an expected value.${NOCOLOR}"
fi
}
if [[ ! -d "$TOK_DIR" ]]; then
echo "Directory $TOK_DIR does not exist."
echo -e "${RED}[ERROR] ${YELLOW}Directory $TOK_DIR does not exist.${NOCOLOR}"
exit 1
fi
echo -e "\n"
for file in "$TOK_DIR"/*; do
filename=$(basename -- "$file")
filename="${filename%.*}"
num=${filename:2:1}
exp="./tests/sprint$num/expected/$filename.expected"
if [[ -f "$exp" ]]; then
diff -q "$file" "$exp" > /dev/null
if [[ $? -eq 0 ]]; then
echo -e "${GREEN}[✔] ${PURPLE}$filename ${WHITE}passed."
else
echo -e "\n${RED}[✘] ${PURPLE}$file ${WHITE}failed with an unexpected value..."
diff --color=always "$file" "$exp"
echo -e ""
fi
else
echo -e "${ORANGE}[-] ${PURPLE}$filename ${WHITE}does not have an expected value."
fi
done
if [[ $# -eq 0 ]]; then
for file in "$TOK_DIR"/*; do
compare_files "$file"
done
elif [[ $# -eq 1 ]]; then
prefix="$1"
for file in "$TOK_DIR"/"$prefix"*; do
if [[ -f "$file" ]]; then
compare_files "$file"
fi
done
else
echo -e "${LIGHTBLUE}Usage: $0 [sp#]${NOCOLOR}"
exit 1
fi

View File

@ -1,373 +0,0 @@
/* Syntax Analyzer with Bison (3.8.2) */
/* The Translators - Spring 2025 */
%{
#include <stdio.h>
#include "../src/symbol_table.c"
#include <math.h>
extern int yylex(void);
void yyerror(const char *err);
extern char* yytext;
extern int yyleng;
extern int yychar;
extern SymbolTable * cur;
//char* cur_value;
//char* cur_type;
int token_tracker;
extern int line_number;
extern int column_number;
extern FILE * yyin;
extern TableNode* funprime;
extern TableNode* arrayprim;
extern TableNode* recprime;
extern TableNode* funtypeprime;
extern TableNode* integ;
extern TableNode* addr;
extern TableNode* chara;
extern TableNode* stri;
extern TableNode* boo;
TableNode * tn;
%}
//%define api.location.type {location_t}
%locations
%union {
int integ;
char * words;
}
%type <words> assignable
%type <words> expression
%type <words> constant
%type <words> id_or_types
%type <words> types
%token <words> ID 101
%token <words> T_INTEGER 201
%token <words> T_ADDRESS 202
%token <words> T_BOOLEAN 203
%token <words> T_CHARACTER 204
%token <words> T_STRING 205
%token <integ> C_INTEGER 301
%token <words> C_NULL 302
%token <words> C_CHARACTER 303
%token <words> C_STRING 304
%token <words> C_TRUE 305
%token <words> C_FALSE 306
%token WHILE 401
%token IF 402
%token THEN 403
%token ELSE 404
%token TYPE 405
%token FUNCTION 406
%token RETURN 407
%token EXTERNAL 408
%token AS 409
%token L_PAREN 501
%token R_PAREN 502
%token L_BRACKET 503
%token R_BRACKET 504
%token L_BRACE 505
%token R_BRACE 506
%token SEMI_COLON 507
%token COLON 508
%token COMMA 509
%token ARROW 510
%token MUL 603
%token DIV 604
%token REM 605
%token ADD 601
%token LESS_THAN 606
%token EQUAL_TO 607
%token AND 610
%token OR 611
%token ASSIGN 608
%token SUB_OR_NEG 602
%token NOT 609
%token DOT 612
%token RESERVE 613
%token RELEASE 614
%token COMMENT 700
//precedence order
%left ASSIGN
%left OR
%left AND
%left EQUAL_TO
%left LESS_THAN
%left ADD SUB_OR_NEG
%left MUL DIV REM
%precedence NOT
%precedence UMINUS
%precedence DOT
%precedence RESERVE RELEASE
%%
program:
prototype_or_definition_list
;
prototype_or_definition_list:
prototype prototype_or_definition_list
| definition prototype_or_definition_list
| prototype
| definition
;
prototype:
L_PAREN EXTERNAL R_PAREN FUNCTION ID COLON ID;
definition:
TYPE ID COLON {tn = CreateEntry(getAncestor(cur), recprime, $2, CreateRecordInfo(0, cur = CreateScope(cur, 0, 0)));
if (table_lookup(getAncestor(cur), $2) == NULL) {
printf("rec not found \n");
}
}dblock { setRecSize(table_lookup(getParent(cur), $2), getRecSize(cur));
cur = getParent(cur);}
| TYPE ID COLON C_INTEGER ARROW id_or_types { CreateEntry(cur, arrayprim, $2, CreateArrayInfo($4, look_up(cur, $6)));}
| function_declaration
| TYPE ID COLON id_or_types ARROW id_or_types {
CreateEntry(cur,funtypeprime,$2,CreateFunctionTypeInfo(table_lookup(cur,$4),table_lookup(cur,$6)));
}
| ID {
TableNode *node = table_lookup(getAncestor(cur), $<words>1);
if (node == NULL || getAdInfoType(node) != TYPE_FUNCTION_DECLARATION) {
printf("function not declared at line %d, column %d\n", @1.first_line, @1.first_column);
} else {
setStartLine(node, @1.first_line);
setAsKeyword(node, false);
}
cur = CreateScope(cur, 0, 0);
} L_PAREN ID {
CreateEntry(cur, getParameter(table_lookup(getAncestor(cur), getType(table_lookup(getAncestor(cur), $<words>1)))), $<words>4, NULL);
}R_PAREN ASSIGN sblock
| ID {
TableNode *node = table_lookup(getAncestor(cur), $<words>1);
if (node == NULL) {
printf("null check\n");
}
if (node == NULL || getAdInfoType(node) != TYPE_FUNCTION_DECLARATION) {
printf("function not declared at line %d, column %d\n", @1.first_line, @1.first_column);
} else {
setStartLine(node, @1.first_line);
setAsKeyword(node, false);
}
cur = CreateScope(cur, 0, 0);
}AS L_PAREN {
TableNode *parameter = getParameter(table_lookup(getAncestor(cur), getType(table_lookup(getAncestor(cur), $<words>1))));
if (parameter == NULL || getAdInfoType(parameter) != TYPE_RECORD) {
printf("function defined with as, but parameter is not a record at line %d, column %d\n", @1.first_line, @1.first_column);
} else {
for (TableNode* entry = getFirstEntry(getRecList(parameter)); entry!= NULL; entry = getNextEntry(entry)){
CreateEntry(cur, entry, NULL, NULL);
}
}
} idlist R_PAREN ASSIGN sblock
;
function_declaration:
FUNCTION ID COLON ID {CreateEntry(cur, look_up(cur, $4), $2, CreateFunctionDeclarationInfo(-1, false));}
| EXTERNAL FUNCTION ID COLON ID {CreateEntry(cur, look_up(cur, $5), $3, NULL);}
;
idlist:
ID {
TableNode *entry = getFirstEntry(cur);
while (getName(entry) != NULL) {
entry = getNextEntry(entry);
}
if (getNextEntry(entry) == NULL) {
printf("too many parameters at line %d column %d\n", @1.first_line, @1.first_column);
}
addName(entry, $<words>1);
} COMMA idlist
| ID {
TableNode *entry = getFirstEntry(cur);
while (getName(entry) != NULL) {
entry = getNextEntry(entry);
}
if (getNextEntry(entry) != NULL) {
printf("too many parameters at line %d column %d\n", @1.first_line, @1.first_column);
}
addName(entry, $<words>1);
}
;
sblock:
L_BRACE {if (getLine(cur) != 0 && getColumn(cur))cur = CreateScope(cur,@1.first_line,@1.first_column);} statement_list {cur = getParent(cur);} R_BRACE
| L_BRACE {if (getLine(cur) != 0 && getColumn(cur))cur = CreateScope(cur,@1.first_line,@1.first_column);} dblock
{printf("seen sblock with dblock\n");} statement_list {cur = getParent(cur);} R_BRACE
;
dblock:
L_BRACKET declaration_list R_BRACKET;
declaration_list:
declaration SEMI_COLON declaration_list
| declaration
;
declaration:
id_or_types COLON ID {printf("ID/TYPE: %s, ID: %s\n", $<words>1, $<words>3) ; CreateEntry(cur,table_lookup(getAncestor(cur),$<words>1),$<words>3,NULL); }
;
id_or_types:
ID {printf("string of id in id_or_type is %s\n",$<words>1); $$ = getType(look_up(cur,$1));}
| types {printf("string of type in id_or_type is %s\n",$<words>1);} {$$ = $<words>1;}
;
statement_list:
compound_statement statement_list
| compound_statement
| simple_statement SEMI_COLON statement_list
| simple_statement SEMI_COLON
;
compound_statement:
WHILE L_PAREN expression R_PAREN sblock
| IF L_PAREN expression R_PAREN THEN sblock ELSE sblock
| sblock //{printf("seen a compound statement rule\n");}
;
simple_statement:
assignable ASSIGN expression {if(strcmp($1, $3) == 0){
} else {
printf("Mismatch at line %d and column%d\n", @2.first_line, @2.first_column);
}}
| RETURN expression
;
assignable:
ID {$$ = getType(look_up(cur,$1));}
| assignable ablock {$$ = getName(getReturn(look_up(cur, $1)));}
| assignable rec_op ID {if(undefined != table_lookup(getRecList(look_up(cur, $1)), $3)){
{$$ = getName(table_lookup(getRecList(look_up(cur, $1)), $3));}};}
;
rec_op :
DOT
expression:
constant {printf("constant expression\n");} {$$ = $<words>1;}
| SUB_OR_NEG expression %prec UMINUS {printf("negative expression\n");if(strcmp($2,"integer") != 0)
{printf("cant negate something not an integer at line %d and column %d\n",@2.first_line,@2.first_column);
$$=strdup("undefined");}else{$$=$2;}}
| NOT expression {printf("not expression\n"); if(strcmp($2,"Boolean")==0){$$=$2;}else{$$=strdup("undefined");
printf("mismatch at line %d and column %d. Invalid type being negated is %s\n",
@1.first_line,@1.first_column,$2);}}
| expression ADD expression
{printf("add expression\n");if(strcmp($1,$3)==0 && strcmp($1,"integer")==0){$$=strdup("integer");}
else{printf("mismatch at line %d and column %d. Invalid types %s and %s.\n",
@2.first_line,@2.first_column,$1,$3);
$$=strdup("undefined");}}
| expression SUB_OR_NEG expression
{printf("sub or neg expression\n");if(strcmp($1,$3)==0 &&strcmp($1,"integer")==0){$$=strdup("integer");}
else{printf("mismatch at line %d and column %d. Invalid types %s and %s.\n",
@2.first_line,@2.first_column,$1,$3);
$$=strdup("undefined");}}
| expression MUL expression
{printf("multiply expression\n");
if(strcmp($1,$3)==0 &&strcmp($1,"integer")==0){$$=strdup("integer");}
else{printf("mismatch at line %d and column %d. Invalid types %s and %s.\n",
@2.first_line,@2.first_column,$1,$3);
$$=strdup("undefined");}}
| expression DIV expression
{printf("divide expression\n");if(strcmp($1,$3)==0 && strcmp($1,"integer")==0){$$=strdup("integer");}
else{printf("mismatch at line %d and column %d. Invalid types %s and %s.\n",
@2.first_line,@2.first_column,$1,$3);
$$=strdup("undefined");}}
| expression REM expression
{printf("remainder expression\n");if(strcmp($1,$3)==0 && strcmp($1,"integer")==0){$$=strdup("integer");}
else{printf("mismatch at line %d and column %d. Invalid types %s and %s.\n",
@2.first_line,@2.first_column,$1,$3);
$$=strdup("undefined");}}
| expression AND expression
{printf("AND expression\n");if(strcmp($1,$3)==0 && strcmp($1,"Boolean")==0){$$=strdup("Boolean");}
else{printf("mismatch at line %d and column %d. Invalid types %s and %s.\n",
@2.first_line,@2.first_column,$1,$3);
$$=strdup("undefined");}}
| expression OR expression
{printf("OR\n");if(strcmp($1,$3)==0 &&
strcmp($1,"Boolean")==0){$$=strdup("Boolean");}
else{printf("mismatch at line %d and column %d. Invalid types %s and %s.\n",
@2.first_line,@2.first_column,$1,$3);
$$=strdup("undefined");}}
| expression LESS_THAN expression
{printf("less than expression\n");if(strcmp($1,$3)==0 &&
strcmp($1,"integer")==0){$$=strdup("Boolean");}
else{printf("mismatch at line %d and column %d. Invalid types %s and %s.\n",
@2.first_line,@2.first_column,$1,$3);
$$=strdup("undefined");}}
| expression EQUAL_TO expression {printf("equals check expression\n");
if(strcmp($1,$3)==0){$$=strdup("Boolean");}
else if((strcmp($1,"array")==0||strcmp($1,"record")==0||
strcmp($1,"function type primitive")==0) && (strcmp($3,"address")==0)){$$=strdup("Boolean");}
else{printf("mismatch at line %d and column %d. Invalid types %s and %s\n",
@2.first_line,@2.first_column,$1,$3);$$=strdup("undefined");}}
| assignable {printf("assignable expression. current type is %s\n",$1);$$=$1;}
| L_PAREN expression R_PAREN {printf("paren expression. current type is %s\n",$2);$$=$2;}
| memOp assignable {$$ = strdup("address");}
;
ablock:
L_PAREN argument_list {$<integ>$ = $<integ>2;} R_PAREN
;
argument_list:
expression COMMA argument_list {$<integ>$ = $<integ>3 + 1;}
| expression {$<integ>$ = 1;}
;
memOp:
RESERVE {printf("reserve expression\n");}
| RELEASE {printf("release expression\n");}
;
constant:
C_STRING {$$ = $<words>1;}
| C_INTEGER {$$ = "integer";}
| C_NULL {$$ = $<words>1;}
| C_CHARACTER {$$ = $<words>1;}
| C_TRUE {$$ = $<words>1;}
| C_FALSE {$$ = $<words>1;}
;
types:
// Commented out T_String below
// T_STRING {printf("string of T_STRING in types is %s\n",$<words>1);} {$$ = $<words>1;}
T_INTEGER {printf("string of T_INTEGER in types is %s\n",$<words>1);} {$$ = $<words>1;}
| T_ADDRESS {printf("string of T_ADDRESS in types is %s\n",$<words>1);} {$$ = $<words>1;}
| T_CHARACTER {printf("string of T_CHARACTER in types is %s\n",$<words>1);} {$$ = $<words>1;}
| T_BOOLEAN {printf("string of T_BOOLEAN in types is %s\n",$<words>1);} {$$ = $<words>1;}
;
%%
void yyerror(const char *err) {
fprintf(stderr, "ERROR: %s at token %s at line number %d,column number %d\n", err,yytext,yylloc.first_line,yylloc.first_column);
}

View File

@ -921,4 +921,4 @@ TableNode *getNextEntry(TableNode *tn) { return tn->next; }
printf("The type of the first entry is %s\n",First_Entry->theType);
return 0;
}
*/
*/

166
test.sh Executable file
View File

@ -0,0 +1,166 @@
#!/bin/bash
# Test Tool #
# The Translators - Spring 2025 #
RED='\033[0;31m'
GREEN='\033[0;32m'
ORANGE='\033[0;33m'
BLUE='\033[0;34m'
PURPLE='\033[0;35m'
CYAN='\033[0;36m'
LIGHTGRAY='\033[0;37m'
DARKGRAY='\033[1;30m'
LIGHTRED='\033[1;31m'
LIGHTGREEN='\033[1;32m'
YELLOW='\033[1;33m'
LIGHTBLUE='\033[1;34m'
LIGHTPURPLE='\033[1;35m'
LIGHTCYAN='\033[1;36m'
WHITE='\033[1;37m'
if [ ! -f "./alpha" ]; then
echo -e "${RED}[ERROR] ${YELLOW}File ./alpha not found!${WHITE}"
exit 1
fi
if [ ! -d "./out" ]; then
mkdir -p out
fi
SWITCH=${YELLOW}
count=0
switchfunc() {
if [ $count -eq 0 ]; then
count=1
SWITCH=${YELLOW}
else
count=0
SWITCH='\033[0;35m'
fi
}
if [ $# -eq 0 ]; then
echo -e "${YELLOW}[INFO] ${WHITE}Running all tests...${WHITE}"
echo -e "${YELLOW}[INFO] ${ORANGE}Testing SPRINT-1 ---------------------------\n${WHITE}"
for file in ./tests/sprint1/test/*; do
if [ -f "$file" ]; then
filename=$(basename -- "$file")
echo -e "- ${SWITCH}Running test: ${LIGHTBLUE}$filename ${SWITCH}-----${WHITE}"
./alpha -st "$file"
echo -e "${SWITCH}----- End of test: ${LIGHTBLUE}$filename ${SWITCH}-${WHITE}\n"
switchfunc
fi
done
echo -e ""
echo -e "${YELLOW}[INFO] ${ORANGE}Testing SPRINT-2 ---------------------------\n${WHITE}"
for file in ./tests/sprint2/test/*; do
if [ -f "$file" ]; then
filename=$(basename -- "$file")
echo -e "- ${SWITCH}Running test: ${LIGHTBLUE}$filename ${SWITCH}-----${WHITE}"
./alpha -st "$file"
echo -e "${SWITCH}----- End of test: ${LIGHTBLUE}$filename ${SWITCH}-${WHITE}\n"
switchfunc
fi
done
echo -e ""
echo -e "${YELLOW}[INFO] ${ORANGE}Testing SPRINT-3 ---------------------------\n${WHITE}"
for file in ./tests/sprint3/test/*; do
if [ -f "$file" ]; then
filename=$(basename -- "$file")
echo -e "- ${SWITCH}Running test: ${LIGHTBLUE}$filename ${SWITCH}-----${WHITE}"
./alpha -st "$file"
echo -e "${SWITCH}----- End of test: ${LIGHTBLUE}$filename ${SWITCH}-${WHITE}\n"
switchfunc
fi
done
echo -e ""
echo -e "${YELLOW}[INFO] ${ORANGE}Testing SPRINT-4 ---------------------------\n${WHITE}"
for file in ./tests/sprint4/test/*; do
if [ -f "$file" ]; then
filename=$(basename -- "$file")
echo -e "- ${SWITCH}Running test: ${LIGHTBLUE}$filename ${SWITCH}-----${WHITE}"
./alpha -st "$file"
echo -e "${SWITCH}----- End of test: ${LIGHTBLUE}$filename ${SWITCH}-${WHITE}\n${WHITE}"
switchfunc
fi
done
else
if [ "$1" == "--help" ]; then
echo -e "${YELLOW}[INFO] ${WHITE}Usage: ./test.sh [prefix]"
echo -e "${YELLOW}[INFO] ${WHITE}--help: show this help message"
echo -e "${YELLOW}[INFO] ${WHITE}--file <file>: run test with file"
exit 0
fi
if [[ "$1" == "--file" ]]; then
shift
if [ $# -eq 0 ]; then
echo -e "${RED}[ERROR] ${YELLOW}No file specified!${WHITE}"
exit 1
fi
if [ -f "$1" ]; then
filename=$(basename -- "$1")
echo -e "- ${SWITCH}Running test: ${LIGHTBLUE}$filename ${SWITCH}-----${WHITE}"
./alpha -st "$1"
echo -e "${SWITCH}----- End of test: ${LIGHTBLUE}$filename ${SWITCH}-${WHITE}"
exit 1
else
echo -e "${RED}[ERROR] ${YELLOW}File $1 not found!${WHITE}"
exit 1
fi
fi
if [[ "$1" == "sp1" ]]; then
echo -e "${YELLOW}[INFO] ${WHITE}Running tests with prefix $1..."
for file in ./tests/sprint1/test/*; do
if [[ "$file" == *"$1"* ]]; then
filename=$(basename -- "$file")
echo -e "- ${SWITCH}Running test: ${LIGHTBLUE}$filename ${SWITCH}-----${WHITE}"
./alpha -st "$file"
echo -e "${SWITCH}----- End of test: ${LIGHTBLUE}$filename ${SWITCH}-${WHITE}\n"
switchfunc
fi
done
elif [[ "$1" == "sp2" ]]; then
echo -e "${YELLOW}[INFO] ${WHITE}Running tests with prefix $1..."
for file in ./tests/sprint2/test/*; do
if [[ "$file" == *"$1"* ]]; then
filename=$(basename -- "$file")
echo -e "- ${SWITCH}Running test: ${LIGHTBLUE}$filename ${SWITCH}-----${WHITE}"
./alpha -st "$file"
echo -e "${SWITCH}----- End of test: ${LIGHTBLUE}$filename ${SWITCH}-${WHITE}\n"
switchfunc
fi
done
elif [[ "$1" == "sp3" ]]; then
echo -e "${YELLOW}[INFO] ${WHITE}Running tests with prefix $1..."
for file in ./tests/sprint3/test/*; do
if [[ "$file" == *"$1"* ]]; then
filename=$(basename -- "$file")
echo -e "- ${SWITCH}Running test: ${LIGHTBLUE}$filename ${SWITCH}-----${WHITE}"
./alpha -st "$file"
echo -e "${SWITCH}----- End of test: ${LIGHTBLUE}$filename ${SWITCH}-${WHITE}\n"
switchfunc
fi
done
elif [[ "$1" == "sp4" ]]; then
echo -e "${YELLOW}[INFO] ${WHITE}Running tests with prefix $1..."
for file in ./tests/sprint4/test/*; do
if [[ "$file" == *"$1"* ]]; then
filename=$(basename -- "$file")
echo -e "- ${SWITCH}Running test: ${LIGHTBLUE}$filename ${SWITCH}-----${WHITE}"
./alpha -st "$file"
echo -e "${SWITCH}----- End of test: ${LIGHTBLUE}$filename ${SWITCH}-${WHITE}\n"
switchfunc
fi
done
else
echo -e "${RED}[ERROR] ${YELLOW}Invalid prefix $1!${WHITE}"
exit 1
fi
fi