Merge pull request #40 from UB-CSE443/Sprint3-Table_Restructure_Part2-FE-t#NoTask
Sprint3 table restructure part2 fe t#no task
This commit is contained in:
35
Makefile
35
Makefile
@ -7,6 +7,8 @@ YACC := bison
|
||||
|
||||
TESTS-S1 := $(wildcard tests/sprint1/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
|
||||
|
||||
@ -32,17 +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:
|
||||
chmod +x ./check.sh
|
||||
chmod +x ./test.sh
|
||||
$(foreach test, $(TESTS-S1), (./$(EXE) -tok $(test) -debug || true);)
|
||||
./test.sh sp2
|
||||
./test.sh sp3
|
||||
./test.sh sp4
|
||||
./check.sh
|
||||
|
||||
test-s1:
|
||||
chmod +x ./check.sh
|
||||
$(foreach test, $(TESTS-S1), ./$(EXE) -tok $(test);)
|
||||
./check.sh
|
||||
chmod +x ./test.sh
|
||||
$(foreach test, $(TESTS-S1), (./$(EXE) -tok $(test) -debug || true);)
|
||||
./check.sh sp1
|
||||
|
||||
test-s2:
|
||||
chmod +x ./check.sh
|
||||
$(foreach test, $(TESTS-S2), ./$(EXE) -st $(test);)
|
||||
./check.sh
|
||||
chmod +x ./test.sh
|
||||
./test.sh sp2
|
||||
./check.sh sp2
|
||||
|
||||
test-s3:
|
||||
chmod +x ./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
|
||||
@ -55,4 +78,4 @@ clean:
|
||||
rm -f *.st
|
||||
rm -rf out
|
||||
rm -rf tmp
|
||||
rm -f parser
|
||||
rm -f parser
|
||||
|
73
check.sh
73
check.sh
@ -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
|
736
src/grammar.y
736
src/grammar.y
@ -1,40 +1,37 @@
|
||||
|
||||
/* Syntax Analyzer with Bison (3.8.2) */
|
||||
/* The Translators - Spring 2025 */
|
||||
|
||||
// ----- THIS FILE MUST BE FORMATTED CORRECTLY FOR READABILITY ----- //
|
||||
|
||||
// ✏️ FORMATTING RULES:
|
||||
// 1️⃣ Use 4 spaces for indentation.
|
||||
// 2️⃣ Grammar rules (terminals and nonterminals) should always be on their own line.
|
||||
// 3️⃣ Grammar rules and C-blocks should always begin 8 spaces in.
|
||||
// 4️⃣ Rule end-markers (;, |) should always be 4 spaces in.
|
||||
// 5️⃣ C-blocks should always be clearly defined and follow clang formatting rules.
|
||||
// 6️⃣ 1-line if/for/while statements must be wrapped in curly braces.
|
||||
// 7️⃣ Comments should always be above rules
|
||||
// 8️⃣ DO NOT USE TABS. EVER.
|
||||
|
||||
// Please ask Scarlett if you are unsure of how to format something. Thanks! 😀
|
||||
|
||||
%{
|
||||
#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;
|
||||
#include "../src/symbol_table.c"
|
||||
|
||||
void yyerror(const char *err);
|
||||
int token_tracker;
|
||||
TableNode * tn;
|
||||
%}
|
||||
//%define api.location.type {location_t}
|
||||
|
||||
%locations
|
||||
|
||||
%union {
|
||||
int integ;
|
||||
char * words;
|
||||
int integ;
|
||||
char * words;
|
||||
}
|
||||
|
||||
|
||||
%type <integ> idlist
|
||||
%type <words> assignable
|
||||
%type <words> expression
|
||||
%type <words> constant
|
||||
@ -46,7 +43,7 @@
|
||||
%token <words> T_BOOLEAN 203
|
||||
%token <words> T_CHARACTER 204
|
||||
%token <words> T_STRING 205
|
||||
%token <words> C_INTEGER 301
|
||||
%token <integ> C_INTEGER 301
|
||||
%token <words> C_NULL 302
|
||||
%token <words> C_CHARACTER 303
|
||||
%token <words> C_STRING 304
|
||||
@ -100,164 +97,633 @@
|
||||
%precedence DOT
|
||||
%precedence RESERVE RELEASE
|
||||
|
||||
|
||||
|
||||
%%
|
||||
|
||||
program:
|
||||
prototype_or_definition_list
|
||||
;
|
||||
prototype_or_definition_list
|
||||
;
|
||||
|
||||
|
||||
|
||||
prototype_or_definition_list:
|
||||
prototype prototype_or_definition_list
|
||||
| definition prototype_or_definition_list
|
||||
| prototype
|
||||
| definition
|
||||
;
|
||||
prototype prototype_or_definition_list
|
||||
| definition prototype_or_definition_list
|
||||
| prototype
|
||||
| definition
|
||||
;
|
||||
|
||||
|
||||
|
||||
prototype:
|
||||
L_PAREN EXTERNAL R_PAREN FUNCTION ID COLON ID;
|
||||
L_PAREN EXTERNAL R_PAREN FUNCTION ID COLON ID;
|
||||
|
||||
|
||||
|
||||
definition:
|
||||
TYPE ID COLON dblock
|
||||
| TYPE ID COLON constant ARROW ID
|
||||
| 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)));
|
||||
TYPE ID COLON
|
||||
{
|
||||
printdebug("Currently see a record definition for %s", $<words>2);
|
||||
tn = CreateEntry(getAncestor(cur), recprime, $2, CreateRecordInfo(0, cur = CreateScope(cur, 0, 0)));
|
||||
if (table_lookup(getAncestor(cur), $2) == undefined) {
|
||||
printdebug("rec not found");
|
||||
}
|
||||
}
|
||||
| ID parameter ASSIGN sblock
|
||||
;
|
||||
dblock
|
||||
{
|
||||
setRecSize(table_lookup(getParent(cur), $2), getRecSize(cur));
|
||||
cur = getParent(cur);
|
||||
}
|
||||
|
||||
| TYPE ID COLON C_INTEGER ARROW id_or_types
|
||||
{
|
||||
printdebug("Currently see a array definition of name %s,storing type %s, of dimensions %d", $2, $6, $4);
|
||||
CreateEntry(cur, arrayprim, $2, CreateArrayInfo($4, look_up(cur, $6)));
|
||||
printdebug("%sID: %s, dimensions: %d, typeOfArray: %s", COLOR_GREEN, $2, $4, $6);
|
||||
}
|
||||
|
||||
| function_declaration
|
||||
|
||||
| TYPE ID COLON id_or_types ARROW id_or_types
|
||||
{
|
||||
printdebug("Currently see a function type definition of name %s,parameter type %s, of return type %s", $2, $4, $6);
|
||||
CreateEntry(cur,funtypeprime,$2,CreateFunctionTypeInfo(table_lookup(cur,$4),table_lookup(cur,$6)));
|
||||
}
|
||||
|
||||
| ID
|
||||
{
|
||||
TableNode *node = table_lookup(getAncestor(cur), $<words>1);
|
||||
if (node == undefined) {
|
||||
printdebug("function not declared at line %d, column %d", @1.first_line, @1.first_column);
|
||||
} else if(getAdInfoType(node) != TYPE_FUNCTION_DECLARATION) {
|
||||
printdebug("function not declared at line %d, column %d", @1.first_line, @1.first_column);
|
||||
} else {
|
||||
setStartLine(node, @1.first_line);
|
||||
setAsKeyword(node, false);
|
||||
}
|
||||
cur = CreateScope(cur, 0, 0);
|
||||
}
|
||||
L_PAREN ID
|
||||
{
|
||||
printdebug("Currently see a function definition taking only one parameter (no as) of name %s and argument name %s", $1,$4);
|
||||
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 == undefined) {
|
||||
printdebug("null check");
|
||||
}
|
||||
if (node == undefined) {
|
||||
printdebug("function not declared at line %d, column %d", @1.first_line, @1.first_column);
|
||||
} else if (getAdInfoType(node) != TYPE_FUNCTION_DECLARATION) {
|
||||
printdebug("function not declared at line %d, column %d", @1.first_line, @1.first_column);
|
||||
} else {
|
||||
setStartLine(node, @1.first_line);
|
||||
setAsKeyword(node, true);
|
||||
}
|
||||
cur = CreateScope(cur, 0, 0);
|
||||
}
|
||||
AS L_PAREN
|
||||
{
|
||||
TableNode *parameter = getParameter(table_lookup(getAncestor(cur), getType(table_lookup(getAncestor(cur), $<words>1))));
|
||||
printdebug("%s", getType(parameter));
|
||||
if (parameter == undefined) {
|
||||
printdebug("function defined with as, but parameter is undefined at line %d, column %d", @1.first_line, @1.first_column);
|
||||
} else if(getAdInfoType(parameter) != TYPE_RECORD) {
|
||||
printdebug("record: %s., primitive: %s.", getType(parameter), getName(recprime));
|
||||
printdebug("function defined with as, but parameter is type %s at line %d, column %d", getType(parameter),@1.first_line, @1.first_column);
|
||||
} else {
|
||||
for (TableNode* entry = getFirstEntry(getRecList(parameter)); entry!= NULL; entry = getNextEntry(entry)) {
|
||||
CreateEntry(cur, entry->theType, NULL, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
idlist
|
||||
{
|
||||
printdebug("Currently see a function definition taking one paramter (with as) of name %s and number of arguments %d", $1,$6);
|
||||
}
|
||||
R_PAREN ASSIGN sblock
|
||||
;
|
||||
|
||||
|
||||
|
||||
function_declaration:
|
||||
FUNCTION ID COLON ID
|
||||
| EXTERNAL FUNCTION ID COLON ID
|
||||
;
|
||||
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);
|
||||
}
|
||||
;
|
||||
|
||||
|
||||
parameter:
|
||||
L_PAREN ID R_PAREN
|
||||
| AS L_PAREN idlist R_PAREN
|
||||
;
|
||||
|
||||
idlist:
|
||||
ID COMMA idlist
|
||||
| ID
|
||||
;
|
||||
ID
|
||||
{
|
||||
TableNode *entry = getFirstEntry(cur);
|
||||
while (strcmp(getName(entry),"undefined") != 0) {
|
||||
entry = getNextEntry(entry);
|
||||
}
|
||||
if (getNextEntry(entry) == NULL) {
|
||||
printdebug("too many parameters at line %d column %d", @1.first_line, @1.first_column);
|
||||
}
|
||||
addName(entry, $<words>1);
|
||||
}
|
||||
COMMA idlist
|
||||
{
|
||||
$$ = $<integ>4 + 1;
|
||||
}
|
||||
|
||||
| ID
|
||||
{
|
||||
TableNode *entry = getFirstEntry(cur);
|
||||
while (strcmp(getName(entry),"undefined") != 0) {
|
||||
entry = getNextEntry(entry);
|
||||
}
|
||||
if (getNextEntry(entry) != NULL) {
|
||||
printdebug("too many parameters at line %d column %d", @1.first_line, @1.first_column);
|
||||
}
|
||||
addName(entry, $<words>1);
|
||||
$$ = 1;
|
||||
}
|
||||
;
|
||||
|
||||
|
||||
sblock:
|
||||
L_BRACE {cur = CreateScope(cur,@1.first_line,@1.first_column);} statement_list {cur = getParent(cur);} R_BRACE
|
||||
| L_BRACE {cur = CreateScope(cur,@1.first_line,@1.first_column);} dblock {printf("seen sblock with dblock\n");} statement_list {cur = getParent(cur);} R_BRACE
|
||||
;
|
||||
L_BRACE
|
||||
{
|
||||
if (getLine(cur) != 0) {
|
||||
cur = CreateScope(cur,@1.first_line,@1.first_column);
|
||||
} else {
|
||||
setLineNumber(cur, @1.first_line);
|
||||
setColumnNumber(cur,@1.first_line);
|
||||
}
|
||||
}
|
||||
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
|
||||
{
|
||||
printdebug("seen sblock with dblock");
|
||||
}
|
||||
statement_list
|
||||
{
|
||||
cur = getParent(cur);
|
||||
}
|
||||
R_BRACE
|
||||
;
|
||||
|
||||
|
||||
|
||||
dblock:
|
||||
L_BRACKET declaration_list R_BRACKET;
|
||||
L_BRACKET
|
||||
{
|
||||
if(getLine(cur)==0) {
|
||||
setLineNumber(cur, @1.first_line);
|
||||
setColumnNumber(cur,@1.first_line);
|
||||
} else {
|
||||
cur = CreateScope(cur,@1.first_line,@1.first_column);
|
||||
}
|
||||
}
|
||||
declaration_list R_BRACKET;
|
||||
|
||||
|
||||
|
||||
declaration_list:
|
||||
declaration SEMI_COLON declaration_list
|
||||
| declaration
|
||||
;
|
||||
declaration SEMI_COLON declaration_list
|
||||
| declaration
|
||||
;
|
||||
|
||||
|
||||
|
||||
declaration:
|
||||
id_or_types COLON ID {CreateEntry(cur,table_lookup(getAncestor(cur),$<words>1),$<words>3,NULL); }
|
||||
;
|
||||
id_or_types COLON ID
|
||||
{
|
||||
printdebug("ID/TYPE: %s, ID: %s", $<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);} {$$ = $<words>1;}
|
||||
| types {printf("string of type in id_or_type is %s\n",$<words>1);} {$$ = $<words>1;}
|
||||
;
|
||||
ID
|
||||
{
|
||||
printdebug("string of id is %s in ID pattern of id_or_type rule.", $1); $$ = $1;
|
||||
}
|
||||
|
||||
| types
|
||||
{
|
||||
printdebug("string of type is %s in types pattern of id_or_type rule.",$1);
|
||||
$$ = $1;
|
||||
}
|
||||
;
|
||||
|
||||
|
||||
|
||||
statement_list:
|
||||
compound_statement statement_list
|
||||
| compound_statement
|
||||
| simple_statement SEMI_COLON statement_list
|
||||
| simple_statement SEMI_COLON
|
||||
;
|
||||
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");}
|
||||
;
|
||||
WHILE L_PAREN expression R_PAREN sblock
|
||||
| IF L_PAREN expression R_PAREN THEN sblock ELSE sblock
|
||||
| sblock
|
||||
;
|
||||
|
||||
|
||||
|
||||
simple_statement:
|
||||
assignable ASSIGN expression
|
||||
| RETURN expression
|
||||
;
|
||||
assignable ASSIGN expression
|
||||
{
|
||||
if(strcmp($1, $3) == 0) {
|
||||
printdebug("Passed standard type check; assignable = expression");
|
||||
} else if((strcmp(getType(look_up(cur, $1)), "array") == 0) && (strcmp($3, "address") == 0)) {
|
||||
printdebug("%s[☺] Passed array type check; %s = %s", COLOR_GREEN, $1, $3);
|
||||
} else if((strcmp(getType(look_up(cur, $1)), "record") == 0) && (strcmp($3, "address") == 0)) {
|
||||
printdebug("%s[☺] Passed address type check; %s = %s", COLOR_GREEN, $1, $3);
|
||||
} else if((strcmp(getType(look_up(cur, $1)), "function type primitive") == 0) && (strcmp($3, "address") == 0)) {
|
||||
printdebug("%s[☺] Passed function type primitive type check; %s = %s", COLOR_GREEN, $1, $3);
|
||||
// } else if () {
|
||||
|
||||
assignable:
|
||||
ID
|
||||
| assignable ablock
|
||||
| assignable rec_op ID
|
||||
;
|
||||
// } else if(strcmp(getType(table_lookup(cur, $1)), getType(table_lookup(cur, $3))) == 0) {
|
||||
// printdebug("%s[] Passed double lookup type check; %s = %s", COLOR_GREEN, $1, $3);
|
||||
} else {
|
||||
printdebug("%s[TYPE ERROR] %sMismatch at %sline %d and column %d%s", COLOR_ORANGE, COLOR_WHITE, COLOR_YELLOW, @2.first_line, @2.first_column, COLOR_WHITE);
|
||||
printdebug(" - Invalid types %s$1: %s and $3: %s%s", COLOR_YELLOW, $1, $3, COLOR_WHITE);
|
||||
printdebug(" - %sgetType for address: %s", COLOR_YELLOW, getType(look_up(cur, $1)));
|
||||
}
|
||||
}
|
||||
|
||||
rec_op :
|
||||
DOT
|
||||
| RETURN expression
|
||||
;
|
||||
|
||||
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\n",@1.first_line,@1.first_column);}}
|
||||
| expression ADD expression {printf("add expression\n");}
|
||||
| expression SUB_OR_NEG expression {printf("subtract expression\n");}
|
||||
| expression MUL expression {printf("multiply expression\n");}
|
||||
| expression DIV expression {printf("division expression\n");}
|
||||
| expression REM expression {printf("remainder expression\n");}
|
||||
|
||||
| expression AND expression {printf("and expression\n");}
|
||||
|
||||
| expression OR expression {printf("or expression\n");}
|
||||
rec_op:
|
||||
DOT
|
||||
|
||||
| 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\n",@2.first_line,@2.first_column);
|
||||
$$=strdup("Boolean");$$=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\n",@2.first_line,@2.first_column);$$=strdup("undefined");}}
|
||||
| assignable {printf("assignable expression\n");$$=$1;}
|
||||
| L_PAREN expression R_PAREN {printf("paren expression\n");$$=$2;}
|
||||
| memOp assignable {$$ = strdup("address");}
|
||||
;
|
||||
|
||||
|
||||
ablock:
|
||||
L_PAREN argument_list R_PAREN
|
||||
;
|
||||
L_PAREN argument_list R_PAREN
|
||||
{
|
||||
$<integ>$ = $<integ>2;
|
||||
printdebug("ablock is %d", $<integ>$);
|
||||
}
|
||||
;
|
||||
|
||||
|
||||
|
||||
argument_list:
|
||||
expression COMMA argument_list
|
||||
| expression
|
||||
;
|
||||
expression COMMA argument_list
|
||||
{
|
||||
CreateEntry(cur, look_up(cur, $1), "", NULL);
|
||||
$<integ>$ = $<integ>3 + 1;
|
||||
printdebug("[ARGUMENT_LIST] argument list is %d", $<integ>$);
|
||||
}
|
||||
|
||||
| expression
|
||||
{
|
||||
CreateEntry(cur, look_up(cur, $1), "", NULL);
|
||||
$<integ>$ = 1; printdebug("[ARGUMENT_LIST] argument list is %d", $<integ>$);
|
||||
}
|
||||
;
|
||||
|
||||
|
||||
|
||||
// will ALWAYS be a TYPE
|
||||
expression:
|
||||
constant
|
||||
{
|
||||
printdebug("constant expression");
|
||||
$$ = $<words>1;
|
||||
}
|
||||
|
||||
| SUB_OR_NEG expression %prec UMINUS
|
||||
{
|
||||
printdebug("negative expression");
|
||||
if(strcmp($2,"integer") != 0) {
|
||||
printdebug("cant negate something not an integer at line %d and column %d",@2.first_line,@2.first_column);
|
||||
$$=strdup("undefined");
|
||||
} else {
|
||||
$$=$2;
|
||||
}
|
||||
}
|
||||
|
||||
| NOT expression
|
||||
{
|
||||
printdebug("not expression");
|
||||
if(strcmp($2,"Boolean")==0) {
|
||||
$$=$2;
|
||||
} else {
|
||||
$$=strdup("undefined");
|
||||
printdebug("mismatch at line %d and column %d. Invalid type being negated is %s", @1.first_line,@1.first_column,$2);
|
||||
}
|
||||
}
|
||||
|
||||
| expression ADD expression
|
||||
{
|
||||
printdebug("add expression");
|
||||
if(strcmp($1,$3)==0 && strcmp($1,"integer")==0) {
|
||||
$$=strdup("integer");
|
||||
} else {
|
||||
printdebug("mismatch at line %d and column %d. Invalid types %s and %s.", @2.first_line,@2.first_column,$1,$3);
|
||||
$$=strdup("undefined");
|
||||
}
|
||||
}
|
||||
|
||||
| expression SUB_OR_NEG expression
|
||||
{
|
||||
printdebug("sub or neg expression");
|
||||
if(strcmp($1,$3)==0 &&strcmp($1,"integer")==0) {
|
||||
$$=strdup("integer");
|
||||
} else {
|
||||
printdebug("mismatch at line %d and column %d. Invalid types %s and %s.", @2.first_line,@2.first_column,$1,$3);
|
||||
$$=strdup("undefined");
|
||||
}
|
||||
}
|
||||
|
||||
| expression MUL expression
|
||||
{
|
||||
printdebug("multiply expression");
|
||||
if(strcmp($1,$3)==0 &&strcmp($1,"integer")==0) {
|
||||
$$=strdup("integer");
|
||||
} else{
|
||||
printdebug("mismatch at line %d and column %d. Invalid types %s and %s.", @2.first_line,@2.first_column,$1,$3);
|
||||
$$=strdup("undefined");
|
||||
}
|
||||
}
|
||||
|
||||
| expression DIV expression
|
||||
{
|
||||
printdebug("divide expression");
|
||||
if(strcmp($1,$3)==0 && strcmp($1,"integer")==0) {
|
||||
$$=strdup("integer");
|
||||
} else {
|
||||
printdebug("mismatch at line %d and column %d. Invalid types %s and %s.", @2.first_line,@2.first_column,$1,$3);
|
||||
$$=strdup("undefined");
|
||||
}
|
||||
}
|
||||
|
||||
| expression REM expression
|
||||
{
|
||||
printdebug("remainder expression");
|
||||
if(strcmp($1,$3)==0 && strcmp($1,"integer")==0) {
|
||||
$$=strdup("integer");
|
||||
} else {
|
||||
printdebug("mismatch at line %d and column %d. Invalid types %s and %s.", @2.first_line,@2.first_column,$1,$3);
|
||||
$$=strdup("undefined");
|
||||
}
|
||||
}
|
||||
|
||||
| expression AND expression
|
||||
{
|
||||
printdebug("AND expression");
|
||||
if(strcmp($1,$3)==0 && strcmp($1,"Boolean")==0) {
|
||||
$$=strdup("Boolean");
|
||||
} else{
|
||||
printdebug("mismatch at line %d and column %d. Invalid types %s and %s.", @2.first_line,@2.first_column,$1,$3);
|
||||
$$=strdup("undefined");
|
||||
}
|
||||
}
|
||||
|
||||
| expression OR expression
|
||||
{
|
||||
printdebug("OR");
|
||||
if(strcmp($1,$3)==0 && strcmp($1,"Boolean")==0) {
|
||||
$$=strdup("Boolean");
|
||||
} else {
|
||||
printdebug("mismatch at line %d and column %d. Invalid types %s and %s.", @2.first_line,@2.first_column,$1,$3);
|
||||
$$=strdup("undefined");
|
||||
}
|
||||
}
|
||||
|
||||
| expression LESS_THAN expression
|
||||
{
|
||||
printdebug("less than expression");
|
||||
if(strcmp($1,$3)==0 && strcmp($1,"integer")==0) {
|
||||
$$=strdup("Boolean");
|
||||
} else {
|
||||
printdebug("mismatch at line %d and column %d. Invalid types %s and %s.", @2.first_line,@2.first_column,$1,$3);
|
||||
$$=strdup("undefined");
|
||||
}
|
||||
}
|
||||
|
||||
| expression EQUAL_TO expression
|
||||
{
|
||||
printdebug("equals check expression");
|
||||
if(strcmp($1,$3)==0) {
|
||||
$$=strdup("Boolean");
|
||||
} else {
|
||||
printdebug("mismatch at line %d and column %d. Invalid types %s and %s", @2.first_line,@2.first_column,$1,$3);
|
||||
$$=strdup("undefined");
|
||||
}
|
||||
}
|
||||
|
||||
| assignable
|
||||
{
|
||||
printdebug("assignable expression. current type is %s",$1);
|
||||
$$=$1;
|
||||
}
|
||||
|
||||
| L_PAREN expression R_PAREN
|
||||
{
|
||||
printdebug("paren expression. current type is %s",$2);
|
||||
$$=$2;
|
||||
}
|
||||
|
||||
| memOp assignable
|
||||
{
|
||||
$$ = strdup("address");
|
||||
}
|
||||
|
||||
;
|
||||
|
||||
|
||||
|
||||
// prolly right, check back with me later
|
||||
// add array case
|
||||
// include type check for ablock in arrays - ablock is always the int of the elements in array/rec
|
||||
assignable:
|
||||
ID
|
||||
{
|
||||
$$ = getType(look_up(cur,$1));
|
||||
printdebug("[ASSIGNABLE - RULE 1] assignable = type: %s | ID = %s", $$, $1);
|
||||
}
|
||||
|
||||
| assignable
|
||||
{
|
||||
printdebug("%sBeginning rule 2 of assignable.", COLOR_CYAN);
|
||||
cur = CreateScope(cur, -1,-1);
|
||||
}
|
||||
ablock
|
||||
{
|
||||
int type = getAdInfoType(look_up(getParent(cur), $1));
|
||||
printdebug("%stype is %d", COLOR_PURPLE, type);
|
||||
|
||||
if (type == TYPE_FUNCTION_DECLARATION) {
|
||||
printdebug("%sEntering function call", COLOR_LIGHTGREEN);
|
||||
if (getAsKeyword(look_up(getParent(cur), $1))) {
|
||||
TableNode *param = getParameter(look_up(getParent(cur), $1));
|
||||
SymbolTable *recList = getRecList(param);
|
||||
TableNode *lastCheckedRef = getFirstEntry(recList);
|
||||
TableNode *lastCheckedAct = getFirstEntry(cur);
|
||||
while (getNextEntry(lastCheckedRef) != NULL) {
|
||||
lastCheckedRef = getNextEntry(lastCheckedRef);
|
||||
}
|
||||
//this isn't very efficient, but will hopefully work
|
||||
while (lastCheckedAct != NULL && lastCheckedRef != NULL) {
|
||||
if (strcmp(getName(lastCheckedAct), getName(lastCheckedRef)) != 0) {
|
||||
printdebug("expected %s expression in function call but got %s at line %d and column %d",getType(lastCheckedRef), getName(lastCheckedAct), @3.first_line, @3.first_column);
|
||||
}
|
||||
lastCheckedAct = getNextEntry(lastCheckedAct);
|
||||
TableNode *tn = getFirstEntry(recList);
|
||||
while (getNextEntry(tn) != lastCheckedRef) {
|
||||
tn = getNextEntry(tn);
|
||||
}
|
||||
lastCheckedRef = tn;
|
||||
}
|
||||
} else {
|
||||
char *expected = getName(getParameter(look_up(getParent(cur), $1)));
|
||||
char *actual = getType(getFirstEntry(cur));
|
||||
if (strcmp(expected, actual) != 0) {
|
||||
printdebug("expected %s expression in function call but got %s at line %d and column %d",expected, actual, @3.first_line, @3.first_column);
|
||||
}
|
||||
}
|
||||
|
||||
$$ = getName(getReturn(table_lookup(getAncestor(cur), $1)));
|
||||
printdebug("[ASSIGNABLE - RULE 2] assignable = type: %s | name_func = %s", $$, $1);
|
||||
|
||||
} else if (type == TYPE_ARRAY_TYPE) {
|
||||
printdebug("%sEntering array call", COLOR_LIGHTGREEN);
|
||||
if (getNumArrDim(look_up(getParent(cur), $1)) != $<integ>2) {
|
||||
printdebug("expected %d arguments but had %d at line %d and column %d\n", getNumArrDim(look_up(cur, $1)), $<integ>2, @2.first_line, @2.first_column);
|
||||
}
|
||||
$$ = getName(getArrType(look_up(getParent(cur), $1)));
|
||||
printdebug("[ASSIGNABLE - RULE 2] assignable = type: %s | name_func = %s", $$, $1);
|
||||
}
|
||||
cur = getParent(cur);
|
||||
}
|
||||
|
||||
| assignable rec_op ID
|
||||
{
|
||||
if(undefined != table_lookup(getRecList(table_lookup(getAncestor(cur), $1)), $3)) {
|
||||
$$ = getName(table_lookup(getRecList(table_lookup(getAncestor(cur), $1)), $3));
|
||||
}
|
||||
printdebug("[ASSIGNABLE - RULE 3] assignable = type: %s | ID = %s", $$, $1);
|
||||
}
|
||||
|
||||
;
|
||||
|
||||
|
||||
|
||||
memOp:
|
||||
RESERVE {printf("reserve expression\n");}
|
||||
| RELEASE {printf("release expression\n");}
|
||||
;
|
||||
RESERVE
|
||||
{
|
||||
printdebug("reserve expression");
|
||||
}
|
||||
|
||||
| RELEASE
|
||||
{
|
||||
printdebug("release expression");
|
||||
}
|
||||
|
||||
;
|
||||
|
||||
|
||||
constant:
|
||||
C_STRING {$$ = $<words>1;}
|
||||
| C_INTEGER {$$ = $<words>1;}
|
||||
| C_NULL {$$ = $<words>1;}
|
||||
| C_CHARACTER {$$ = $<words>1;}
|
||||
| C_TRUE {$$ = $<words>1;}
|
||||
| C_FALSE {$$ = $<words>1;}
|
||||
;
|
||||
C_STRING
|
||||
{
|
||||
$$ = $<words>1;
|
||||
printdebug("string of C_STRING in constant is %s",$<words>1);
|
||||
}
|
||||
|
||||
| C_INTEGER
|
||||
{
|
||||
$$ = "integer";
|
||||
printdebug("string of C_INTEGER in constant is integer");
|
||||
}
|
||||
|
||||
| C_NULL
|
||||
{
|
||||
$$ = $<words>1;
|
||||
printdebug("string of C_NULL in constant is %s",$<words>1);
|
||||
}
|
||||
|
||||
| C_CHARACTER
|
||||
{
|
||||
$$ = $<words>1;
|
||||
printdebug("string of C_CHARACTER in constant is %s",$<words>1);
|
||||
}
|
||||
|
||||
| C_TRUE
|
||||
{
|
||||
$$ = $<words>1;
|
||||
printdebug("string of C_TRUE in constant is %s",$<words>1);
|
||||
}
|
||||
|
||||
| C_FALSE
|
||||
{
|
||||
$$ = $<words>1;
|
||||
printdebug("string of C_FALSE in constant is %s",$<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;}
|
||||
;
|
||||
T_INTEGER
|
||||
{
|
||||
$$ = $1;
|
||||
printdebug("string of T_INTEGER in types is %s",$<words>1);
|
||||
}
|
||||
|
||||
| T_ADDRESS
|
||||
{
|
||||
$$ = $1;
|
||||
printdebug("string of T_ADDRESS in types is %s",$<words>1);
|
||||
}
|
||||
|
||||
| T_CHARACTER
|
||||
{
|
||||
$$ = $1;
|
||||
printdebug("string of T_CHARACTER in types is %s",$<words>1);
|
||||
}
|
||||
|
||||
| T_BOOLEAN
|
||||
{
|
||||
$$ = $1;
|
||||
printdebug("string of T_BOOLEAN in types is %s",$<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);
|
||||
fprintf(stderr, "ERROR: %s at token %s at line number %d,column number %d", err,yytext,yylloc.first_line,yylloc.first_column);
|
||||
}
|
||||
|
@ -4,26 +4,26 @@
|
||||
%option noyywrap
|
||||
%option header-file="flex.h"
|
||||
%option yylineno
|
||||
%{
|
||||
#include <stdbool.h>
|
||||
#include "../tmp/grammar.tab.h"
|
||||
#include "../src/symbol_table.h"
|
||||
#ifndef DEBUG
|
||||
#define DEBUG 0
|
||||
#endif
|
||||
extern SymbolTable * cur;
|
||||
extern FILE* tok_flag;
|
||||
extern void incr(int lnum,int cnum, int tok);
|
||||
extern void print_tok(int tok);
|
||||
|
||||
int line_number = 1, column_number = 1;
|
||||
int yycolumn = 1;
|
||||
#define YY_USER_ACTION { \
|
||||
yylloc.first_line = yylineno; \
|
||||
yylloc.last_line = yylineno; \
|
||||
yylloc.first_column = yycolumn; \
|
||||
yylloc.last_column = yycolumn + yyleng - 1; \
|
||||
yycolumn += yyleng; }
|
||||
%{
|
||||
#include "../tmp/grammar.tab.h"
|
||||
#include "../src/symbol_table.h"
|
||||
#ifndef DEBUG
|
||||
#define DEBUG 0
|
||||
#endif
|
||||
extern SymbolTable * cur;
|
||||
extern FILE* tok_flag;
|
||||
extern void incr(int lnum,int cnum, int tok);
|
||||
extern void print_tok(int tok);
|
||||
|
||||
int line_number = 1, column_number = 1;
|
||||
int yycolumn = 1;
|
||||
#define YY_USER_ACTION { \
|
||||
yylloc.first_line = yylineno; \
|
||||
yylloc.last_line = yylineno; \
|
||||
yylloc.first_column = yycolumn; \
|
||||
yylloc.last_column = yycolumn + yyleng - 1; \
|
||||
yycolumn += yyleng; }
|
||||
%}
|
||||
|
||||
STARCOM [^\*]|\*+[^\)\*]+
|
||||
@ -72,7 +72,7 @@ SCHAR \\n|\\t|\\\"|[^\"\n\\]
|
||||
"," {if(DEBUG) {printf( "COMMA: %s (%d)\n", yytext, COMMA);} else {if(tok_flag != NULL){print_tok(COMMA);}incr(line_number,column_number,COMMA);return COMMA;}}
|
||||
"->" {if(DEBUG) {printf( "ARROW: %s (%d)\n", yytext, ARROW);} else {if(tok_flag != NULL){print_tok(ARROW);}incr(line_number,column_number,ARROW);return ARROW;}}
|
||||
|
||||
{DIGIT}+ {if(DEBUG) {printf( "C_INTEGER: %s (%d)\n", yytext, C_INTEGER);} else {if(tok_flag != NULL){print_tok(C_INTEGER);}incr(line_number,column_number,C_INTEGER);yylval.words = strdup("integer");return C_INTEGER;}}
|
||||
{DIGIT}+ {if(DEBUG) {printf( "C_INTEGER: %s (%d)\n", yytext, C_INTEGER);} else {if(tok_flag != NULL){print_tok(C_INTEGER);}incr(line_number,column_number,C_INTEGER);yylval.integ = atoi(yytext)/*words = strdup("integer")*/;return C_INTEGER;}}
|
||||
'{CHAR}' {if(DEBUG) {printf( "C_CHARACTER: %s (%d)\n", yytext, C_CHARACTER);} else {if(tok_flag != NULL){print_tok(C_CHARACTER);}incr(line_number,column_number,C_CHARACTER);yylval.words = strdup("character");return C_CHARACTER;}}
|
||||
\"{SCHAR}*\" {if(DEBUG) {printf( "C_STRING: %s (%d)\n", yytext, C_STRING);} else {if(tok_flag != NULL){print_tok(C_STRING);}incr(line_number,column_number,C_STRING);yylval.words = strdup("string");return C_STRING;}}
|
||||
{COMMENT} {if(DEBUG) {printf( "COMMENT: %s (%d)\n", yytext, COMMENT);} else {if(tok_flag != NULL){print_tok(COMMENT);}incr(line_number,column_number,COMMENT);/*return COMMENT;*/}}
|
||||
|
41
src/runner.c
41
src/runner.c
@ -2,15 +2,15 @@
|
||||
/* The Translators - Spring 2025 */
|
||||
|
||||
#include "runner.h"
|
||||
extern TableNode *funprime;
|
||||
extern TableNode *arrayprim;
|
||||
extern TableNode *integ;
|
||||
extern TableNode *addr;
|
||||
extern TableNode *chara;
|
||||
extern TableNode *stri;
|
||||
extern TableNode *boo;
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
// if last argument is debug then set to true and ignore it for the rest
|
||||
// of this file
|
||||
if (argc > 1 && strcmp(argv[argc - 1], "-debug") == 0) {
|
||||
DEBUG = true;
|
||||
argc--;
|
||||
}
|
||||
|
||||
if (argc == 1) {
|
||||
fprintf(stderr, INVALID);
|
||||
return -1;
|
||||
@ -80,10 +80,12 @@ void incr(int lnum, int cnum, int tok) {
|
||||
// column_number += yyleng;
|
||||
// }
|
||||
}
|
||||
|
||||
void print_tok(int tok) {
|
||||
fprintf(tok_flag, "%d %d %3d \"%s\"\n", line_number, column_number, tok,
|
||||
yytext);
|
||||
}
|
||||
|
||||
int run(FILE *alpha) {
|
||||
int token;
|
||||
top = cur = init(CreateScope(NULL, 1, 1));
|
||||
@ -132,7 +134,16 @@ int run(FILE *alpha) {
|
||||
|
||||
if (st_flag != NULL) {
|
||||
yyparse();
|
||||
print_symbol_table(getAncestor(cur), st_flag);
|
||||
|
||||
if (cur == NULL) {
|
||||
printdebug("%s[FATAL] cur is null", COLOR_LIGHTRED);
|
||||
}
|
||||
|
||||
if (top == NULL) {
|
||||
printdebug("%s[FATAL] top is null", COLOR_LIGHTRED);
|
||||
}
|
||||
|
||||
print_symbol_table(top, st_flag);
|
||||
fclose(st_flag);
|
||||
if (yyin != NULL) {
|
||||
fclose(yyin);
|
||||
@ -142,7 +153,8 @@ int run(FILE *alpha) {
|
||||
|
||||
yyparse();
|
||||
FILE *f = fdopen(1, "w");
|
||||
print_symbol_table(getAncestor(cur), f);
|
||||
|
||||
print_symbol_table(top, f);
|
||||
fclose(f);
|
||||
|
||||
if (yyin != NULL) {
|
||||
@ -212,13 +224,4 @@ int is_alpha_file(char *alpha, int file_len) {
|
||||
return -1; // not alpha file
|
||||
}
|
||||
return 0; // is alpha file
|
||||
}
|
||||
|
||||
void enter_scope(int line, int column) { cur = CreateScope(cur, line, column); }
|
||||
void exit_scope() {
|
||||
if (cur->Parent_Scope == NULL) {
|
||||
printf("Can't close top");
|
||||
return;
|
||||
}
|
||||
cur = cur->Parent_Scope;
|
||||
}
|
||||
}
|
48
src/runner.h
48
src/runner.h
@ -25,32 +25,56 @@
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "../tmp/flex.h"
|
||||
#include "symbol_table.h"
|
||||
// #include "typedefs.h"
|
||||
#include "../tmp/grammar.tab.h"
|
||||
#include "symbol_table.h"
|
||||
|
||||
extern int line_number, column_number;
|
||||
extern char *yytext;
|
||||
extern FILE *yyin;
|
||||
int arg;
|
||||
extern bool DEBUG;
|
||||
|
||||
SymbolTable *top;
|
||||
SymbolTable *cur;
|
||||
|
||||
// int main(int argc, char* argv[]);
|
||||
char *is_tok(int argc, char *argv[]);
|
||||
// int is_alpha_file(char *file, int file_len);
|
||||
void enter_scope(int, int);
|
||||
void exit_scope(void);
|
||||
|
||||
FILE *alpha_file;
|
||||
FILE *tok_flag = NULL;
|
||||
FILE *st_flag = NULL;
|
||||
bool DEBUG = false;
|
||||
int no_flag = 0;
|
||||
int arg;
|
||||
|
||||
TableNode *funprime;
|
||||
TableNode *arrayprim;
|
||||
TableNode *integ;
|
||||
TableNode *addr;
|
||||
TableNode *chara;
|
||||
TableNode *stri;
|
||||
TableNode *boo;
|
||||
TableNode *recprime;
|
||||
TableNode *funtypeprime;
|
||||
TableNode *undefined;
|
||||
|
||||
int main(int argc, char *argv[]);
|
||||
int check_flag(char *arg, char *alpha);
|
||||
void incr(int lnum, int cnum, int tok);
|
||||
void print_tok(int tok);
|
||||
int run(FILE *alpha);
|
||||
bool is_help(char *input);
|
||||
int new_file(char *arg, char *alpha);
|
||||
int is_alpha_file(char *alpha, int file_len);
|
||||
bool is_help(char *input);
|
||||
int run(FILE *alpha);
|
||||
int check_flag(char *arg, char *alpha);
|
||||
|
||||
char *COLOR_RED = "\033[0;31m";
|
||||
char *COLOR_GREEN = "\033[0;32m";
|
||||
char *COLOR_ORANGE = "\033[0;33m";
|
||||
char *COLOR_BLUE = "\033[0;34m";
|
||||
char *COLOR_PURPLE = "\033[0;35m";
|
||||
char *COLOR_CYAN = "\033[0;36m";
|
||||
char *COLOR_LIGHTGRAY = "\033[0;37m";
|
||||
char *COLOR_DARKGRAY = "\033[1;30m";
|
||||
char *COLOR_LIGHTRED = "\033[1;31m";
|
||||
char *COLOR_LIGHTGREEN = "\033[1;32m";
|
||||
char *COLOR_YELLOW = "\033[1;33m";
|
||||
char *COLOR_LIGHTBLUE = "\033[1;34m";
|
||||
char *COLOR_LIGHTPURPLE = "\033[1;35m";
|
||||
char *COLOR_LIGHTCYAN = "\033[1;36m";
|
||||
char *COLOR_WHITE = "\033[1;37m";
|
File diff suppressed because it is too large
Load Diff
@ -1,3 +1,4 @@
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@ -9,26 +10,12 @@ typedef struct {
|
||||
int size;
|
||||
} primitive_info;
|
||||
|
||||
/*This structure can be subsumed into the structure below (1-d array of chars)
|
||||
typedef struct{
|
||||
//shouldn't need to store any values since would be compiled at runtime
|
||||
//int length;
|
||||
//char* location;
|
||||
}string_info;
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
int numofdimensions;
|
||||
// the above value tells you how long the below array is. For example if
|
||||
// num of dimensions is 5, I can store 1,3,2,5,9 to define > int*
|
||||
// arr; shouldn't need to store any values (like sizes of dimenions or
|
||||
// the location int* sizesofdimensions; do have to store type of array
|
||||
struct TableNode *typeofarray;
|
||||
} array_info;
|
||||
|
||||
typedef struct {
|
||||
// similar to above we define a record to hold the number of elements
|
||||
// and an array of tablenodes (types) that it contains in the >
|
||||
int numofelements;
|
||||
struct SymbolTable *recordScope;
|
||||
} record_info;
|
||||
@ -47,19 +34,16 @@ typedef union {
|
||||
primitive_info *PrimAdInfo;
|
||||
array_info *ArrayAdInfo;
|
||||
record_info *RecAdInfo;
|
||||
// string_info* StringAdInfo;
|
||||
function_declaration_info *FunDecAdInfo;
|
||||
function_type_info *FunTypeAdInfo;
|
||||
} AdInfo;
|
||||
|
||||
typedef struct ListOfTable {
|
||||
struct SymbolTable *table;
|
||||
// struct ListOfTable* prev;
|
||||
struct ListOfTable *next;
|
||||
} ListOfTable;
|
||||
|
||||
typedef struct TableNode {
|
||||
// reference to the type entry that this is
|
||||
struct TableNode *theType;
|
||||
char *theName;
|
||||
AdInfo *additionalinfo;
|
||||
@ -74,30 +58,100 @@ typedef struct SymbolTable {
|
||||
int Column_Number;
|
||||
} SymbolTable;
|
||||
|
||||
typedef enum {
|
||||
TYPE_STRING = 1,
|
||||
TYPE_ARRAY_TYPE = 2,
|
||||
TYPE_RECORD_TYPE = 3,
|
||||
TYPE_FUNCTION_DECLARATION = 4,
|
||||
TYPE_FUNCTION_TYPE = 5,
|
||||
TYPE_PRIMITIVE = 6,
|
||||
TYPE_ALL_ELSE = 7,
|
||||
TYPE_UNDEFINED = 8,
|
||||
TYPE_RECORD = 9,
|
||||
TYPE_ARRAY = 10
|
||||
} types;
|
||||
|
||||
AdInfo *CreatePrimitiveInfo(int size);
|
||||
int getPrimSize(TableNode *definition);
|
||||
AdInfo *CreateArrayInfo(int dim, TableNode *type);
|
||||
int getNumArrDim(TableNode *definition);
|
||||
TableNode *getArrType(TableNode *definition);
|
||||
AdInfo *CreateRecordInfo(int length, SymbolTable *recordScope);
|
||||
int getRecLength(TableNode *definition);
|
||||
SymbolTable *getRecList(TableNode *definition);
|
||||
TableNode *setRecSize(TableNode *tn, int n);
|
||||
int getRecSize(SymbolTable *tn);
|
||||
AdInfo *CreateFunctionDeclarationInfo(int line, bool asorregular);
|
||||
int getStartLine(TableNode *definition);
|
||||
TableNode *setStartLine(TableNode *tn, int start);
|
||||
bool getAsKeyword(TableNode *definition);
|
||||
TableNode *setAsKeyword(TableNode *tn, bool as);
|
||||
AdInfo *CreateFunctionTypeInfo(TableNode *parameter, TableNode *returntype);
|
||||
TableNode *getParameter(TableNode *definition);
|
||||
TableNode *getReturn(TableNode *definition);
|
||||
SymbolTable *CreateScope(SymbolTable *ParentScope, int Line, int Column);
|
||||
SymbolTable *init(SymbolTable *start);
|
||||
TableNode *populateTypeAndInfo(TableNode *tn, TableNode *type, AdInfo *info);
|
||||
int getAdInfoType(TableNode *tn);
|
||||
TableNode *CreateEntry(SymbolTable *table, TableNode *typeOf, char *id,
|
||||
AdInfo *ad);
|
||||
char *getType(TableNode *tn);
|
||||
char *getName(TableNode *tn);
|
||||
int getLine(SymbolTable *st);
|
||||
int getColumn(SymbolTable *st);
|
||||
TableNode *addName(TableNode *tn, char *str);
|
||||
SymbolTable *setLineNumber(SymbolTable *st, int line);
|
||||
SymbolTable *setColumnNumber(SymbolTable *st, int column);
|
||||
TableNode *table_lookup(SymbolTable *table, char *x);
|
||||
TableNode *look_up(SymbolTable *table, char *x);
|
||||
void print_symbol_table(SymbolTable *table, FILE *file_ptr);
|
||||
|
||||
SymbolTable *getAncestor(SymbolTable *table);
|
||||
SymbolTable *removeEntry(SymbolTable *scope, char *search);
|
||||
bool typeCheck(char *firstID, char *secondID);
|
||||
SymbolTable *getParent(SymbolTable *st);
|
||||
ListOfTable *getChildren(SymbolTable *st);
|
||||
SymbolTable *getFirstChild(ListOfTable *lt);
|
||||
ListOfTable *getRestOfChildren(ListOfTable *lt);
|
||||
TableNode *getFirstEntry(SymbolTable *st);
|
||||
TableNode *getNextEntry(TableNode *tn);
|
||||
SymbolTable *init(SymbolTable *scope);
|
||||
int getPrimSize(TableNode *definition);
|
||||
int getNumArrDim(TableNode *definition);
|
||||
TableNode *getArrType(TableNode *definition);
|
||||
int getRecLength(TableNode *definition);
|
||||
SymbolTable *getRecList(TableNode *definition);
|
||||
int getStartLine(TableNode *definition);
|
||||
bool getAsKeyword(TableNode *definition);
|
||||
TableNode *getParameter(TableNode *definition);
|
||||
TableNode *getReturn(TableNode *definition);
|
||||
|
||||
char *getType(TableNode *tn);
|
||||
char *getName(TableNode *tn);
|
||||
int getLine(SymbolTable *st);
|
||||
int getColumn(SymbolTable *st);
|
||||
void printdebug_impl(char *file, int line, const char *format, ...);
|
||||
#define printdebug(format, ...) \
|
||||
printdebug_impl(__FILE__, __LINE__, format, ##__VA_ARGS__)
|
||||
|
||||
extern int yylex(void);
|
||||
extern char *yytext;
|
||||
extern int yyleng;
|
||||
extern int yychar;
|
||||
extern SymbolTable *cur;
|
||||
extern int line_number;
|
||||
extern int column_number;
|
||||
extern FILE *yyin;
|
||||
extern bool DEBUG;
|
||||
|
||||
extern TableNode *funprime;
|
||||
extern TableNode *arrayprim;
|
||||
extern TableNode *integ;
|
||||
extern TableNode *addr;
|
||||
extern TableNode *chara;
|
||||
extern TableNode *stri;
|
||||
extern TableNode *boo;
|
||||
extern TableNode *recprime;
|
||||
extern TableNode *funtypeprime;
|
||||
extern TableNode *undefined;
|
||||
|
||||
extern char *COLOR_RED;
|
||||
extern char *COLOR_GREEN;
|
||||
extern char *COLOR_ORANGE;
|
||||
extern char *COLOR_BLUE;
|
||||
extern char *COLOR_PURPLE;
|
||||
extern char *COLOR_CYAN;
|
||||
extern char *COLOR_LIGHTGRAY;
|
||||
extern char *COLOR_DARKGRAY;
|
||||
extern char *COLOR_LIGHTRED;
|
||||
extern char *COLOR_LIGHTGREEN;
|
||||
extern char *COLOR_YELLOW;
|
||||
extern char *COLOR_LIGHTBLUE;
|
||||
extern char *COLOR_LIGHTPURPLE;
|
||||
extern char *COLOR_LIGHTCYAN;
|
||||
extern char *COLOR_WHITE;
|
166
test.sh
Executable file
166
test.sh
Executable 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" -debug
|
||||
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" -debug
|
||||
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" -debug
|
||||
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" -debug
|
||||
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" -debug
|
||||
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" -debug
|
||||
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" -debug
|
||||
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" -debug
|
||||
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" -debug
|
||||
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
|
@ -1,6 +1,7 @@
|
||||
type rec: [integer: x; integer: y]
|
||||
type T1: integer -> integer
|
||||
type T2: rec -> integer
|
||||
type arr : 1 -> integer
|
||||
|
||||
function foo : T1
|
||||
function bar1 : T2
|
||||
@ -18,10 +19,10 @@ bar2 as (r,s) := {
|
||||
entry(arg) := {
|
||||
[ integer: result ; rec: w]
|
||||
result := foo(5);
|
||||
w := reserve(w); (* see types.alpha – reserve returns a value of type address, which can be assigned to array and record variables*)
|
||||
w := reserve w; (* see types.alpha – reserve returns a value of type address, which can be assigned to array and record variables*)
|
||||
w.x := 5;
|
||||
w.y := 7;
|
||||
result := bar1(w); (* pass w (a rec type value) to bar1 *)
|
||||
result := bar2(5,7); (* implicitly build a rec type value, assign 5 and 7 to fields x and y, but call them r and s *)
|
||||
return 0;
|
||||
}
|
||||
}
|
17
tests/sprint2/test/sp2_function_types.alpha
Normal file
17
tests/sprint2/test/sp2_function_types.alpha
Normal file
@ -0,0 +1,17 @@
|
||||
type Boolean2Boolean: Boolean -> Boolean
|
||||
type integer2integer: integer -> integer
|
||||
type character2integer: character -> integer
|
||||
type Boolean2integer: Boolean -> integer
|
||||
type string2integer: string -> integer
|
||||
function integerXinteger2integer: integerXinteger (*-> integer
|
||||
type integerXinteger2Boolean: integerXinteger -> Boolean
|
||||
type characterXcharacter2Boolean: characterXcharacter -> Boolean
|
||||
type BooleanXBoolean2Boolean: BooleanXBoolean -> Boolean
|
||||
type integer2address: integer -> address
|
||||
type address2integer: address -> integer
|
||||
external function printInteger: integer2integer
|
||||
external function printCharacter: character2integer
|
||||
external function printBoolean: Boolean2integer
|
||||
external function reserve: integer2address
|
||||
external function release: address2integer
|
||||
function entry: string2integer*)
|
@ -7,9 +7,9 @@ You should #include this file at the start of your alpha file.
|
||||
Some useful types are defined below.
|
||||
*)
|
||||
type string: 1 -> character
|
||||
type BooleanXBoolean: [Boolean: x, y]
|
||||
type characterXcharacter: [character: x, y]
|
||||
type integerXinteger: [integer: x, y]
|
||||
type BooleanXBoolean: [Boolean: x; Boolean: y]
|
||||
type characterXcharacter: [character: x; character: y]
|
||||
type integerXinteger: [integer: x; integer: y]
|
||||
|
||||
type Boolean2Boolean: Boolean -> Boolean
|
||||
type integer2integer: integer -> integer
|
||||
@ -25,6 +25,4 @@ type address2integer: address -> integer
|
||||
external function printInteger: integer2integer
|
||||
external function printCharacter: character2integer
|
||||
external function printBoolean: Boolean2integer
|
||||
external function reserve: integer2address
|
||||
external function release: address2integer
|
||||
function entry: string2integer
|
||||
|
@ -9,6 +9,7 @@ function foo : T1
|
||||
function bar1 : T2
|
||||
function bar2 : T2
|
||||
function make_list : list
|
||||
|
||||
make_list(a) := {
|
||||
[integer:orig_a; address: ret; address: curr; address: temp]
|
||||
if (a < 0 | a = 0) then {
|
||||
|
6
tests/sprint3/test/sp3_boolean_binary_op_typecheck.alpha
Normal file
6
tests/sprint3/test/sp3_boolean_binary_op_typecheck.alpha
Normal file
@ -0,0 +1,6 @@
|
||||
entry(arg) := {
|
||||
[integer:x; address: arr; address: arr2; Boolean : b2; Boolean : b1]
|
||||
b2 := 3 < x;
|
||||
b1 := arr = 2;
|
||||
b1 := 6<7 & arr2=7;
|
||||
}
|
5
tests/sprint3/test/sp3_boolean_unary_op_typecheck.alpha
Normal file
5
tests/sprint3/test/sp3_boolean_unary_op_typecheck.alpha
Normal file
@ -0,0 +1,5 @@
|
||||
entry(arg) := {
|
||||
[integer:x; address: arr; address: arr2; Boolean : b2; Boolean : b1]
|
||||
b2 := !(3 < 2);
|
||||
b1 := !5;
|
||||
}
|
25
tests/sprint3/test/sp3_carls_second_mistake.alpha
Normal file
25
tests/sprint3/test/sp3_carls_second_mistake.alpha
Normal file
@ -0,0 +1,25 @@
|
||||
type string: 1 -> character
|
||||
type a_of_s: 1 -> string
|
||||
|
||||
(* maybe some other type definitions *)
|
||||
|
||||
entry(arg) := {
|
||||
[ string: one_name; string: another_name; a_of_s: many_names ]
|
||||
one_name := "a string literal";
|
||||
another_name := reserve another_name(4); (* reserve space for an an array of character, with 4 members *)
|
||||
another_name(0) := 'C';
|
||||
another_name(1) := 'a';
|
||||
another_name(2) := 'r';
|
||||
another_name(3) := 'l';
|
||||
many_names := reserve many_names(3);
|
||||
many_names(0) := one_name;
|
||||
many_names(1) := another_name;
|
||||
many_names(2) := reserve many_names(2)(6); (* reserve space for an item of the same type as a_of_s(2), an array of character, with 6 members *)
|
||||
many_names(2)(0) := 'P';
|
||||
many_names(2)(1) := 'a';
|
||||
many_names(2)(2) := 'r';
|
||||
many_names(2)(3) := 't';
|
||||
many_names(2)(4) := 'h';
|
||||
0(2)(5) := 'o';
|
||||
return 0;
|
||||
}
|
9
tests/sprint3/test/sp3_integer_binary_op_typecheck.alpha
Normal file
9
tests/sprint3/test/sp3_integer_binary_op_typecheck.alpha
Normal file
@ -0,0 +1,9 @@
|
||||
entry(arg) := {
|
||||
[integer:x; address: arr; address: arr2; Boolean : b2; Boolean : b1; character : a]
|
||||
x := 3 + 2 * 8;
|
||||
x := 3 - 2 / 8;
|
||||
x := a * 2 % 8;
|
||||
b2 := 3 * 2 % 8;
|
||||
x := 3 % 2 * 8;
|
||||
x := 3 + arr - 8;
|
||||
}
|
6
tests/sprint3/test/sp3_integer_unary_op_typecheck.alpha
Normal file
6
tests/sprint3/test/sp3_integer_unary_op_typecheck.alpha
Normal file
@ -0,0 +1,6 @@
|
||||
entry(arg) := {
|
||||
[integer:x; address: arr; address: arr2; Boolean : b2; Boolean : b1]
|
||||
x := -8;
|
||||
x := -b1;
|
||||
b2 := -x;
|
||||
}
|
Reference in New Issue
Block a user