Merge pull request #51 from UB-CSE443/Dev
This commit is contained in:
6
.clang-format
Normal file
6
.clang-format
Normal file
@ -0,0 +1,6 @@
|
||||
BasedOnStyle: Google
|
||||
IndentWidth: 4
|
||||
ColumnLimit: 0
|
||||
AllowShortStringsOnSingleLine: true
|
||||
BreakStringLiterals: false
|
||||
ReflowComments: false
|
@ -1,35 +0,0 @@
|
||||
* [32mDev[m
|
||||
Sprint1-TokenLocationLogic-NoTask[m
|
||||
Sprint1-TokenizeConstantsAndLiterals-FE-t#03[m
|
||||
Sprint2-BlockHandlingGrammar-FE-t#34[m
|
||||
Sprint2-CombineGrammarAndMakeAndRunner-BE-NoTask#[m
|
||||
Sprint2-NewFormatPlusGrammar-FE-t#NoTask[m
|
||||
Sprint2-PrintOutErrorTokenPositions-NoTask[m
|
||||
Sprint2-Symbol_Table_Setup-FE-t#32[m
|
||||
Token_Error_Logic-No_Task[m
|
||||
main[m
|
||||
[31mremotes/origin/Dev[m
|
||||
[31mremotes/origin/HEAD[m -> origin/main
|
||||
[31mremotes/origin/Sprint1-BasicProgSetup-FE-t#06[m
|
||||
[31mremotes/origin/Sprint1-BasicProgSetupFix-t#06[m
|
||||
[31mremotes/origin/Sprint1-HelpInput-FE-t#18[m
|
||||
[31mremotes/origin/Sprint1-TokenLocationLogic-NoTask[m
|
||||
[31mremotes/origin/Sprint1-TokenizeConstantsAndLiterals-FE-t#03[m
|
||||
[31mremotes/origin/Sprint1-TokenizeID_MainFunction-FE-t#04[m
|
||||
[31mremotes/origin/Sprint1-TokenizeOperators-FE-t#08[m
|
||||
[31mremotes/origin/Sprint1-Type/Keywards-FE-t#07[m
|
||||
[31mremotes/origin/Sprint1-punctuation/grouping-FE-t#09[m
|
||||
[31mremotes/origin/Sprint2-AssignableAndMemory-FE-t#39[m
|
||||
[31mremotes/origin/Sprint2-BlockHandlingGrammar-FE-t#34[m
|
||||
[31mremotes/origin/Sprint2-CombineGrammarAndMakeAndRunner-BE-NoTask#[m
|
||||
[31mremotes/origin/Sprint2-CommandLineHandling-FE-t#33[m
|
||||
[31mremotes/origin/Sprint2-CompoundStmntGrmmr-FE-t#36[m
|
||||
[31mremotes/origin/Sprint2-FunctionDefinition-FE-t#38[m
|
||||
[31mremotes/origin/Sprint2-Infrastructure-FE-t#30[m
|
||||
[31mremotes/origin/Sprint2-NewFormatPlusGrammar-FE-t#NoTask[m
|
||||
[31mremotes/origin/Sprint2-PrintOutErrorTokenPositions-NoTask[m
|
||||
[31mremotes/origin/Sprint2-SymbolTableOperations-FE-t#29[m
|
||||
[31mremotes/origin/Sprint2-Symbol_Table_Setup-FE-t#32[m
|
||||
[31mremotes/origin/Sprint2-addingTests-t#00[m
|
||||
[31mremotes/origin/Token_Error_Logic-No_Task[m
|
||||
[31mremotes/origin/main[m
|
113
Makefile
113
Makefile
@ -1,59 +1,104 @@
|
||||
# ----- Definitions -----
|
||||
CC := gcc
|
||||
FLEX := flex
|
||||
BISON = bison
|
||||
|
||||
CFLAGS := -ggdb
|
||||
BISONFLAGS := -d
|
||||
|
||||
LEX := src/lexicalStructure.lex
|
||||
YACC := src/grammar.y
|
||||
EXE := alpha
|
||||
CFLAGS :=
|
||||
YACC := bison
|
||||
|
||||
OBJS := tmp/runner.o tmp/symbol_table.o tmp/grammar.tab.o tmp/lex.yy.o tmp/intermediate_code.o tmp/codegen.o
|
||||
|
||||
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
|
||||
|
||||
tmp/grammar.tab.c: src/grammar.y
|
||||
|
||||
# ----- Targets -----
|
||||
all: compiler
|
||||
|
||||
compiler: clean tmp $(OBJS)
|
||||
$(CC) $(CFLAGS) -o $(EXE) $(OBJS)
|
||||
|
||||
clean:
|
||||
rm -f $(EXE)
|
||||
rm -rf out
|
||||
rm -rf tmp
|
||||
rm -f *.s
|
||||
rm -f *.out
|
||||
|
||||
tmp:
|
||||
mkdir -p tmp
|
||||
$(YACC) -d src/grammar.y
|
||||
mv grammar.tab.c tmp/
|
||||
mv grammar.tab.h tmp/
|
||||
|
||||
tmp/lex.yy.c: src/lexicalStructure.lex tmp/grammar.tab.c
|
||||
tmp/grammar.tab.c tmp/grammar.tab.h: $(YACC)
|
||||
$(BISON) $(BISONFLAGS) -o tmp/grammar.tab.c $(YACC)
|
||||
|
||||
tmp/lex.yy.c tmp/flex.h: $(LEX) tmp/grammar.tab.h
|
||||
$(FLEX) -o tmp/lex.yy.c $(LEX)
|
||||
mv flex.h tmp/
|
||||
mv flex.h tmp/flex.h
|
||||
# -----------
|
||||
|
||||
tmp/runner.o: src/runner.c src/runner.h tmp/flex.h
|
||||
$(CC) $(CFLAGS) -o tmp/runner.o -c src/runner.c
|
||||
|
||||
|
||||
# ----- Create Objs -----
|
||||
tmp/grammar.tab.o: tmp/grammar.tab.c
|
||||
$(CC) $(CFLAGS) -c tmp/grammar.tab.c -o tmp/grammar.tab.o
|
||||
|
||||
tmp/lex.yy.o: tmp/lex.yy.c
|
||||
$(CC) $(CFLAGS) -c tmp/lex.yy.c -o tmp/lex.yy.o
|
||||
|
||||
tmp/symbol_table.o: src/symbol_table.c src/symbol_table.h
|
||||
$(CC) $(CFLAGS) -o tmp/symbol_table.o -c src/symbol_table.c
|
||||
$(CC) $(CFLAGS) -c src/symbol_table.c -o tmp/symbol_table.o
|
||||
|
||||
runner: tmp/lex.yy.c tmp/runner.o tmp/symbol_table.o
|
||||
$(CC) $(CFLAGS) -o $(EXE) tmp/runner.o tmp/grammar.tab.c tmp/lex.yy.c
|
||||
tmp/intermediate_code.o: src/intermediate_code.c src/intermediate_code.h
|
||||
$(CC) $(CFLAGS) -c src/intermediate_code.c -o tmp/intermediate_code.o
|
||||
|
||||
debug: CFLAGS += -DDEBUG=1
|
||||
debug: clean compiler
|
||||
tmp/codegen.o: src/codegen.c src/codegen.h
|
||||
$(CC) $(CFLAGS) -c src/codegen.c -o tmp/codegen.o
|
||||
|
||||
test: test-s1 test-s2
|
||||
tmp/runner.o: src/runner.c src/runner.h tmp/flex.h tmp/grammar.tab.h
|
||||
$(CC) $(CFLAGS) -c src/runner.c -o tmp/runner.o
|
||||
# -----------
|
||||
|
||||
|
||||
|
||||
# ----- Tests -----
|
||||
test:
|
||||
chmod +x ./check.sh
|
||||
chmod +x ./test.sh
|
||||
$(foreach test, $(TESTS-S1), (./$(EXE) -tok -debug $(test) || 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 -debug $(test) || true);)
|
||||
./check.sh sp1
|
||||
|
||||
test-s2:
|
||||
chmod +x ./check.sh
|
||||
$(foreach test, $(TESTS-S2), ./$(EXE) -tok $(test);)
|
||||
./check.sh
|
||||
$(foreach test, $(TESTS-S2), ./$(EXE) $(test);)
|
||||
chmod +x ./test.sh
|
||||
./test.sh sp2
|
||||
./check.sh sp2
|
||||
|
||||
clean:
|
||||
rm -f *.o
|
||||
rm -f lex.yy.c
|
||||
rm -f $(EXE)
|
||||
rm -f flex.h
|
||||
rm -f *.tok
|
||||
rm -f grammar.tab.c
|
||||
rm -f grammar.tab.h
|
||||
rm -f *.st
|
||||
rm -rf out
|
||||
rm -rf tmp
|
||||
rm -f parser
|
||||
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
|
||||
# -----------
|
70
check.sh
70
check.sh
@ -5,23 +5,63 @@
|
||||
# The Translators - Spring 2025 #
|
||||
|
||||
TOK_DIR="out"
|
||||
NOCOLOR='\033[0m'
|
||||
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'
|
||||
|
||||
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}"
|
||||
elif [[ ! -s "$file" ]]; then
|
||||
echo -e "${RED}[✘] ${PURPLE}$filename ${WHITE}failed with an empty file. (did it segfault?)${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
|
||||
echo -e "--------------------------------------------"
|
||||
echo -e "Checking $file...\n"
|
||||
diff --color=always "$file" "$exp"
|
||||
echo -e "--------------------------------------------\n"
|
||||
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
|
618
src/codegen.c
Normal file
618
src/codegen.c
Normal file
@ -0,0 +1,618 @@
|
||||
/* Code Generator */
|
||||
/* The Translators - Spring 2025 */
|
||||
|
||||
#include "codegen.h"
|
||||
|
||||
int generate(){
|
||||
offset = 0;
|
||||
Instruction *i = begin;
|
||||
while (i != NULL) {
|
||||
switch(getOp(i)) {
|
||||
case E_LABEL:
|
||||
generateLabel(i);
|
||||
break;
|
||||
case E_ADD:
|
||||
generateAdd(i);
|
||||
break;
|
||||
case E_SUB:
|
||||
generateSub(i);
|
||||
break;
|
||||
case E_MUL:
|
||||
generateMult(i);
|
||||
break;
|
||||
case E_DIV:
|
||||
generateDiv(i);
|
||||
break;
|
||||
case E_MOD:
|
||||
generateMod(i);
|
||||
break;
|
||||
case E_OR:
|
||||
generateOr(i);
|
||||
break;
|
||||
case E_AND:
|
||||
generateAnd(i);
|
||||
break;
|
||||
case E_NEG:
|
||||
generateNeg(i);
|
||||
break;
|
||||
case E_NOT:
|
||||
generateNot(i);
|
||||
break;
|
||||
case E_ASSIGN:
|
||||
generateAssign(i);
|
||||
break;
|
||||
case E_GOTO:
|
||||
generateGoto(i);
|
||||
break;
|
||||
case E_IF_X_TRUE:
|
||||
generateIfTrue(i);
|
||||
break;
|
||||
case E_IF_X_FALSE:
|
||||
generateIfFalse(i);
|
||||
break;
|
||||
case E_LESS_THAN:
|
||||
generateLessThan(i);
|
||||
break;
|
||||
case E_EQUAL_TO:
|
||||
generateEqualTo(i);
|
||||
break;
|
||||
case E_CALL:
|
||||
generateCall(i);
|
||||
break;
|
||||
case E_PARAM:
|
||||
generateParam(i);
|
||||
break;
|
||||
case E_RETURN:
|
||||
generateReturn(i);
|
||||
break;
|
||||
case E_INDEX_COPY_RIGHT:
|
||||
generateCopyRight(i);
|
||||
break;
|
||||
case E_INDEX_COPY_LEFT:
|
||||
generateCopyLeft(i);
|
||||
break;
|
||||
case E_ADDRESS_OF:
|
||||
generateAddressOf(i);
|
||||
break;
|
||||
default:
|
||||
;
|
||||
}
|
||||
i = i->next;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
CGNode *getNextCG(CGNode *cg) {
|
||||
if (cg == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
return cg->next;
|
||||
}
|
||||
|
||||
int getAddress(CGNode *cg) {
|
||||
if (cg == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return currentsp - cg->address;
|
||||
}
|
||||
|
||||
TableNode *getTNofCG(CGNode *cg) {
|
||||
if (cg == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
return cg->tn;
|
||||
}
|
||||
|
||||
CGNode *findCG(TableNode *tn) {
|
||||
CGNode *cg = cgList;
|
||||
while (cg != NULL) {
|
||||
if (getTNofCG(cg) == tn) {
|
||||
return cg;
|
||||
}
|
||||
cg = getNextCG(cg);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
CGNode *addCG(TableNode *tn, int sp) {
|
||||
CGNode *cg = calloc(1, sizeof(CGNode));
|
||||
cg->tn = tn;
|
||||
offset += 4; // <- quick fix getPrimSize(getTypeEntry(tn))
|
||||
cg->address = offset;
|
||||
cg->next = cgList;
|
||||
cgList = cg;
|
||||
return cg;
|
||||
}
|
||||
|
||||
|
||||
int generateLabel(Instruction *inst) {
|
||||
fprintf(cg_flag, ".L%d:\n", getLabel(inst));
|
||||
return 0;
|
||||
}
|
||||
int generateAdd(Instruction *inst) {
|
||||
/*
|
||||
Both immediate:
|
||||
One immediate:
|
||||
Neither immediate:
|
||||
*/
|
||||
TNodeOrConst *op1 = getOperand1(inst);
|
||||
TNodeOrConst *op2 = getOperand2(inst);
|
||||
CGNode *cg = findCG(getResult(inst));
|
||||
|
||||
if (op1 == NULL || op2 == NULL) {
|
||||
printdebug("generateAdd failed, NULL operand");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (cg == NULL) {
|
||||
cg = addCG(getResult(inst), offset);
|
||||
}
|
||||
|
||||
|
||||
CGNode *op1CG = findCG(getTN(op1));
|
||||
CGNode *op2CG = findCG(getTN(op1));
|
||||
if (op1CG == NULL) {
|
||||
printdebug("generateAdd failed, %s is not initialized/in CG", getName(getTN(op1)));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (op2CG == NULL) {
|
||||
printdebug("generateAdd failed, %s is not initialized/in CG", getName(getTN(op2)));
|
||||
return -1;
|
||||
}
|
||||
fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\t#addition start\n", getAddress(op1CG));
|
||||
fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\n", getAddress(op2CG));
|
||||
fprintf(cg_flag, "\taddl\t%%edx, %%eax\n");
|
||||
fprintf(cg_flag, "\tmovl\t%%eax, %d(%%rbp)\t#addition end\n", getAddress(cg));
|
||||
return 0;
|
||||
}
|
||||
|
||||
int generateSub(Instruction *instruction) {
|
||||
/*
|
||||
Both immediate:
|
||||
One immediate:
|
||||
Neither immediate:
|
||||
*/
|
||||
TNodeOrConst *op1 = getOperand1(instruction);
|
||||
TNodeOrConst *op2 = getOperand2(instruction);
|
||||
CGNode *cg = findCG(getResult(instruction));
|
||||
|
||||
if (op1 == NULL || op2 == NULL) {
|
||||
printdebug("generateSub failed, NULL operand");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (cg == NULL) {
|
||||
cg = addCG(getResult(instruction), offset);
|
||||
}
|
||||
|
||||
CGNode *op1CG = findCG(getTN(op1));
|
||||
CGNode *op2CG = findCG(getTN(op2));
|
||||
if (op1CG == NULL) {
|
||||
printdebug("generateSub failed, op1 is not constant but not in CGlist");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (op2CG == NULL) {
|
||||
printdebug("generateAdd failed, %s is not initialized/in CG", getName(getTN(op2)));
|
||||
return -1;
|
||||
}
|
||||
|
||||
fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\t#subtraction start\n", getAddress(op1CG));
|
||||
fprintf(cg_flag, "\tsubl\t%d(%%rbp), %%eax\n", getAddress(op2CG));
|
||||
fprintf(cg_flag, "\tmovl\t%%eax, %d(%%rbp)\t#subtraction end\n", getAddress(cg));
|
||||
return 0;
|
||||
}
|
||||
|
||||
int generateMult(Instruction *inst){
|
||||
/*
|
||||
Both immediate:
|
||||
One immediate:
|
||||
Neither immediate:
|
||||
*/
|
||||
TNodeOrConst *op1 = getOperand1(inst);
|
||||
TNodeOrConst *op2 = getOperand2(inst);
|
||||
CGNode *cg = findCG(getResult(inst));
|
||||
|
||||
if (op1 == NULL || op2 == NULL) {
|
||||
printdebug("generateMult failed, NULL operand");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (cg == NULL) {
|
||||
cg = addCG(getResult(inst), offset);
|
||||
}
|
||||
CGNode *op1CG = findCG(getTN(op1));
|
||||
CGNode *op2CG = findCG(getTN(op2));
|
||||
if (op1CG == NULL) {
|
||||
printdebug("generateMult failed, op1 is not constant but not in CGlist");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (op2CG == NULL) {
|
||||
printdebug("generateMult failed, %s is not initialized/in CG", getName(getTN(op2)));
|
||||
return -1;
|
||||
}
|
||||
|
||||
fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\t#multiplication start\n", getAddress(op1CG));
|
||||
fprintf(cg_flag, "\timull\t%d(%%rbp), %%eax\n", getAddress(op2CG));
|
||||
fprintf(cg_flag, "\tmovl\t%%eax, %d(%%rbp)\t#multiplication end\n", getAddress(cg));
|
||||
return 0;
|
||||
}
|
||||
|
||||
int generateDiv(Instruction *inst) {
|
||||
/*
|
||||
Both immediate:
|
||||
One immediate:
|
||||
Neither immediate:
|
||||
*/
|
||||
TNodeOrConst *op1 = getOperand1(inst);
|
||||
TNodeOrConst *op2 = getOperand2(inst);
|
||||
CGNode *cg = findCG(getResult(inst));
|
||||
|
||||
if (op1 == NULL || op2 == NULL) {
|
||||
printdebug("generateDiv failed, NULL operand");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (cg == NULL) {
|
||||
cg = addCG(getResult(inst), offset);
|
||||
}
|
||||
|
||||
CGNode *op1CG = findCG(getTN(op1));
|
||||
CGNode *op2CG = findCG(getTN(op2));
|
||||
if (op1CG == NULL) {
|
||||
printdebug("generateDiv failed, op1 is not constant but not in CGlist");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (op2CG == NULL) {
|
||||
printdebug("generateDiv failed, %s is not initialized/in CG", getName(getTN(op2)));
|
||||
return -1;
|
||||
}
|
||||
|
||||
fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\t#division start\n", getAddress(op1CG)); //moves dividend into eax
|
||||
fprintf(cg_flag, "\tcltd\n"); //sign extends the dividend in eax
|
||||
fprintf(cg_flag, "\tidivl\t%d(%%rbp)\n", getAddress(op2CG));//divides edx by value accessed from stack
|
||||
fprintf(cg_flag, "\tmovl\t%%eax, %d(%%rbp)\t#division end\n", getAddress(cg)); //stores result
|
||||
return 0;
|
||||
}
|
||||
|
||||
int generateMod(Instruction *inst) {
|
||||
/*
|
||||
Both immediate:
|
||||
One immediate:
|
||||
Neither immediate:
|
||||
*/
|
||||
TNodeOrConst *op1 = getOperand1(inst);
|
||||
TNodeOrConst *op2 = getOperand2(inst);
|
||||
CGNode *cg = findCG(getResult(inst));
|
||||
|
||||
if (op1 == NULL || op2 == NULL) {
|
||||
printdebug("generateMod failed, NULL operand");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (cg == NULL) {
|
||||
cg = addCG(getResult(inst), offset);
|
||||
}
|
||||
CGNode *op1CG = findCG(getTN(op1));
|
||||
CGNode *op2CG = findCG(getTN(op2));
|
||||
if (op1CG == NULL) {
|
||||
printdebug("generateMod failed, op1 is not constant but not in CGlist");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (op2CG == NULL) {
|
||||
printdebug("generateMod failed, %s is not initialized/in CG", getName(getTN(op2)));
|
||||
return -1;
|
||||
}
|
||||
|
||||
fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\t#mod start\n", getAddress(op1CG)); //moves dividend into eax
|
||||
fprintf(cg_flag, "\tcltd\n"); //sign extends the dividend in eax
|
||||
fprintf(cg_flag, "\tidivl\t%d(%%rbp)\n", getAddress(op2CG));//divides edx by value accessed from stack
|
||||
fprintf(cg_flag, "\tmovl\t%%edx, %d(%%rbp)\t#mod end\n", getAddress(cg)); //stores result from edx (remainder)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int generateOr(Instruction *inst) {
|
||||
/*
|
||||
Both immediate:
|
||||
One immediate:
|
||||
Neither immediate:
|
||||
*/
|
||||
TNodeOrConst *op1 = getOperand1(inst);
|
||||
TNodeOrConst *op2 = getOperand2(inst);
|
||||
CGNode *cg = findCG(getResult(inst));
|
||||
|
||||
if (op1 == NULL || op2 == NULL) {
|
||||
printdebug("generateOr failed, NULL operand");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (cg == NULL) {
|
||||
cg = addCG(getResult(inst), offset);
|
||||
}
|
||||
|
||||
CGNode *op1CG = findCG(getTN(op1));
|
||||
CGNode *op2CG = findCG(getTN(op2));
|
||||
if (op1CG == NULL) {
|
||||
printdebug("generateOr failed, op1 is not constant but not in CGlist");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (op2CG == NULL) {
|
||||
printdebug("generateOr failed, %s is not initialized/in CG", getName(getTN(op2)));
|
||||
return -1;
|
||||
}
|
||||
|
||||
int label = label_gen();
|
||||
|
||||
fprintf(cg_flag, "\tcmpl\t$0, %d(%%rbp)\t#start or\n", getAddress(op1CG));
|
||||
fprintf(cg_flag, "\tjne\t.L%dor2\n", label);
|
||||
|
||||
fprintf(cg_flag, "\tcmpl\t$0, %d(%%rbp)\n", getAddress(op2CG));
|
||||
fprintf(cg_flag, "\tje\t.L%dor3\n", label);
|
||||
|
||||
fprintf(cg_flag, ".L%dor2:\n", label);
|
||||
fprintf(cg_flag, "\tmovl\t$1, %%eax\n");
|
||||
fprintf(cg_flag, "\tjmp\t.L%dor4\n", label);
|
||||
|
||||
fprintf(cg_flag, ".L%dor3:\n", label);
|
||||
fprintf(cg_flag, "\tmovl\t$0, %%eax\n");
|
||||
|
||||
fprintf(cg_flag, ".L%dor4:\n", label);
|
||||
fprintf(cg_flag, "\tmovb\t%%al, %d(%%rbp)\n", getAddress(cg));
|
||||
fprintf(cg_flag, "\tandb\t$1, %d(%%rbp)\t#or end\n", getAddress(cg)); //stores result
|
||||
return 0;
|
||||
}
|
||||
|
||||
int generateAnd(Instruction *inst) {
|
||||
/*
|
||||
Both immediate:
|
||||
One immediate:
|
||||
Neither immediate:
|
||||
*/
|
||||
TNodeOrConst *op1 = getOperand1(inst);
|
||||
TNodeOrConst *op2 = getOperand2(inst);
|
||||
CGNode *cg = findCG(getResult(inst));
|
||||
|
||||
if (op1 == NULL || op2 == NULL) {
|
||||
printdebug("%sgenerateAnd failed, NULL operand", COLOR_RED);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (cg == NULL) {
|
||||
cg = addCG(getResult(inst), offset);
|
||||
}
|
||||
|
||||
CGNode *op1CG = findCG(getTN(op1));
|
||||
CGNode *op2CG = findCG(getTN(op2));
|
||||
if (op1CG == NULL) {
|
||||
printdebug("generateAnd failed, op1 is not constant but not in CGlist");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (op2CG == NULL) {
|
||||
printdebug("generateAnd failed, %s is not initialized/in CG", getName(getTN(op2)));
|
||||
return -1;
|
||||
}
|
||||
int label = label_gen();
|
||||
|
||||
fprintf(cg_flag, "\tcmpl\t$0, %d(%%rbp)\t#start and\n", getAddress(op1CG));
|
||||
fprintf(cg_flag, "\tje\t.L%dor2\n", label);
|
||||
|
||||
fprintf(cg_flag, "\tcmpl\t$0, %d(%%rbp)\n", getAddress(op2CG));
|
||||
fprintf(cg_flag, "\tje\t.L%dor2\n", label);
|
||||
|
||||
fprintf(cg_flag, "\tmovl\t$1, %%eax\n");
|
||||
fprintf(cg_flag, "\tjmp\t.L%dor3\n", label);
|
||||
|
||||
fprintf(cg_flag, ".L%dor2:\n", label);
|
||||
fprintf(cg_flag, "\tmovl\t$0, %%eax\n");
|
||||
|
||||
fprintf(cg_flag, ".L%dor3:\n", label);
|
||||
fprintf(cg_flag, "\tmovb\t%%al, %d(%%rbp)\n", getAddress(cg));
|
||||
fprintf(cg_flag, "\tandb\t$1, %d(%%rbp)\t#and end\n", getAddress(cg)); //stores result
|
||||
return 0;
|
||||
}
|
||||
int generateNeg(Instruction *inst) {
|
||||
TNodeOrConst *op1 = getOperand1(inst);
|
||||
CGNode *cg = findCG(getResult(inst));
|
||||
|
||||
if (op1 == NULL) {
|
||||
printdebug("generateNeg failed, NULL operand");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (cg == NULL) {
|
||||
cg = addCG(getResult(inst), offset);
|
||||
}
|
||||
|
||||
CGNode *op1CG = findCG(getTN(op1));
|
||||
if (op1CG == NULL) {
|
||||
printdebug("generateNeg failed, op1 is not constant but not in CGlist");
|
||||
return -1;
|
||||
}
|
||||
|
||||
fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\t#negation start\n", getAddress(op1CG));
|
||||
fprintf(cg_flag, "\tnegl\t%%eax\n");
|
||||
fprintf(cg_flag, "\tmovl\t%%eax, %d(%%rbp)\t#negation end\n", getAddress(cg));
|
||||
return 0;
|
||||
}
|
||||
int generateNot(Instruction *inst) {
|
||||
TNodeOrConst *op1 = getOperand1(inst);
|
||||
CGNode *cg = findCG(getResult(inst));
|
||||
|
||||
if (op1 == NULL) {
|
||||
printdebug("generateNot failed, NULL operand");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (cg == NULL) {
|
||||
cg = addCG(getResult(inst), offset);
|
||||
}
|
||||
|
||||
CGNode *op1CG = findCG(getTN(op1));
|
||||
if (op1CG == NULL) {
|
||||
printdebug("generateNot failed, op1 is not constant but not in CGlist");
|
||||
return -1;
|
||||
}
|
||||
|
||||
fprintf(cg_flag, "\tmovzbl\t%d(%%rbp), %%eax\t#not start\n", getAddress(op1CG));
|
||||
fprintf(cg_flag, "\ttestl\t%%eax, %%eax\n");
|
||||
fprintf(cg_flag, "\tsetne\t%%al\n");
|
||||
fprintf(cg_flag, "\txorl\t$1, %%eax\n");
|
||||
fprintf(cg_flag, "\tmovzbl\t%%al, %%eax\n");
|
||||
fprintf(cg_flag, "\tmovb\t%%al, %d(%%rbp)\n", getAddress(cg));
|
||||
fprintf(cg_flag, "\tandb\t$1, %d(%%rbp)\t#not end\n", getAddress(cg));
|
||||
return 0;
|
||||
}
|
||||
|
||||
int generateAssign(Instruction *inst) {
|
||||
TNodeOrConst *op1 = getOperand1(inst);
|
||||
CGNode *cg = findCG(getResult(inst));
|
||||
|
||||
|
||||
if (op1 == NULL) {
|
||||
printdebug("generateAssign failed, NULL operand");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (cg == NULL) {
|
||||
cg = addCG(getResult(inst), offset);
|
||||
}
|
||||
|
||||
|
||||
//add option for constant assignment (should be easy)
|
||||
if (isConst(op1) == true) {
|
||||
fprintf(cg_flag, "\tmovl\t$%d, %d(%%rbp)\t#constant assign\n", getConst(op1), getAddress(cg));
|
||||
return 0;
|
||||
}
|
||||
|
||||
CGNode *op1CG = findCG(getTN(op1));
|
||||
if (op1CG == NULL) {
|
||||
printf("failed here\n");
|
||||
printdebug("generateAssign failed, op1 is not constant but not in CGlist");
|
||||
return -1;
|
||||
}
|
||||
|
||||
fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\t#assign start\n", getAddress(op1CG));
|
||||
fprintf(cg_flag, "\tmovl\t%%eax, %d(%%rbp)\t#assign end\n", getAddress(cg));
|
||||
return 0;
|
||||
}
|
||||
|
||||
int generateGoto(Instruction *instruction){
|
||||
return -1;
|
||||
}
|
||||
|
||||
int generateCondGoto(Instruction *instruction) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int generateIfTrue(Instruction *instruction){
|
||||
return -1;
|
||||
// might just be a goto for where to go if something is true, or returning if something is true, or checking if true and writing goto if thats the case
|
||||
}
|
||||
|
||||
int generateIfFalse(Instruction *instruction){
|
||||
return -1;
|
||||
}
|
||||
|
||||
int generateLessThan(Instruction *inst){
|
||||
/*
|
||||
Both immediate:
|
||||
One immediate:
|
||||
Neither immediate:
|
||||
*/
|
||||
TNodeOrConst *op1 = getOperand1(inst);
|
||||
TNodeOrConst *op2 = getOperand2(inst);
|
||||
CGNode *cg = findCG(getResult(inst));
|
||||
|
||||
if (op1 == NULL || op2 == NULL) {
|
||||
printdebug("%sgenerateLessThan failed, NULL operand", COLOR_RED);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (cg == NULL) {
|
||||
cg = addCG(getResult(inst), offset);
|
||||
}
|
||||
|
||||
CGNode *op1CG = findCG(getTN(op1));
|
||||
CGNode *op2CG = findCG(getTN(op2));
|
||||
if (op1CG == NULL) {
|
||||
printdebug("generateLessThan failed, op1 is not constant but not in CGlist");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (op2CG == NULL) {
|
||||
printdebug("generateLessThan failed, %s is not initialized/in CG", getName(getTN(op2)));
|
||||
return -1;
|
||||
}
|
||||
|
||||
fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\t#less than start\n", getAddress(op1CG));
|
||||
fprintf(cg_flag, "\tcmpl\t%d(%%rbp), %%eax\n", getAddress(op2CG));
|
||||
fprintf(cg_flag, "\tsetl\t%%al\n");
|
||||
fprintf(cg_flag, "\tmovb\t%%al, %d(%%rbp)\t#less than end\n", getAddress(cg));
|
||||
return 0;
|
||||
}
|
||||
|
||||
int generateEqualTo(Instruction *inst){
|
||||
/*
|
||||
Both immediate:
|
||||
One immediate:
|
||||
Neither immediate:
|
||||
*/
|
||||
TNodeOrConst *op1 = getOperand1(inst);
|
||||
TNodeOrConst *op2 = getOperand2(inst);
|
||||
CGNode *cg = findCG(getResult(inst));
|
||||
|
||||
if (op1 == NULL || op2 == NULL) {
|
||||
printdebug("%sgenerateLessThan failed, NULL operand", COLOR_RED);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (cg == NULL) {
|
||||
cg = addCG(getResult(inst), offset);
|
||||
}
|
||||
|
||||
CGNode *op1CG = findCG(getTN(op1));
|
||||
CGNode *op2CG = findCG(getTN(op2));
|
||||
if (op1CG == NULL) {
|
||||
printdebug("generateLessThan failed, op1 is not constant but not in CGlist");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (op2CG == NULL) {
|
||||
printdebug("generateLessThan failed, %s is not initialized/in CG", getName(getTN(op2)));
|
||||
return -1;
|
||||
}
|
||||
|
||||
fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\t#equal to start\n", getAddress(op1CG));
|
||||
fprintf(cg_flag, "\tcmpl\t%d(%%rbp), %%eax\n", getAddress(op2CG));
|
||||
fprintf(cg_flag, "\tsete\t%%al\n");
|
||||
fprintf(cg_flag, "\tmovb\t%%al, %d(%%rbp)\t#equal to end\n", getAddress(cg));
|
||||
return 0;
|
||||
}
|
||||
int generateCall(Instruction *instruction){
|
||||
return -1;
|
||||
//will want to store parameters and then update the offset by adding 8? for stack pointer stuff, can then print call subroutine name, followed by movl of the result into the result's cg
|
||||
}
|
||||
int generateReturn(Instruction *instruction){
|
||||
return -1;
|
||||
//will movl the result into the appropriate register and move the stack pointer/offset stuff back to correct value
|
||||
}
|
||||
int generateCopyRight(Instruction *instruction){
|
||||
return -1;
|
||||
}
|
||||
int generateCopyLeft(Instruction *instruction){
|
||||
return -1;
|
||||
}
|
||||
int generateAddressOf(Instruction *instruction){
|
||||
return -1;
|
||||
}
|
||||
int generateParam(Instruction *instruction){
|
||||
//need to check if op1 is null, then add it to the appropriate register/cg node. need a way to keep track of this, maybe just have global count of params generated
|
||||
return -1;
|
||||
}
|
60
src/codegen.h
Normal file
60
src/codegen.h
Normal file
@ -0,0 +1,60 @@
|
||||
/* Code Generator */
|
||||
/* The Translators - Spring 2025 */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "intermediate_code.h"
|
||||
#include "symbol_table.h"
|
||||
|
||||
extern FILE *cg_flag;
|
||||
|
||||
typedef struct CGNode {
|
||||
TableNode *tn;
|
||||
int address;
|
||||
CGNode *next;
|
||||
} CGNode;
|
||||
|
||||
int generate();
|
||||
CGNode *getNextCG(CGNode *cg);
|
||||
int getAddress(CGNode *cg);
|
||||
TableNode *getTNofCG(CGNode *cg);
|
||||
CGNode *findCG(TableNode *tn);
|
||||
CGNode *addCG(TableNode *tn, int sp);
|
||||
int generateLabel(Instruction *inst);
|
||||
int generateAdd(Instruction *inst);
|
||||
int generateSub(Instruction *instruction);
|
||||
int generateMult(Instruction *inst);
|
||||
int generateDiv(Instruction *inst);
|
||||
int generateMod(Instruction *inst);
|
||||
int generateOr(Instruction *inst);
|
||||
int generateAnd(Instruction *inst);
|
||||
int generateNeg(Instruction *inst);
|
||||
int generateNot(Instruction *inst);
|
||||
int generateAssign(Instruction *inst);
|
||||
int generateGoto(Instruction *instruction);
|
||||
int generateCondGoto(Instruction *instruction);
|
||||
int generateIfTrue(Instruction *instruction);
|
||||
int generateIfFalse(Instruction *instruction);
|
||||
int generateLessThan(Instruction *inst);
|
||||
int generateEqualTo(Instruction *inst);
|
||||
int generateCall(Instruction *instruction);
|
||||
int generateReturn(Instruction *instruction);
|
||||
int generateCopyRight(Instruction *instruction);
|
||||
int generateCopyLeft(Instruction *instruction);
|
||||
int generateAddressOf(Instruction *instruction);
|
||||
int generateParam(Instruction *instruction);
|
||||
|
||||
extern int label_count;
|
||||
extern Instruction *begin;
|
||||
extern Instruction *current;
|
||||
|
||||
extern int offset;
|
||||
extern int currentsp;
|
||||
extern CGNode *cgList;
|
32
src/grammar.h
Normal file
32
src/grammar.h
Normal file
@ -0,0 +1,32 @@
|
||||
/* Syntax Analyzer with Bison (3.8.2) */
|
||||
/* The Translators - Spring 2025 */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../src/codegen.h"
|
||||
#include "../src/intermediate_code.h"
|
||||
#include "../src/symbol_table.h"
|
||||
extern FILE *asc_flag;
|
||||
extern bool tc_flag;
|
||||
extern void insert_code_line(char * error_message, int line_number);
|
||||
|
||||
typedef enum {
|
||||
ERROR_RUNTIME = 1,
|
||||
ERROR_SYNTAX = 2,
|
||||
ERROR_TYPE = 3,
|
||||
ERROR_UNDEFINED = 4
|
||||
} ErrorType;
|
||||
|
||||
int token_tracker;
|
||||
TableNode *tn;
|
||||
|
||||
void yyerror(const char *err);
|
||||
void throw_error(ErrorType error_type, const char *format, ...);
|
||||
|
||||
int label_count;
|
||||
Instruction *begin;
|
||||
Instruction *current;
|
||||
|
||||
int offset;
|
||||
int currentsp;
|
||||
CGNode *cgList;
|
1264
src/grammar.y
1264
src/grammar.y
File diff suppressed because it is too large
Load Diff
400
src/intermediate_code.c
Normal file
400
src/intermediate_code.c
Normal file
@ -0,0 +1,400 @@
|
||||
/* Intermediate Code */
|
||||
/* The Translators - Spring 2025 */
|
||||
|
||||
#include "intermediate_code.h"
|
||||
|
||||
// TODO: this is here to bring your attention to the comment bellow.
|
||||
// check if start is NULL if it is assign it to the start globle variable
|
||||
// otherwise make it next of current and set cur to your instruction.
|
||||
TNodeOrConst* getOperand1(Instruction* i) {
|
||||
return i->operand1;
|
||||
}
|
||||
|
||||
TNodeOrConst* getOperand2(Instruction* i) {
|
||||
return i->operand2;
|
||||
}
|
||||
|
||||
TableNode* getResult(Instruction* i) {
|
||||
return i->result;
|
||||
}
|
||||
|
||||
Op getOp(Instruction* i) {
|
||||
return i->opcode;
|
||||
}
|
||||
|
||||
int getLabel(Instruction* i) {
|
||||
return i->label;
|
||||
}
|
||||
|
||||
int get_index(Instruction* i) {
|
||||
return i->index;
|
||||
}
|
||||
|
||||
void set_label(Instruction* i, int label) {
|
||||
i->label = label;
|
||||
}
|
||||
|
||||
bool isConst(TNodeOrConst* tnc) {
|
||||
return tnc->d != NODE;
|
||||
}
|
||||
|
||||
TNodeOrConst* tn_or_const(Discriminant d, void* tnc) {
|
||||
TNodeOrConst* count = calloc(1, sizeof(*count));
|
||||
count->d = d;
|
||||
count->tnc_union = calloc(1, sizeof(*count->tnc_union));
|
||||
switch (d) {
|
||||
case NODE:
|
||||
count->tnc_union->node = tnc;
|
||||
break;
|
||||
case ADDRESS:
|
||||
count->tnc_union->address = tnc;
|
||||
break;
|
||||
case STRING:
|
||||
count->tnc_union->string = tnc;
|
||||
break;
|
||||
case INTEGER:
|
||||
count->tnc_union->integer = *(int*)tnc;
|
||||
break;
|
||||
case CHARACTER:
|
||||
count->tnc_union->character = *(char*)tnc;
|
||||
break;
|
||||
case BOOLEAN:
|
||||
count->tnc_union->Boolean = *(uint_least8_t*)tnc;
|
||||
break;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
static void emit_helper(void) {
|
||||
Instruction* inst = calloc(1, sizeof(*inst));
|
||||
if (begin == NULL) {
|
||||
begin = current = inst;
|
||||
current->index = 1;
|
||||
} else {
|
||||
current->next = inst;
|
||||
inst->prev = current;
|
||||
inst->index = current->index + 1;
|
||||
current = inst;
|
||||
}
|
||||
}
|
||||
|
||||
void emit_binary_op(Op op, TableNode* result, TNodeOrConst* arg1, TNodeOrConst* arg2) {
|
||||
emit_helper();
|
||||
current->opcode = op;
|
||||
// TODO: create temp and remove result from param list
|
||||
current->result = result;
|
||||
current->operand1 = arg1;
|
||||
current->operand2 = arg2;
|
||||
}
|
||||
|
||||
void emit_unary_op(Op op, TableNode* result, TNodeOrConst* arg) {
|
||||
emit_helper();
|
||||
current->opcode = op;
|
||||
current->result = result;
|
||||
current->operand1 = arg;
|
||||
}
|
||||
|
||||
void emit_assignment(TableNode* target, TNodeOrConst* source) {
|
||||
emit_helper();
|
||||
current->opcode = E_ASSIGN;
|
||||
current->result = target;
|
||||
current->operand1 = source;
|
||||
}
|
||||
|
||||
char* get_string(TNodeOrConst* tc) {
|
||||
char* s;
|
||||
switch (tc->d) {
|
||||
case NODE:
|
||||
return getName(tc->tnc_union->node);
|
||||
case ADDRESS:
|
||||
return strdup("null");
|
||||
case STRING:
|
||||
return tc->tnc_union->string;
|
||||
case INTEGER:
|
||||
s = calloc(10, sizeof(char));
|
||||
sprintf(s, "%d", tc->tnc_union->integer);
|
||||
return s;
|
||||
case CHARACTER:
|
||||
s = calloc(2, sizeof(char));
|
||||
sprintf(s, "%c", tc->tnc_union->character);
|
||||
return s;
|
||||
case BOOLEAN:
|
||||
if (tc->tnc_union->Boolean) {
|
||||
return strdup("true");
|
||||
}
|
||||
return strdup("false");
|
||||
}
|
||||
}
|
||||
|
||||
void emit_as_file(FILE* out_file, Instruction* i) {
|
||||
if (i == NULL) {
|
||||
return;
|
||||
}
|
||||
switch (i->opcode) {
|
||||
case E_LABEL:
|
||||
break;
|
||||
// this is a terrible one to start with
|
||||
// fprintf(out_file, "%04.d: %d ", i->index, i->label);
|
||||
case E_ADD:
|
||||
fprintf(out_file, "%4.d: %s = %s + %s\n",
|
||||
i->index, getName(i->result),
|
||||
get_string(i->operand1),
|
||||
get_string(i->operand2));
|
||||
break;
|
||||
case E_SUB:
|
||||
fprintf(out_file, "%4.d: %s = %s - %s\n",
|
||||
i->index, getName(i->result),
|
||||
get_string(i->operand1),
|
||||
get_string(i->operand2));
|
||||
break;
|
||||
case E_MUL:
|
||||
fprintf(out_file, "%4.d: %s = %s * %s\n",
|
||||
i->index, getName(i->result),
|
||||
get_string(i->operand1),
|
||||
get_string(i->operand2));
|
||||
break;
|
||||
case E_DIV:
|
||||
fprintf(out_file, "%4.d: %s = %s / %s\n",
|
||||
i->index, getName(i->result),
|
||||
get_string(i->operand1),
|
||||
get_string(i->operand2));
|
||||
break;
|
||||
case E_MOD:
|
||||
fprintf(out_file, "%4.d: %s = %s %% %s\n",
|
||||
i->index, getName(i->result),
|
||||
get_string(i->operand1),
|
||||
get_string(i->operand2));
|
||||
break;
|
||||
case E_OR:
|
||||
fprintf(out_file, "%4.d: %s = %s | %s\n",
|
||||
i->index, getName(i->result),
|
||||
get_string(i->operand1),
|
||||
get_string(i->operand2));
|
||||
break;
|
||||
case E_AND:
|
||||
fprintf(out_file, "%4.d: %s = %s & %s\n",
|
||||
i->index, getName(i->result),
|
||||
get_string(i->operand1),
|
||||
get_string(i->operand2));
|
||||
break;
|
||||
case E_NEG:
|
||||
fprintf(out_file, "%4.d: %s = -%s\n",
|
||||
i->index, getName(i->result),
|
||||
get_string(i->operand1));
|
||||
break;
|
||||
case E_NOT:
|
||||
fprintf(out_file, "%4.d: %s = !%s\n",
|
||||
i->index, getName(i->result),
|
||||
get_string(i->operand1));
|
||||
break;
|
||||
case E_ASSIGN:
|
||||
fprintf(out_file, "%4.d: %s = %s\n",
|
||||
i->index, getName(i->result),
|
||||
get_string(i->operand1));
|
||||
break;
|
||||
case E_GOTO:
|
||||
// are we ever going to use this?
|
||||
// yes we do look at bounds checking
|
||||
case E_IF_X_TRUE:
|
||||
fprintf(out_file, "%4.d: if %s goto %d\n",
|
||||
i->index, get_string(i->operand1),
|
||||
i->label);
|
||||
break;
|
||||
case E_IF_X_FALSE:
|
||||
fprintf(out_file, "%4.d: if %s false goto %d\n",
|
||||
i->index, get_string(i->operand1),
|
||||
i->label);
|
||||
break;
|
||||
case E_LESS_THAN:
|
||||
fprintf(out_file, "%4.d: if %s < %s goto %d\n",
|
||||
i->index, get_string(i->operand1),
|
||||
get_string(i->operand2), i->label);
|
||||
break;
|
||||
case E_EQUAL_TO:
|
||||
fprintf(out_file, "%4.d: if %s = %s goto %d\n",
|
||||
i->index, get_string(i->operand1),
|
||||
get_string(i->operand2), i->label);
|
||||
break;
|
||||
case E_CALL:
|
||||
fprintf(out_file, "%4.d: call %s %s\n",
|
||||
i->index, get_string(i->operand1),
|
||||
get_string(i->operand2));
|
||||
break;
|
||||
|
||||
case E_PARAM:
|
||||
fprintf(out_file, "%4.d: param %s \n",
|
||||
i->index, get_string(i->operand1));
|
||||
break;
|
||||
case E_RETURN:
|
||||
|
||||
case E_INDEX_COPY_RIGHT:
|
||||
case E_INDEX_COPY_LEFT:
|
||||
|
||||
case E_ADDRESS_OF:
|
||||
|
||||
case E_DEREF_RIGHT:
|
||||
case E_DEREF_LEFT:
|
||||
}
|
||||
|
||||
emit_as_file(out_file, i->next);
|
||||
}
|
||||
|
||||
void emit_label(int label) {
|
||||
emit_helper();
|
||||
current->opcode = E_LABEL;
|
||||
current->label = label;
|
||||
}
|
||||
|
||||
void emit_jump(int label) {
|
||||
emit_helper();
|
||||
current->opcode = E_GOTO;
|
||||
current->label = label;
|
||||
}
|
||||
|
||||
void emit_conditional_jump(Op condition, int label, ...) {
|
||||
// when this instruction is a conditional jump then the imput looks like (Op, int, TNodeOrConst *).
|
||||
// when the inst is a cond with a Relational operation then the input looks like (Op, int, TNodeOrConst *, TNodeOrConst *)
|
||||
emit_helper();
|
||||
va_list argptr;
|
||||
va_start(argptr, label);
|
||||
current->opcode = condition;
|
||||
current->label = label;
|
||||
TNodeOrConst* n1;
|
||||
TNodeOrConst* n2;
|
||||
switch (condition) {
|
||||
case E_IF_X_TRUE:
|
||||
case E_IF_X_FALSE:
|
||||
n1 = va_arg(argptr, TNodeOrConst*);
|
||||
current->operand1 = n1;
|
||||
break;
|
||||
case E_LESS_THAN:
|
||||
case E_EQUAL_TO:
|
||||
n1 = va_arg(argptr, TNodeOrConst*);
|
||||
n2 = va_arg(argptr, TNodeOrConst*);
|
||||
current->operand1 = n1;
|
||||
current->operand2 = n2;
|
||||
break;
|
||||
}
|
||||
va_end(argptr);
|
||||
}
|
||||
|
||||
void emit_function_start(TNodeOrConst * name) {
|
||||
emit_helper();
|
||||
current->opcode = E_LABEL; // I think this is right TODO: ask
|
||||
current->operand1 = name;
|
||||
// this is probabaly a func declaration
|
||||
}
|
||||
|
||||
void emit_parameter(TNodeOrConst* param) {
|
||||
emit_helper();
|
||||
current->opcode = E_PARAM;
|
||||
current->operand1 = param;
|
||||
}
|
||||
|
||||
void emit_function_call(TableNode* result, int param_count, TNodeOrConst* name) {
|
||||
emit_helper();
|
||||
current->opcode = E_CALL;
|
||||
current->operand1 = tn_or_const(INTEGER, ¶m_count);
|
||||
current->operand2 = name;
|
||||
current->result = result;
|
||||
}
|
||||
|
||||
void emit_return(TNodeOrConst* value) {
|
||||
emit_helper();
|
||||
current->opcode = E_RETURN;
|
||||
current->operand1 = value;
|
||||
}
|
||||
|
||||
void emit_reserve(TableNode* result, TNodeOrConst* size) {
|
||||
emit_parameter(size);
|
||||
emit_function_call(result, 1, tn_or_const(NODE, look_up(cur, "reserve")));
|
||||
}
|
||||
|
||||
void emit_release(TableNode* pointer) {
|
||||
emit_parameter(tn_or_const(NODE, pointer));
|
||||
emit_function_call(pointer, 1, tn_or_const(NODE, look_up(cur, "release")));
|
||||
}
|
||||
|
||||
void emit_deref_right() {
|
||||
return;
|
||||
}
|
||||
|
||||
void emit_deref_left() {
|
||||
return;
|
||||
}
|
||||
|
||||
void emit_field_access(char* result, char* record, char* field) {
|
||||
emit_helper();
|
||||
}
|
||||
|
||||
void emit_array_access(Op op, TableNode* result, TNodeOrConst* array, TNodeOrConst* index) {
|
||||
emit_helper();
|
||||
current->opcode;
|
||||
current->result = result;
|
||||
current->operand1 = array;
|
||||
current->operand2 = index;
|
||||
// TODO: Still don't know what to do with the dimentions
|
||||
}
|
||||
|
||||
void emit_bounds_check(TNodeOrConst* index, TNodeOrConst* arr) {
|
||||
/*
|
||||
{[string: 5]
|
||||
.
|
||||
.
|
||||
s:= reserve s(5);
|
||||
s(0) := 'H';
|
||||
s(1) := 'e';
|
||||
.
|
||||
.
|
||||
s._0 num of dims Known at compile time
|
||||
s._1 size Known at run time
|
||||
s._1 int | 1 byte
|
||||
+-------+---+---+---+---+---+
|
||||
| 5 | H | e | l | l | o |
|
||||
+-------+---+---+---+---+---+
|
||||
size
|
||||
^
|
||||
|
|
||||
p
|
||||
s._0 ok
|
||||
s._1 ok
|
||||
s._2 not ok
|
||||
t_0 is index
|
||||
t_1 = *(int *)p = s._1
|
||||
if t_0 < 0 GOTO ERROR
|
||||
if t_0 < s._1 GOTO access array
|
||||
GOTO ERROR
|
||||
*/
|
||||
//emit_conditional_jump(E_LESS_THAN, );
|
||||
//emit_conditional_jump(E_LESS_THAN, );
|
||||
//emit_jump();
|
||||
/* We need a label ERROR to jump to
|
||||
*/
|
||||
}
|
||||
|
||||
/*// * Implement temp variable generator function that produces unique names (t1, t2, etc.)
|
||||
char * temp_var_gen(){
|
||||
char * ret = calloc(9, sizeof(*ret));
|
||||
sprintf(ret, "$t%d", temp_count);
|
||||
temp_count++;
|
||||
return ret;
|
||||
}
|
||||
*/
|
||||
int label_gen(){
|
||||
label_count++;
|
||||
return label_count;
|
||||
}
|
||||
|
||||
TableNode* getTN(TNodeOrConst* tnc) {
|
||||
if (tnc->d == NODE) {
|
||||
return tnc->tnc_union->node;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int getConst(TNodeOrConst* tnc) {
|
||||
if (tnc->d == INTEGER) {
|
||||
return tnc->tnc_union->integer;
|
||||
}
|
||||
return -1;
|
||||
}
|
124
src/intermediate_code.h
Normal file
124
src/intermediate_code.h
Normal file
@ -0,0 +1,124 @@
|
||||
/* Intermediate Code */
|
||||
/* The Translators - Spring 2025 */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "symbol_table.h"
|
||||
|
||||
// these are from page 364
|
||||
typedef enum {
|
||||
E_LABEL = 10000, // this is not in the book
|
||||
E_ADD, // 1 from the list
|
||||
E_SUB, // 1
|
||||
E_MUL, // 1
|
||||
E_DIV, // 1
|
||||
E_MOD, // 1
|
||||
E_OR, // 1
|
||||
E_AND, // 1
|
||||
E_NEG, // 2
|
||||
E_NOT, // 2
|
||||
E_ASSIGN, // 3
|
||||
E_GOTO, // 4
|
||||
E_COND_GOTO, // 5 I don't thik I need this because we could just follow the < or the = and just assume that it's a cond got
|
||||
E_IF_X_TRUE, // 5
|
||||
E_IF_X_FALSE, // 5
|
||||
E_LESS_THAN, // 6 rule 1 + 5
|
||||
E_EQUAL_TO, // 6 rule 1 + 5
|
||||
E_CALL, // 7
|
||||
E_PARAM, // 7
|
||||
E_RETURN, // 7
|
||||
E_INDEX_COPY_RIGHT, // 8 this is x = y[i]
|
||||
E_INDEX_COPY_LEFT, // 8 x[i] = y
|
||||
E_ADDRESS_OF, // 9 x = &y
|
||||
E_DEREF_RIGHT, // 9 x = *y
|
||||
E_DEREF_LEFT // 9 x* = y
|
||||
} Op;
|
||||
|
||||
typedef enum {
|
||||
NODE = 11000, // TableNode
|
||||
INTEGER, // int
|
||||
STRING, // char *
|
||||
CHARACTER, // char
|
||||
ADDRESS, // void *
|
||||
BOOLEAN // bool
|
||||
} Discriminant;
|
||||
|
||||
typedef union {
|
||||
TableNode* node;
|
||||
int integer;
|
||||
char* string;
|
||||
char character;
|
||||
void* address;
|
||||
bool Boolean;
|
||||
} TNConstUnion;
|
||||
|
||||
typedef struct {
|
||||
Discriminant d;
|
||||
TNConstUnion* tnc_union;
|
||||
} TNodeOrConst;
|
||||
|
||||
typedef struct Instruction Instruction;
|
||||
typedef struct Instruction {
|
||||
Op opcode;
|
||||
TableNode* result;
|
||||
TNodeOrConst* operand1;
|
||||
TNodeOrConst* operand2;
|
||||
int label;
|
||||
int index;
|
||||
|
||||
Instruction* prev;
|
||||
Instruction* next;
|
||||
} Instruction;
|
||||
|
||||
typedef struct TFList {
|
||||
Instruction* i;
|
||||
TFList* next;
|
||||
} TFList;
|
||||
|
||||
TNodeOrConst* getOperand1(Instruction* i);
|
||||
TNodeOrConst* getOperand2(Instruction* i);
|
||||
TableNode* getResult(Instruction* i);
|
||||
Op getOp(Instruction* i);
|
||||
int getLabel(Instruction* i);
|
||||
int get_index(Instruction* i);
|
||||
void set_label(Instruction* i, int label);
|
||||
bool isConst(TNodeOrConst* tnc);
|
||||
TNodeOrConst* tn_or_const(Discriminant d, void* tnc);
|
||||
static void emit_helper(void);
|
||||
void emit_binary_op(Op op, TableNode* result, TNodeOrConst* arg1, TNodeOrConst* arg2);
|
||||
void emit_unary_op(Op op, TableNode* result, TNodeOrConst* arg);
|
||||
void emit_assignment(TableNode* target, TNodeOrConst* source);
|
||||
char* get_string(TNodeOrConst* tc);
|
||||
void emit_as_file(FILE* out_file, Instruction* i);
|
||||
void emit_label(int label);
|
||||
void emit_jump(int label);
|
||||
void emit_conditional_jump(Op condition, int label, ...);
|
||||
void emit_function_start(TNodeOrConst * name);
|
||||
void emit_parameter(TNodeOrConst* param);
|
||||
void emit_function_call(TableNode* result, int param_count, TNodeOrConst* name);
|
||||
void emit_return(TNodeOrConst* value);
|
||||
void emit_reserve(TableNode* result, TNodeOrConst* size);
|
||||
void emit_release(TableNode* pointer);
|
||||
void emit_deref_right();
|
||||
void emit_deref_left();
|
||||
void emit_field_access(char* result, char* record, char* field);
|
||||
void emit_array_access(Op op, TableNode* result, TNodeOrConst* array, TNodeOrConst* index);
|
||||
void emit_bounds_check(TNodeOrConst* index, TNodeOrConst* arr);
|
||||
int label_gen();
|
||||
TableNode* getTN(TNodeOrConst* tnc);
|
||||
int getConst(TNodeOrConst* tnc);
|
||||
|
||||
extern int label_count;
|
||||
extern Instruction* begin;
|
||||
extern Instruction* current;
|
||||
|
||||
extern int offset;
|
||||
extern int currentsp;
|
||||
extern CGNode* cgList;
|
34
src/lexicalStructure.h
Normal file
34
src/lexicalStructure.h
Normal file
@ -0,0 +1,34 @@
|
||||
/* Lexical Analyzer with Flex (1.6.0) */
|
||||
/* The Translators - Spring 2025 */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../src/symbol_table.h"
|
||||
#include "../tmp/grammar.tab.h"
|
||||
|
||||
extern SymbolTable *cur;
|
||||
extern FILE *tok_flag;
|
||||
extern TableNode *funprime;
|
||||
extern TableNode *funtypeprime;
|
||||
extern TableNode *arrayprim;
|
||||
extern TableNode *recprime;
|
||||
extern TableNode *integ;
|
||||
extern TableNode *addr;
|
||||
extern TableNode *chara;
|
||||
extern TableNode *stri;
|
||||
extern TableNode *boo;
|
||||
extern TableNode *undefined;
|
||||
extern void incr(int lnum, int cnum, int tok);
|
||||
extern void print_tok(int tok);
|
||||
|
||||
int line_number = 1;
|
||||
int 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; \
|
||||
}
|
@ -4,26 +4,9 @@
|
||||
%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 "../src/lexicalStructure.h"
|
||||
%}
|
||||
|
||||
STARCOM [^\*]|\*+[^\)\*]+
|
||||
@ -36,63 +19,63 @@ SCHAR \\n|\\t|\\\"|[^\"\n\\]
|
||||
|
||||
%%
|
||||
|
||||
"integer" {if(DEBUG) {printf( "T_INTEGER: %s (%d)\n", yytext, T_INTEGER);} else {if(tok_flag != NULL){print_tok(T_INTEGER);}incr(line_number,column_number,T_INTEGER);yylval.words = strdup(yytext);return T_INTEGER;}}
|
||||
"address" {if(DEBUG) {printf( "T_ADDRESS: %s (%d)\n", yytext, T_ADDRESS);} else {if(tok_flag != NULL){print_tok(T_ADDRESS);}incr(line_number,column_number,T_ADDRESS);yylval.words = strdup(yytext);return T_ADDRESS;}}
|
||||
"Boolean" {if(DEBUG) {printf( "T_BOOLEAN: %s (%d)\n", yytext, T_BOOLEAN);} else {if(tok_flag != NULL){print_tok(T_INTEGER);}incr(line_number,column_number,T_INTEGER);yylval.words = strdup(yytext);return T_BOOLEAN;}}
|
||||
"character" {if(DEBUG) {printf( "T_CHARACTER: %s (%d)\n", yytext, T_CHARACTER);} else {if(tok_flag != NULL){print_tok(T_CHARACTER);}incr(line_number,column_number,T_CHARACTER);yylval.words = strdup(yytext);return T_CHARACTER;}}
|
||||
"integer" { if(tok_flag != NULL) {print_tok(T_INTEGER);} incr(line_number,column_number,T_INTEGER); yylval.tn = integ; return T_INTEGER; }
|
||||
"address" { if(tok_flag != NULL) {print_tok(T_ADDRESS);} incr(line_number,column_number,T_ADDRESS); yylval.tn = addr; return T_ADDRESS; }
|
||||
"Boolean" { if(tok_flag != NULL) {print_tok(T_INTEGER);} incr(line_number,column_number,T_INTEGER); yylval.tn = boo; return T_BOOLEAN; }
|
||||
"character" { if(tok_flag != NULL) {print_tok(T_CHARACTER);} incr(line_number,column_number,T_CHARACTER); yylval.tn = chara; return T_CHARACTER; }
|
||||
|
||||
"while" {if(DEBUG) {printf( "WHILE: %s (%d)\n", yytext, WHILE);} else {if(tok_flag != NULL){print_tok(WHILE);}incr(line_number,column_number,WHILE);return WHILE;}}
|
||||
"if" {if(DEBUG) {printf( "IF: %s (%d)\n", yytext, IF);} else {if(tok_flag != NULL){print_tok(IF);}incr(line_number,column_number,IF);return IF;}}
|
||||
"then" {if(DEBUG) {printf( "THEN: %s (%d)\n", yytext, THEN);} else {if(tok_flag != NULL){print_tok(THEN);}incr(line_number,column_number,THEN);return THEN;}}
|
||||
"else" {if(DEBUG) {printf( "ELSE: %s (%d)\n", yytext, ELSE);} else {if(tok_flag != NULL){print_tok(ELSE);}incr(line_number,column_number,ELSE);return ELSE;}}
|
||||
"type" {if(DEBUG) {printf( "TYPE: %s (%d)\n", yytext, TYPE);} else {if(tok_flag != NULL){print_tok(TYPE);}incr(line_number,column_number,TYPE);return TYPE;}}
|
||||
"function" {if(DEBUG) {printf( "FUNCTION: %s (%d)\n", yytext, FUNCTION);} else {if(tok_flag != NULL){print_tok(FUNCTION);}incr(line_number,column_number,FUNCTION);return FUNCTION;}}
|
||||
"return" {if(DEBUG) {printf( "RETURN: %s (%d)\n", yytext, RETURN);} else {if(tok_flag != NULL){print_tok(RETURN);}incr(line_number,column_number,RETURN);return RETURN;}}
|
||||
"external" {if(DEBUG) {printf( "EXTERNAL: %s (%d)\n", yytext, EXTERNAL);} else {if(tok_flag != NULL){print_tok(EXTERNAL);}incr(line_number,column_number,EXTERNAL);return EXTERNAL;}}
|
||||
"as" {if(DEBUG) {printf( "AS: %s (%d)\n", yytext, AS);} else {if(tok_flag != NULL){print_tok(AS);}incr(line_number,column_number,AS);return AS;}}
|
||||
"while" { if(tok_flag != NULL) {print_tok(WHILE);} incr(line_number,column_number,WHILE); return WHILE; }
|
||||
"if" { if(tok_flag != NULL) {print_tok(IF);} incr(line_number,column_number,IF); return IF; }
|
||||
"then" { if(tok_flag != NULL) {print_tok(THEN);} incr(line_number,column_number,THEN); return THEN; }
|
||||
"else" { if(tok_flag != NULL) {print_tok(ELSE);} incr(line_number,column_number,ELSE); return ELSE; }
|
||||
"type" { if(tok_flag != NULL) {print_tok(TYPE);} incr(line_number,column_number,TYPE); return TYPE; }
|
||||
"function" { if(tok_flag != NULL) {print_tok(FUNCTION);} incr(line_number,column_number,FUNCTION); return FUNCTION; }
|
||||
"return" { if(tok_flag != NULL) {print_tok(RETURN);} incr(line_number,column_number,RETURN); return RETURN; }
|
||||
"external" { if(tok_flag != NULL) {print_tok(EXTERNAL);} incr(line_number,column_number,EXTERNAL); return EXTERNAL; }
|
||||
"as" { if(tok_flag != NULL) {print_tok(AS);} incr(line_number,column_number,AS); return AS; }
|
||||
|
||||
"release" {if(DEBUG) {printf( "RELEASE: %s (%d)\n", yytext, RELEASE);} else {if(tok_flag != NULL){print_tok(RELEASE);}incr(line_number,column_number,RELEASE);return RELEASE;}}
|
||||
"reserve" {if(DEBUG) {printf( "RESERVE: %s (%d)\n", yytext, RESERVE);} else {if(tok_flag != NULL){print_tok(RESERVE);}incr(line_number,column_number,RESERVE);return RESERVE;}}
|
||||
"release" { if(tok_flag != NULL) {print_tok(RELEASE);} incr(line_number,column_number,RELEASE); return RELEASE; }
|
||||
"reserve" { if(tok_flag != NULL) {print_tok(RESERVE);} incr(line_number,column_number,RESERVE); return RESERVE; }
|
||||
|
||||
"+" {if(DEBUG) {printf( "ADD: %s (%d)\n", yytext, ADD);} else {if(tok_flag != NULL){print_tok(ADD);}incr(line_number,column_number,ADD);return ADD;}}
|
||||
"-" {if(DEBUG) {printf( "SUB_OR_NEG: %s (%d)\n", yytext, SUB_OR_NEG);} else {if(tok_flag != NULL){print_tok(SUB_OR_NEG);}incr(line_number,column_number,SUB_OR_NEG);return SUB_OR_NEG;}}
|
||||
"*" {if(DEBUG) {printf( "MUL: %s (%d)\n", yytext, MUL);} else {if(tok_flag != NULL){print_tok(MUL);}incr(line_number,column_number,MUL);return MUL;}}
|
||||
"/" {if(DEBUG) {printf( "DIV: %s (%d)\n", yytext, DIV);} else {if(tok_flag != NULL){print_tok(DIV);}incr(line_number,column_number,DIV);return DIV;}}
|
||||
"%" {if(DEBUG) {printf( "REM: %s (%d)\n", yytext, REM);} else {if(tok_flag != NULL){print_tok(REM);}incr(line_number,column_number,REM);return REM;}}
|
||||
"<" {if(DEBUG) {printf( "LESS_THAN: %s (%d)\n", yytext, LESS_THAN);} else {if(tok_flag != NULL){print_tok(LESS_THAN);}incr(line_number,column_number,LESS_THAN);return LESS_THAN;}}
|
||||
"=" {if(DEBUG) {printf( "EQUAL_TO: %s (%d)\n", yytext, EQUAL_TO);} else {if(tok_flag != NULL){print_tok(EQUAL_TO);}incr(line_number,column_number,EQUAL_TO);return EQUAL_TO;}}
|
||||
":=" {if(DEBUG) {printf( "ASSIGN: %s (%d)\n", yytext, ASSIGN);} else {if(tok_flag != NULL){print_tok(ASSIGN);}incr(line_number,column_number,ASSIGN);return ASSIGN;}}
|
||||
"!" {if(DEBUG) {printf( "NOT: %s (%d)\n", yytext, NOT);} else {if(tok_flag != NULL){print_tok(NOT);}incr(line_number,column_number,NOT);return NOT;}}
|
||||
"&" {if(DEBUG) {printf( "AND: %s (%d)\n", yytext, AND);} else {if(tok_flag != NULL){print_tok(AND);}incr(line_number,column_number,AND);return AND;}}
|
||||
"|" {if(DEBUG) {printf( "OR: %s (%d)\n", yytext, OR);} else {if(tok_flag != NULL){print_tok(OR);}incr(line_number,column_number,OR);return OR;}}
|
||||
"." {if(DEBUG) {printf( "DOT: %s (%d)\n", yytext, DOT);} else {if(tok_flag != NULL){print_tok(DOT);}incr(line_number,column_number,DOT);return DOT;}}
|
||||
"+" { if(tok_flag != NULL) {print_tok(ADD);} incr(line_number,column_number,ADD); return ADD; }
|
||||
"-" { if(tok_flag != NULL) {print_tok(SUB_OR_NEG);} incr(line_number,column_number,SUB_OR_NEG); return SUB_OR_NEG; }
|
||||
"*" { if(tok_flag != NULL) {print_tok(MUL);} incr(line_number,column_number,MUL); return MUL; }
|
||||
"/" { if(tok_flag != NULL) {print_tok(DIV);} incr(line_number,column_number,DIV); return DIV; }
|
||||
"%" { if(tok_flag != NULL) {print_tok(REM);} incr(line_number,column_number,REM); return REM; }
|
||||
"<" { if(tok_flag != NULL) {print_tok(LESS_THAN);} incr(line_number,column_number,LESS_THAN); return LESS_THAN; }
|
||||
"=" { if(tok_flag != NULL) {print_tok(EQUAL_TO);} incr(line_number,column_number,EQUAL_TO); return EQUAL_TO; }
|
||||
":=" { if(tok_flag != NULL) {print_tok(ASSIGN);} incr(line_number,column_number,ASSIGN); return ASSIGN; }
|
||||
"!" { if(tok_flag != NULL) {print_tok(NOT);} incr(line_number,column_number,NOT); return NOT; }
|
||||
"&" { if(tok_flag != NULL) {print_tok(AND);} incr(line_number,column_number,AND); return AND; }
|
||||
"|" { if(tok_flag != NULL) {print_tok(OR);} incr(line_number,column_number,OR); return OR; }
|
||||
"." { if(tok_flag != NULL) {print_tok(DOT);} incr(line_number,column_number,DOT); return DOT; }
|
||||
|
||||
";" {if(DEBUG) {printf( "SEMI_COLON: %s (%d)\n", yytext, SEMI_COLON);} else {if(tok_flag != NULL){print_tok(SEMI_COLON);}incr(line_number,column_number,SEMI_COLON);return SEMI_COLON;}}
|
||||
":" {if(DEBUG) {printf( "COLON: %s (%d)\n", yytext, COLON);} else {if(tok_flag != NULL){print_tok(COLON);}incr(line_number,column_number,COLON);return COLON;}}
|
||||
"," {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;}}
|
||||
";" { if(tok_flag != NULL) {print_tok(SEMI_COLON);} incr(line_number,column_number,SEMI_COLON); return SEMI_COLON; }
|
||||
":" { if(tok_flag != NULL) {print_tok(COLON);} incr(line_number,column_number,COLON); return COLON; }
|
||||
"," { if(tok_flag != NULL) {print_tok(COMMA);} incr(line_number,column_number,COMMA); return COMMA; }
|
||||
"->" { 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.integ = atoi(yytext);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);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);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;*/}}
|
||||
{DIGIT}+ {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(tok_flag != NULL){print_tok(C_CHARACTER);}incr(line_number,column_number,C_CHARACTER);char* token = strdup(yytext)/*yylval.tn = chara*/;yylval.letter = token[1];return C_CHARACTER;}
|
||||
\"{SCHAR}*\" {if(tok_flag != NULL){print_tok(C_STRING);}incr(line_number,column_number,C_STRING);int k = strlen(yytext);yytext[k-1] = '\0';yylval.words = strdup(&yytext[1]);return C_STRING;}
|
||||
{COMMENT} {if(tok_flag != NULL){print_tok(COMMENT);}incr(line_number,column_number,COMMENT);/*return COMMENT;*/}
|
||||
|
||||
"(" {if(DEBUG) {printf( "L_PAREN: %s (%d)\n", yytext, L_PAREN);} else {if(tok_flag != NULL){print_tok(L_PAREN);}incr(line_number,column_number,L_PAREN);return L_PAREN;}}
|
||||
")" {if(DEBUG) {printf( "R_PAREN: %s (%d)\n", yytext, R_PAREN);} else {if(tok_flag != NULL){print_tok(R_PAREN);}incr(line_number,column_number,R_PAREN);return R_PAREN;}}
|
||||
"[" {if(DEBUG) {printf( "L_BRACKET: %s (%d)\n", yytext, L_BRACKET);} else {if(tok_flag != NULL){print_tok(L_BRACKET);}incr(line_number,column_number,L_BRACKET);return L_BRACKET;}}
|
||||
"]" {if(DEBUG) {printf( "R_BRACKET: %s (%d)\n", yytext, R_BRACKET);} else {if(tok_flag != NULL){print_tok(R_BRACKET);}incr(line_number,column_number,R_BRACKET);return R_BRACKET;}}
|
||||
"{" {if(DEBUG) {printf( "L_BRACE: %s (%d)\n", yytext, L_BRACE);} else {if(tok_flag != NULL){print_tok(L_BRACE);}incr(line_number,column_number,L_BRACE);return L_BRACE;}}
|
||||
"}" {if(DEBUG) {printf( "R_BRACE: %s (%d)\n", yytext, R_BRACE);} else {if(tok_flag != NULL){print_tok(R_BRACE);}incr(line_number,column_number,R_BRACE);return R_BRACE;}}
|
||||
"(" { if(tok_flag != NULL) {print_tok(L_PAREN);} incr(line_number,column_number,L_PAREN); return L_PAREN; }
|
||||
")" { if(tok_flag != NULL) {print_tok(R_PAREN);} incr(line_number,column_number,R_PAREN); return R_PAREN; }
|
||||
"[" { if(tok_flag != NULL) {print_tok(L_BRACKET);} incr(line_number,column_number,L_BRACKET); return L_BRACKET; }
|
||||
"]" { if(tok_flag != NULL) {print_tok(R_BRACKET);} incr(line_number,column_number,R_BRACKET); return R_BRACKET; }
|
||||
"{" { if(tok_flag != NULL) {print_tok(L_BRACE);} incr(line_number,column_number,L_BRACE); return L_BRACE; }
|
||||
"}" { if(tok_flag != NULL) {print_tok(R_BRACE);} incr(line_number,column_number,R_BRACE); return R_BRACE; }
|
||||
|
||||
"true" {if(DEBUG) {printf( "C_TRUE: %s (%d)\n", yytext, C_TRUE);} else {if(tok_flag != NULL){print_tok(C_TRUE);}incr(line_number,column_number,C_TRUE);yylval.words = strdup(yytext);return C_TRUE;}}
|
||||
"false" {if(DEBUG) {printf( "C_FALSE: %s (%d)\n", yytext, C_FALSE);} else {if(tok_flag != NULL){print_tok(C_FALSE);}incr(line_number,column_number,C_FALSE);yylval.words = strdup(yytext);return C_FALSE;}}
|
||||
"null" {if(DEBUG) {printf( "C_NULL: %s (%d)\n", yytext, C_NULL);} else {if(tok_flag != NULL){print_tok(C_NULL);}incr(line_number,column_number,C_NULL);yylval.words = strdup(yytext);return C_NULL;}}
|
||||
"true" { if(tok_flag != NULL) {print_tok(C_TRUE);} incr(line_number,column_number,C_TRUE); yylval.tn = boo; return C_TRUE; }
|
||||
"false" { if(tok_flag != NULL) {print_tok(C_FALSE);} incr(line_number,column_number,C_FALSE); yylval.tn = boo; return C_FALSE; }
|
||||
"null" { if(tok_flag != NULL) {print_tok(C_NULL);} incr(line_number,column_number,C_NULL); yylval.tn = addr; return C_NULL; }
|
||||
|
||||
{ID} {if(DEBUG) {printf( "ID: %s (%d)\n", yytext, ID);} else {if(tok_flag != NULL){print_tok(ID);}incr(line_number,column_number,ID);yylval.words = strdup(yytext); return ID;}}
|
||||
{ID} { if(tok_flag != NULL) {print_tok(ID);} incr(line_number,column_number,ID); yylval.words = strdup(yytext); return ID; }
|
||||
|
||||
\n {yycolumn=1;incr(line_number,column_number,0);}
|
||||
\t {incr(line_number,column_number,0);}
|
||||
" " {incr(line_number,column_number,0);}
|
||||
. {incr(line_number,column_number,0);}
|
||||
\n { yycolumn = 1; incr(line_number,column_number,0); }
|
||||
\t { incr(line_number,column_number,0); }
|
||||
" " { incr(line_number,column_number,0); }
|
||||
. { incr(line_number,column_number,0); }
|
||||
|
||||
%%
|
||||
|
452
src/runner.c
452
src/runner.c
@ -4,203 +4,331 @@
|
||||
#include "runner.h"
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
if (argc == 1) {
|
||||
fprintf(stderr, INVALID);
|
||||
return -1;
|
||||
}
|
||||
if (argc == 1) {
|
||||
fprintf(stderr, INVALID);
|
||||
return -1;
|
||||
}
|
||||
|
||||
else if (argc == 2) {
|
||||
if (is_help(argv[1])) {
|
||||
return 0;
|
||||
} else if (is_alpha_file(argv[1], strlen(argv[1])) == 0) {
|
||||
no_flag = SET_FLAG;
|
||||
alpha_file = fopen(argv[1], "r");
|
||||
} else {
|
||||
fprintf(stderr, INVALID);
|
||||
return -1;
|
||||
}
|
||||
else if (argc == 2) {
|
||||
if (is_help(argv[1])) {
|
||||
return 0;
|
||||
} else if (is_alpha_file(argv[1], strlen(argv[1])) == 0) {
|
||||
no_flag = SET_FLAG;
|
||||
alpha_file = fopen(argv[1], "r");
|
||||
} else {
|
||||
fprintf(stderr, INVALID);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
else {
|
||||
if (is_alpha_file(argv[argc - 1], strlen(argv[argc - 1])) != 0) {
|
||||
fprintf(stderr, INVALID);
|
||||
return -1;
|
||||
} else {
|
||||
for (int i = 1; i < argc - 1; i++) {
|
||||
if (check_flag(argv[i], argv[argc - 1]) != 0) {
|
||||
fprintf(stderr, "INVALID FLAG(S): Use -help to view valid inputs \n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
alpha_file = fopen(argv[argc - 1], "r");
|
||||
else {
|
||||
if (is_alpha_file(argv[argc - 1], strlen(argv[argc - 1])) != 0) {
|
||||
fprintf(stderr, INVALID);
|
||||
return -1;
|
||||
} else {
|
||||
for (int i = 1; i < argc - 1; i++) {
|
||||
if (check_flag(argv[i], argv[argc - 1]) != 0) {
|
||||
fprintf(stderr, INVALID);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
alpha_file = fopen(argv[argc - 1], "r");
|
||||
}
|
||||
return run(alpha_file);
|
||||
}
|
||||
return run(alpha_file);
|
||||
}
|
||||
|
||||
int check_flag(char *arg, char *alpha) {
|
||||
if (strcmp("-tok", arg) == 0) {
|
||||
if (tok_flag == NULL) {
|
||||
return new_file(arg, alpha);
|
||||
}
|
||||
fprintf(stderr, "FLAGS REPEAT\n");
|
||||
return -1;
|
||||
} else if (strcmp("-st", arg) == 0) {
|
||||
if (st_flag == NULL) {
|
||||
return new_file(arg, alpha);
|
||||
}
|
||||
fprintf(stderr, "FLAGS REPEAT\n");
|
||||
return -1;
|
||||
} else {
|
||||
fprintf(stderr, "INVALID FLAG: Use -help for valid inputs\n");
|
||||
return -1;
|
||||
if (strcmp("-tok", arg) == 0) {
|
||||
if (tok_flag == NULL) {
|
||||
return new_file(arg, alpha);
|
||||
}
|
||||
}
|
||||
|
||||
void incr(int lnum,int cnum, int tok){
|
||||
//if (tok == COMMENT) {
|
||||
for (int i = 0; i < yyleng; i++) {
|
||||
if (yytext[i] == '\n') {
|
||||
line_number++;
|
||||
column_number = 0;
|
||||
}
|
||||
column_number++;
|
||||
}
|
||||
// }else{
|
||||
// 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 = CreateScope(NULL, 1, 1);
|
||||
|
||||
// If file is not found
|
||||
if (alpha == NULL) {
|
||||
fprintf(stderr, "INPUT FILE NOT FOUND\n");
|
||||
return -1;
|
||||
fprintf(stderr, "FLAGS REPEAT\n");
|
||||
return -1;
|
||||
} else if (strcmp("-st", arg) == 0) {
|
||||
if (st_flag == NULL) {
|
||||
return new_file(arg, alpha);
|
||||
}
|
||||
yyin = alpha;
|
||||
|
||||
// TOK FLAG
|
||||
if (tok_flag != NULL) {
|
||||
while (0 != (token = yylex())) {
|
||||
//if (tok_flag != NULL) {
|
||||
// fprintf(tok_flag, "%d %d %3d \"%s\"\n", line_number, column_number,
|
||||
// token, yytext);
|
||||
//}
|
||||
/*if (token == COMMENT) {
|
||||
for (int i = 0; i < yyleng; i++) {
|
||||
if (yytext[i] == '\n') {
|
||||
line_number++;
|
||||
column_number = 0;
|
||||
}
|
||||
column_number++;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (token == 1999) {
|
||||
printf(
|
||||
"On line number %d and column number %d we have an invalid "
|
||||
"character:%s\n",
|
||||
line_number, column_number, yytext);
|
||||
}
|
||||
column_number += yyleng; */
|
||||
}
|
||||
fclose(tok_flag);
|
||||
|
||||
if (yyin != NULL) {
|
||||
fclose(yyin);
|
||||
}
|
||||
return 0;
|
||||
fprintf(stderr, "FLAGS REPEAT\n");
|
||||
return -1;
|
||||
} else if (strcmp("-asc", arg) == 0) {
|
||||
if (asc_flag == NULL) {
|
||||
return new_file(arg, alpha);
|
||||
}
|
||||
|
||||
if (st_flag != NULL) {
|
||||
// output symbol table, file pointer is
|
||||
// print_symbol_table(top,st_flag);
|
||||
fprintf(stderr, "FLAGS REPEAT\n");
|
||||
return -1;
|
||||
} else if (strcmp("-tc", arg) == 0) {
|
||||
if (tc_flag == false) {
|
||||
tc_flag = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
yyparse();
|
||||
FILE *f = fdopen(1, "w");
|
||||
print_symbol_table(getAncestor(cur), f);
|
||||
fclose(f);
|
||||
|
||||
if (yyin != NULL) {
|
||||
fclose(yyin);
|
||||
fprintf(stderr, "FLAGS REPEAT\n");
|
||||
return -1;
|
||||
} else if (strcmp("-ir", arg) == 0) {
|
||||
if (ir_flag == NULL) {
|
||||
return new_file(arg, alpha);
|
||||
}
|
||||
|
||||
fprintf(stderr, "FLAGS REPEAT\n");
|
||||
return -1;
|
||||
} else if (strcmp("-cg", arg) == 0) {
|
||||
if (cg_flag == NULL) {
|
||||
return new_file(arg, alpha);
|
||||
}
|
||||
fprintf(stderr, "FLAGS REPEAT\n");
|
||||
return -1;
|
||||
} else if (strcmp("-debug", arg) == 0) {
|
||||
DEBUG = true;
|
||||
return 0;
|
||||
} else {
|
||||
fprintf(stderr, "INVALID FLAG: Use -help for valid inputs\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
void incr(int lnum, int cnum, int tok) {
|
||||
for (int i = 0; i < yyleng; i++) {
|
||||
if (yytext[i] == '\n') {
|
||||
line_number++;
|
||||
column_number = 0;
|
||||
}
|
||||
column_number++;
|
||||
}
|
||||
}
|
||||
|
||||
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));
|
||||
|
||||
// If file is not found
|
||||
if (alpha == NULL) {
|
||||
fprintf(stderr, "INPUT FILE NOT FOUND\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
char *line;
|
||||
int i = 1;
|
||||
while ((line = file_read_line(alpha)) != NULL) {
|
||||
CodeLine *code_line = malloc(sizeof(CodeLine));
|
||||
code_line->line_number = i;
|
||||
code_line->line = malloc(strlen(line) + 1);
|
||||
strcpy(code_line->line, line);
|
||||
code_line->next = NULL;
|
||||
code_line->is_error = false;
|
||||
append_code_line(code_line);
|
||||
free(line);
|
||||
i++;
|
||||
}
|
||||
|
||||
fseek(alpha, 0, SEEK_SET);
|
||||
|
||||
yyin = alpha;
|
||||
yyparse();
|
||||
|
||||
if (tok_flag != NULL) {
|
||||
while (0 != (token = yylex())) {
|
||||
// Don't delete me 🥺
|
||||
}
|
||||
fclose(tok_flag);
|
||||
}
|
||||
|
||||
if (st_flag != NULL) {
|
||||
printdebug("[-st] Symbol Table is enabled.");
|
||||
print_symbol_table(top, st_flag);
|
||||
fclose(st_flag);
|
||||
}
|
||||
|
||||
if (asc_flag != NULL) {
|
||||
printdebug("[-asc] Annotated Source Code is enabled.");
|
||||
print_code_lines();
|
||||
fclose(asc_flag);
|
||||
}
|
||||
|
||||
if (tc_flag != false) {
|
||||
printdebug("[-tc] Type checking is enabled.");
|
||||
}
|
||||
|
||||
if (ir_flag != NULL) {
|
||||
printdebug("[-ir] Intermediate code is enabled.");
|
||||
emit_as_file(ir_flag, begin);
|
||||
fclose(ir_flag);
|
||||
}
|
||||
|
||||
if (cg_flag != NULL) {
|
||||
printdebug("[-cg] Code generation is enabled.");
|
||||
generate();
|
||||
fclose(cg_flag);
|
||||
}
|
||||
|
||||
if (yyin != NULL) {
|
||||
fclose(yyin);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool is_help(char *input) {
|
||||
if (strcmp(input, "-help") == 0) {
|
||||
printf("%s", HELP);
|
||||
return true;
|
||||
}
|
||||
if (strcmp(input, "-help") == 0) {
|
||||
printf("%s", HELP);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
int new_file(char *arg, char *alpha) {
|
||||
int type_len;
|
||||
const char *basename = alpha;
|
||||
const char *slash = strchr(alpha, '/');
|
||||
int type_len;
|
||||
const char *basename = alpha;
|
||||
const char *slash = strchr(alpha, '/');
|
||||
|
||||
while (slash != NULL) {
|
||||
basename = slash + 1;
|
||||
slash = strchr(basename, '/');
|
||||
}
|
||||
while (slash != NULL) {
|
||||
basename = slash + 1;
|
||||
slash = strchr(basename, '/');
|
||||
}
|
||||
|
||||
mkdir("./out", 0777);
|
||||
mkdir("./out", 0777);
|
||||
|
||||
char *new_basename = calloc(strlen(basename) + 5, sizeof(char));
|
||||
strcpy(new_basename, "./out/");
|
||||
strcat(new_basename, basename);
|
||||
basename = new_basename;
|
||||
char *new_basename = calloc(strlen(basename) + 5, sizeof(char));
|
||||
strcpy(new_basename, "./out/");
|
||||
strcat(new_basename, basename);
|
||||
basename = new_basename;
|
||||
|
||||
if (strcmp(arg, "-tok") == 0) {
|
||||
type_len = TOK_LEN;
|
||||
} else if (strcmp(arg, "-st") == 0) {
|
||||
type_len = ST_LEN;
|
||||
} else {
|
||||
fprintf(stderr, "INVALID FLAG: Use -help to view valid inputs\n");
|
||||
return -1;
|
||||
}
|
||||
if (strcmp(arg, "-tok") == 0) {
|
||||
type_len = TOK_LEN;
|
||||
} else if (strcmp(arg, "-st") == 0) {
|
||||
type_len = ST_LEN;
|
||||
} else if (strcmp(arg, "-asc") == 0) {
|
||||
type_len = ASC_LEN;
|
||||
} else if (strcmp(arg, "-ir") == 0) {
|
||||
type_len = IR_LEN;
|
||||
} else if (strcmp(arg, "-cg") == 0) {
|
||||
type_len = CG_LEN;
|
||||
} else {
|
||||
fprintf(stderr, INVALID);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// calculate lengths
|
||||
int basename_len = strlen(basename);
|
||||
char *file_name =
|
||||
calloc(basename_len - ALPHA_OFFSET + type_len + 2, sizeof(char));
|
||||
// calculate lengths
|
||||
int basename_len = strlen(basename);
|
||||
char *file_name = calloc(basename_len - ALPHA_OFFSET + type_len + 2, sizeof(char));
|
||||
|
||||
// coy filename and add extension
|
||||
// coy filename and add extension
|
||||
if (strcmp(arg, "-cg") == 0) {
|
||||
strncpy(file_name, basename, basename_len - ALPHA_OFFSET);
|
||||
strcat(file_name, ".s");
|
||||
} else {
|
||||
strncpy(file_name, basename, basename_len - ALPHA_OFFSET);
|
||||
strcat(file_name, ".");
|
||||
strcat(file_name, arg + 1);
|
||||
}
|
||||
|
||||
if (strcmp(arg, "-tok") == 0) {
|
||||
tok_flag = fopen(file_name, "w");
|
||||
} else if (strcmp(arg, "-st") == 0) {
|
||||
st_flag = fopen(file_name, "w");
|
||||
}
|
||||
return 0;
|
||||
if (strcmp(arg, "-tok") == 0) {
|
||||
tok_flag = fopen(file_name, "w");
|
||||
} else if (strcmp(arg, "-st") == 0) {
|
||||
st_flag = fopen(file_name, "w");
|
||||
} else if (strcmp(arg, "-asc") == 0) {
|
||||
asc_flag = fopen(file_name, "w");
|
||||
} else if (strcmp(arg, "-ir") == 0) {
|
||||
ir_flag = fopen(file_name, "w");
|
||||
} else if (strcmp(arg, "-cg") == 0) {
|
||||
cg_flag = fopen(file_name, "w");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int is_alpha_file(char *alpha, int file_len) {
|
||||
if (strcmp(".alpha", alpha + sizeof(char) * (file_len - ALPHA_OFFSET)) != 0) {
|
||||
return -1; // not alpha file
|
||||
}
|
||||
return 0; // is alpha file
|
||||
if (strcmp(".alpha",
|
||||
alpha + sizeof(char) * (file_len - ALPHA_OFFSET)) != 0) {
|
||||
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;
|
||||
void insert_code_line(char * error_message, int line_number) {
|
||||
CodeLine *error_line = malloc(sizeof(CodeLine));
|
||||
error_line->line_number = line_number;
|
||||
error_line->line = malloc(strlen(error_message) + 1);
|
||||
strcpy(error_line->line, error_message);
|
||||
error_line->next = NULL;
|
||||
error_line->is_error = true;
|
||||
|
||||
if (error_line == NULL || code_head == NULL) return;
|
||||
|
||||
int line = error_line->line_number;
|
||||
CodeLine *current = code_head;
|
||||
while (current != NULL) {
|
||||
if (current->line_number == line) {
|
||||
CodeLine *next_code_line = current->next;
|
||||
current->next = error_line;
|
||||
error_line->next = next_code_line;
|
||||
}
|
||||
cur = cur->Parent_Scope;
|
||||
current = current->next;
|
||||
}
|
||||
}
|
||||
|
||||
void append_code_line(CodeLine *code_line) {
|
||||
if (code_line == NULL) return;
|
||||
|
||||
if (code_head == NULL) {
|
||||
code_head = code_line;
|
||||
} else {
|
||||
CodeLine *current = code_head;
|
||||
while (current->next != NULL) {
|
||||
current = current->next;
|
||||
}
|
||||
current->next = code_line;
|
||||
}
|
||||
}
|
||||
|
||||
void print_code_lines() {
|
||||
if (code_head == NULL) {
|
||||
printf("No code lines to print.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
CodeLine *current = code_head;
|
||||
while (current != NULL) {
|
||||
if (current->is_error) {
|
||||
fprintf(asc_flag, "%s", current->line);
|
||||
} else {
|
||||
fprintf(asc_flag, "%03d: %s", current->line_number, current->line);
|
||||
}
|
||||
current = current->next;
|
||||
}
|
||||
}
|
||||
|
||||
char *file_read_line(FILE *fp) {
|
||||
if (fp == NULL) return NULL;
|
||||
|
||||
size_t size = 128;
|
||||
size_t len = 0;
|
||||
char *str = malloc(size);
|
||||
if (!str) return NULL;
|
||||
|
||||
int c;
|
||||
while ((c = fgetc(fp)) != EOF) {
|
||||
if (len + 1 >= size) {
|
||||
size *= 2;
|
||||
char *new_buffer = realloc(str, size);
|
||||
if (!new_buffer) {
|
||||
free(str);
|
||||
return NULL;
|
||||
}
|
||||
str = new_buffer;
|
||||
}
|
||||
|
||||
str[len++] = (char)c;
|
||||
if (c == '\n') break;
|
||||
}
|
||||
|
||||
if (len == 0 && c == EOF) {
|
||||
free(str);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
str[len] = '\0';
|
||||
return str;
|
||||
}
|
101
src/runner.h
101
src/runner.h
@ -1,18 +1,31 @@
|
||||
/* Runner File - Compiles alpha Compiler */
|
||||
/* The Translators - Spring 2025 */
|
||||
|
||||
#pragma once
|
||||
|
||||
#define ALPHA_OFFSET 6
|
||||
#define TOK_LEN 3
|
||||
#define ST_LEN 2
|
||||
#define HELP \
|
||||
"HELP:\nHow to run the alpha compiler:\n./alpha [options] program\nValid " \
|
||||
"options:\n-tok output the token number, token, line number, and column " \
|
||||
"number for each of the tokens to the .tok file\n-st output the symbol " \
|
||||
"table for the program to the .st file\n-help print this message and exit " \
|
||||
"the alpha compiler\n"
|
||||
#define SET_FLAG 1 // Used to set flags for arg types
|
||||
#define ASC_LEN 3
|
||||
#define IR_LEN 2
|
||||
#define CG_LEN 1
|
||||
#define HELP \
|
||||
"HELP:\n" \
|
||||
" How to run the alpha compiler:\n" \
|
||||
" ./alpha [options] program\n" \
|
||||
"Valid options:\n" \
|
||||
" -tok output the token number, token, line number, and column number for each of the tokens to the .tok file\n" \
|
||||
" -st output the symbol table for the program to the .st file\n" \
|
||||
" -asc output the annotated source code for the program to the .asc file, including syntax errors\n" \
|
||||
" -tc run the type checker and report type errors to the .asc file\n" \
|
||||
" -ir run the intermediate representation generator, writing output to the .ir file\n" \
|
||||
" -cg run the (x86 assembly) code generator, writing output to the .s file\n" \
|
||||
" -debug produce debugging messages to stderr\n" \
|
||||
" -help print this message and exit the alpha compiler\n"
|
||||
|
||||
#define SET_FLAG 1 // Used to set flags for arg types
|
||||
#define INVALID \
|
||||
"INVALID INPUT: Include a .alpha file or use -help for more inputs \n"
|
||||
"INVALID INPUT: Include a .alpha file or use -help for more inputs \n"
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
@ -21,32 +34,78 @@
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "../tmp/flex.h"
|
||||
#include "symbol_table.h"
|
||||
//#include "typedefs.h"
|
||||
#include "../tmp/grammar.tab.h"
|
||||
#include "codegen.h"
|
||||
#include "intermediate_code.h"
|
||||
#include "symbol_table.h"
|
||||
|
||||
extern int line_number, column_number;
|
||||
extern int line_number;
|
||||
extern int 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;
|
||||
FILE *asc_flag = NULL;
|
||||
FILE *ir_flag = NULL;
|
||||
FILE *cg_flag = NULL;
|
||||
bool tc_flag = false;
|
||||
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;
|
||||
extern Instruction *begin;
|
||||
|
||||
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";
|
||||
|
||||
typedef struct CodeLine {
|
||||
char *line;
|
||||
int line_number;
|
||||
bool is_error;
|
||||
struct CodeLine *next;
|
||||
} CodeLine;
|
||||
|
||||
CodeLine *code_head;
|
||||
|
||||
char *file_read_line(FILE *fp);
|
||||
void insert_code_line(char * error_message, int line_number);
|
||||
void append_code_line(CodeLine *code_line);
|
||||
void print_code_lines();
|
1691
src/symbol_table.c
1691
src/symbol_table.c
File diff suppressed because it is too large
Load Diff
@ -1,42 +1,194 @@
|
||||
/* Symbol Table */
|
||||
/* The Translators - Spring 2025 */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#define SIZE_INT 4
|
||||
#define SIZE_ADDR 8
|
||||
#define SIZE_CHAR 1
|
||||
#define SIZE_BOOL 1
|
||||
|
||||
struct TableNode;
|
||||
typedef struct TFList TFList;
|
||||
typedef struct CGNode CGNode;
|
||||
|
||||
typedef struct Constant_Stack {
|
||||
struct TableNode *theType;
|
||||
void *theValue;
|
||||
struct Constant_Stack *next;
|
||||
bool isConst;
|
||||
} Constant_Stack;
|
||||
|
||||
typedef struct {
|
||||
int size;
|
||||
} primitive_info;
|
||||
|
||||
typedef struct {
|
||||
int numofdimensions;
|
||||
struct TableNode *typeofarray;
|
||||
} array_info;
|
||||
|
||||
typedef struct {
|
||||
int numofelements;
|
||||
struct SymbolTable *recordScope;
|
||||
int total_size;
|
||||
int *offsets;
|
||||
} record_info;
|
||||
|
||||
typedef struct {
|
||||
int startlinenumber;
|
||||
bool regularoras;
|
||||
} function_declaration_info;
|
||||
|
||||
typedef struct {
|
||||
struct TableNode *parameter;
|
||||
struct TableNode *returntype;
|
||||
} function_type_info;
|
||||
|
||||
typedef union {
|
||||
primitive_info *PrimAdInfo;
|
||||
array_info *ArrayAdInfo;
|
||||
record_info *RecAdInfo;
|
||||
function_declaration_info *FunDecAdInfo;
|
||||
function_type_info *FunTypeAdInfo;
|
||||
} AdInfo;
|
||||
|
||||
typedef struct ListOfTable {
|
||||
struct SymbolTable* table;
|
||||
// struct ListOfTable* prev;
|
||||
struct ListOfTable* next;
|
||||
struct SymbolTable *table;
|
||||
struct ListOfTable *next;
|
||||
} ListOfTable;
|
||||
|
||||
typedef struct TableNode {
|
||||
char* theType;
|
||||
char* theName;
|
||||
struct TableNode* next;
|
||||
struct TableNode *theType;
|
||||
int tag;
|
||||
char *theName;
|
||||
AdInfo *additionalinfo;
|
||||
struct TableNode *next;
|
||||
} TableNode;
|
||||
|
||||
typedef struct SymbolTable {
|
||||
TableNode* entries;
|
||||
struct SymbolTable* Parent_Scope;
|
||||
struct ListOfTable* Children_Scope;
|
||||
int Line_Number;
|
||||
int Column_Number;
|
||||
TableNode *entries;
|
||||
struct SymbolTable *Parent_Scope;
|
||||
struct ListOfTable *Children_Scope;
|
||||
int Line_Number;
|
||||
int Column_Number;
|
||||
} SymbolTable;
|
||||
|
||||
SymbolTable* CreateScope(SymbolTable* ParentScope, int Line, int Column);
|
||||
TableNode* CreateEntry(SymbolTable* table, char* typeOf, char* id);
|
||||
TableNode* table_lookup(SymbolTable* table, char* x);
|
||||
TableNode* look_up(SymbolTable* table, char* x);
|
||||
void print_symbol_table(SymbolTable* table, FILE* file_ptr);
|
||||
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,
|
||||
TYPE_SYSTEM_DEFINED = 11,
|
||||
TYPE_PRIMITIVE_TYPE = 12
|
||||
} types;
|
||||
|
||||
SymbolTable* getAncestor(SymbolTable* table);
|
||||
SymbolTable* getParent(SymbolTable* st);
|
||||
ListOfTable* getChildren(SymbolTable* st);
|
||||
SymbolTable* getFirstChild(ListOfTable* lt);
|
||||
ListOfTable* getRestOfChildren(ListOfTable* lt);
|
||||
TableNode* getFirstEntry(SymbolTable* st);
|
||||
TableNode* getNextEntry(TableNode* tn);
|
||||
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__)
|
||||
|
||||
char *temp_var_gen();
|
||||
Constant_Stack *Push(TableNode *type, void *value, bool isConst);
|
||||
Constant_Stack *Pop();
|
||||
Constant_Stack *Print_Stack();
|
||||
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 getRecTotal(TableNode *node);
|
||||
TableNode *setRecOffsetInfo(SymbolTable *scope, TableNode *node);
|
||||
int *getRecOffsets(TableNode *node);
|
||||
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);
|
||||
AdInfo *getAdInfo(TableNode *tn);
|
||||
int getAdInfoType(TableNode *tn);
|
||||
TableNode *CreateEntry(SymbolTable *table, int tag, TableNode *typeOf, char *id, AdInfo *ad);
|
||||
TableNode *getTypeEntry(TableNode *tn);
|
||||
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 printline(FILE *file_ptr, bool b);
|
||||
void st_fprint(FILE *file_ptr, char *label1, int label2, int label3, char *label4, char *label5);
|
||||
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);
|
||||
TableNode *printTableNode(TableNode *tn);
|
||||
|
||||
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 int temp2_count;
|
||||
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 Constant_Stack *head;
|
||||
|
||||
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;
|
@ -1,3 +1,6 @@
|
||||
/* Type Definitions */
|
||||
/* The Translators - Spring 2025 */
|
||||
|
||||
// identifier
|
||||
#define ID 101
|
||||
// type names
|
||||
|
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 -debug "$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 -debug "$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 -debug "$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 -cg "$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 -debug "$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 -debug "$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 -debug "$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 -debug "$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 -cg -debug "$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
|
10
tests/carl/Errors/entry.undeclaredType.alpha
Normal file
10
tests/carl/Errors/entry.undeclaredType.alpha
Normal file
@ -0,0 +1,10 @@
|
||||
type M : string -> integer
|
||||
|
||||
function foo : M
|
||||
|
||||
foo (s) := {
|
||||
[
|
||||
int: x
|
||||
]
|
||||
return 0;
|
||||
}
|
16
tests/carl/Errors/entry.undeclaredType.alpha.asc
Normal file
16
tests/carl/Errors/entry.undeclaredType.alpha.asc
Normal file
@ -0,0 +1,16 @@
|
||||
alpha parser, version 0.2 (2023-03-04) - Annotated Source Code for file entry.undeclaredType.alpha
|
||||
001: type M : string -> integer
|
||||
002:
|
||||
003: function foo : M
|
||||
004:
|
||||
005: foo (s) := {
|
||||
006: [
|
||||
007: int: x
|
||||
^0 ^1
|
||||
LINE 7:9 ** ERROR #0: the name 'int', used here as a type, has not been declared at this point in the program.
|
||||
LINE 7:14 ** ERROR #1: the name 'x' is being declared with an unknown type.
|
||||
|
||||
008: ]
|
||||
009: return 0;
|
||||
010: }
|
||||
011:
|
7
tests/carl/Errors/entry.undeclaredVar.alpha
Normal file
7
tests/carl/Errors/entry.undeclaredVar.alpha
Normal file
@ -0,0 +1,7 @@
|
||||
type M : string -> integer
|
||||
|
||||
function entry : M
|
||||
|
||||
entry(s) := {
|
||||
return x;
|
||||
}
|
12
tests/carl/Errors/entry.undeclaredVar.alpha.asc
Normal file
12
tests/carl/Errors/entry.undeclaredVar.alpha.asc
Normal file
@ -0,0 +1,12 @@
|
||||
alpha parser, version 0.2 (2023-03-04) - Annotated Source Code for file entry.undeclaredVar.alpha
|
||||
001: type M : string -> integer
|
||||
002:
|
||||
003: function entry : M
|
||||
004:
|
||||
005: entry(s) := {
|
||||
006: return x;
|
||||
^0
|
||||
LINE 6:12 ** ERROR #0: the name 'x', used here as a variable name, has not been declared at this point in the program.
|
||||
|
||||
007: }
|
||||
008:
|
14
tests/carl/Errors/error.operator.alpha
Normal file
14
tests/carl/Errors/error.operator.alpha
Normal file
@ -0,0 +1,14 @@
|
||||
type string2int: string -> integer
|
||||
|
||||
function entry : string2int
|
||||
|
||||
entry(arg) := {
|
||||
[ integer: i; integer: sum ]
|
||||
sum := 0;
|
||||
i := 0;
|
||||
while (i < 10) {
|
||||
sum = sum + i;
|
||||
i := i + 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
19
tests/carl/Errors/error.operator.alpha.asc
Normal file
19
tests/carl/Errors/error.operator.alpha.asc
Normal file
@ -0,0 +1,19 @@
|
||||
alpha parser, version 0.2 (2023-03-04) - Annotated Source Code for file error.operator.alpha
|
||||
001: type string2int: string -> integer
|
||||
002:
|
||||
003: function entry : string2int
|
||||
004:
|
||||
005: entry(arg) := {
|
||||
006: [ integer: i; integer: sum ]
|
||||
007: sum := 0;
|
||||
008: i := 0;
|
||||
009: while (i < 10) {
|
||||
010: sum = sum + i;
|
||||
^0
|
||||
LINE 10:13 ** ERROR #0: assignment operator (:=) expected but equality operator (=) found.
|
||||
|
||||
011: i := i + 1;
|
||||
012: }
|
||||
013: return 0;
|
||||
014: }
|
||||
015:
|
8
tests/carl/NoErrors/entry.definition.alpha
Normal file
8
tests/carl/NoErrors/entry.definition.alpha
Normal file
@ -0,0 +1,8 @@
|
||||
(* type string : 1 -> character *)
|
||||
type M : string -> integer
|
||||
|
||||
function entry : M
|
||||
|
||||
entry(s) := {
|
||||
return 0;
|
||||
}
|
10
tests/carl/NoErrors/entry.definition.alpha.asc
Normal file
10
tests/carl/NoErrors/entry.definition.alpha.asc
Normal file
@ -0,0 +1,10 @@
|
||||
alpha parser, version 0.2 (2023-03-04) - Annotated Source Code for file entry.definition.alpha
|
||||
001: (* type string : 1 -> character *)
|
||||
002: type M : string -> integer
|
||||
003:
|
||||
004: function entry : M
|
||||
005:
|
||||
006: entry(s) := {
|
||||
007: return 0;
|
||||
008: }
|
||||
009:
|
11
tests/carl/NoErrors/entry.duplicateDifferent.alpha
Normal file
11
tests/carl/NoErrors/entry.duplicateDifferent.alpha
Normal file
@ -0,0 +1,11 @@
|
||||
type M : string -> integer
|
||||
|
||||
function entry : M
|
||||
|
||||
entry(s) := {
|
||||
[
|
||||
integer: x;
|
||||
character: x
|
||||
]
|
||||
return x;
|
||||
}
|
13
tests/carl/NoErrors/entry.duplicateDifferent.alpha.asc
Normal file
13
tests/carl/NoErrors/entry.duplicateDifferent.alpha.asc
Normal file
@ -0,0 +1,13 @@
|
||||
alpha parser, version 0.2 (2023-03-04) - Annotated Source Code for file entry.duplicateDifferent.alpha
|
||||
001: type M : string -> integer
|
||||
002:
|
||||
003: function entry : M
|
||||
004:
|
||||
005: entry(s) := {
|
||||
006: [
|
||||
007: integer: x;
|
||||
008: character: x
|
||||
009: ]
|
||||
010: return x;
|
||||
011: }
|
||||
012:
|
9
tests/carl/NoErrors/entry.duplicateSame.alpha
Normal file
9
tests/carl/NoErrors/entry.duplicateSame.alpha
Normal file
@ -0,0 +1,9 @@
|
||||
type M : string -> integer
|
||||
function entry : M
|
||||
|
||||
entry(s) := {
|
||||
[
|
||||
integer: x; integer: x
|
||||
]
|
||||
return x;
|
||||
}
|
11
tests/carl/NoErrors/entry.duplicateSame.alpha.asc
Normal file
11
tests/carl/NoErrors/entry.duplicateSame.alpha.asc
Normal file
@ -0,0 +1,11 @@
|
||||
alpha parser, version 0.2 (2023-03-04) - Annotated Source Code for file entry.duplicateSame.alpha
|
||||
001: type M : string -> integer
|
||||
002: function entry : M
|
||||
003:
|
||||
004: entry(s) := {
|
||||
005: [
|
||||
006: integer: x; integer: x
|
||||
007: ]
|
||||
008: return x;
|
||||
009: }
|
||||
010:
|
11
tests/carl/NoErrors/entry.local.alpha
Normal file
11
tests/carl/NoErrors/entry.local.alpha
Normal file
@ -0,0 +1,11 @@
|
||||
type M : string -> integer
|
||||
|
||||
function entry : M
|
||||
|
||||
entry(s) := {
|
||||
[
|
||||
integer: x
|
||||
]
|
||||
x := 0;
|
||||
return x;
|
||||
}
|
13
tests/carl/NoErrors/entry.local.alpha.asc
Normal file
13
tests/carl/NoErrors/entry.local.alpha.asc
Normal file
@ -0,0 +1,13 @@
|
||||
alpha parser, version 0.2 (2023-03-04) - Annotated Source Code for file entry.local.alpha
|
||||
001: type M : string -> integer
|
||||
002:
|
||||
003: function entry : M
|
||||
004:
|
||||
005: entry(s) := {
|
||||
006: [
|
||||
007: integer: x
|
||||
008: ]
|
||||
009: x := 0;
|
||||
010: return x;
|
||||
011: }
|
||||
012:
|
14
tests/carl/NoErrors/error.none.alpha
Normal file
14
tests/carl/NoErrors/error.none.alpha
Normal file
@ -0,0 +1,14 @@
|
||||
type string2int: string -> integer
|
||||
|
||||
function entry : string2int
|
||||
|
||||
entry(arg) := {
|
||||
[ integer: i ; integer: sum ]
|
||||
sum := 0;
|
||||
i := 0 ;
|
||||
while (i < 10) {
|
||||
sum := sum + i;
|
||||
i := i + 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
16
tests/carl/NoErrors/error.none.alpha.asc
Normal file
16
tests/carl/NoErrors/error.none.alpha.asc
Normal file
@ -0,0 +1,16 @@
|
||||
alpha parser, version 0.2 (2023-03-04) - Annotated Source Code for file error.none.alpha
|
||||
001: type string2int: string -> integer
|
||||
002:
|
||||
003: function entry : string2int
|
||||
004:
|
||||
005: entry(arg) := {
|
||||
006: [ integer: i ; integer: sum ]
|
||||
007: sum := 0;
|
||||
008: i := 0 ;
|
||||
009: while (i < 10) {
|
||||
010: sum := sum + i;
|
||||
011: i := i + 1;
|
||||
012: }
|
||||
013: return 0;
|
||||
014: }
|
||||
015:
|
3
tests/carl/NoErrors/function.declaration.alpha
Normal file
3
tests/carl/NoErrors/function.declaration.alpha
Normal file
@ -0,0 +1,3 @@
|
||||
type M : integer -> integer
|
||||
|
||||
function f : M
|
5
tests/carl/NoErrors/function.declaration.alpha.asc
Normal file
5
tests/carl/NoErrors/function.declaration.alpha.asc
Normal file
@ -0,0 +1,5 @@
|
||||
alpha parser, version 0.2 (2023-03-04) - Annotated Source Code for file function.declaration.alpha
|
||||
001: type M : integer -> integer
|
||||
002:
|
||||
003: function f : M
|
||||
004:
|
7
tests/carl/NoErrors/function.definition.alpha
Normal file
7
tests/carl/NoErrors/function.definition.alpha
Normal file
@ -0,0 +1,7 @@
|
||||
type M : integer -> integer
|
||||
|
||||
function f : M
|
||||
|
||||
f(x) := {
|
||||
return x;
|
||||
}
|
9
tests/carl/NoErrors/function.definition.alpha.asc
Normal file
9
tests/carl/NoErrors/function.definition.alpha.asc
Normal file
@ -0,0 +1,9 @@
|
||||
alpha parser, version 0.2 (2023-03-04) - Annotated Source Code for file function.definition.alpha
|
||||
001: type M : integer -> integer
|
||||
002:
|
||||
003: function f : M
|
||||
004:
|
||||
005: f(x) := {
|
||||
006: return x;
|
||||
007: }
|
||||
008:
|
73
tests/carl/NoErrors/functionValue.alpha
Normal file
73
tests/carl/NoErrors/functionValue.alpha
Normal file
@ -0,0 +1,73 @@
|
||||
(* Type definitions *)
|
||||
|
||||
(* mapping type *)
|
||||
type string2int: string -> integer
|
||||
|
||||
(* array of functions *)
|
||||
type funArray: 1 -> string2int
|
||||
|
||||
(* record of functions *)
|
||||
type funRec: [ string2int: f; string2int: g ]
|
||||
|
||||
(* function returning function *)
|
||||
type integer_2_string2int: integer -> string2int
|
||||
|
||||
(* function returning function *)
|
||||
type string2int_2_integer: string2int -> integer
|
||||
|
||||
|
||||
type iXiXc: [integer: a; integer: b; character: c]
|
||||
|
||||
type iic2b: iXiXc -> Boolean
|
||||
|
||||
(* Function declarations using the above type definitions *)
|
||||
function a: string2int
|
||||
function b: integer_2_string2int
|
||||
function c: string2int_2_integer
|
||||
|
||||
function d: iic2b
|
||||
|
||||
d(x,y,z) := {
|
||||
return (x < y & z < 'm');
|
||||
}
|
||||
|
||||
function entry: string2int
|
||||
|
||||
a(x) := {
|
||||
[string : s]
|
||||
s := x;
|
||||
return 0;
|
||||
}
|
||||
|
||||
b(x) := {
|
||||
[integer: i]
|
||||
i := x;
|
||||
return a;
|
||||
}
|
||||
|
||||
c(x) := {
|
||||
[string: s]
|
||||
s := "Hi!";
|
||||
return x(s);
|
||||
}
|
||||
|
||||
|
||||
(* Function definition
|
||||
entry is the first function called
|
||||
*)
|
||||
entry(arg) := {
|
||||
[integer: result; string2int: f; integer: temp]
|
||||
temp := a("Hello");
|
||||
f := b(temp);
|
||||
result := c(f);
|
||||
if (d(1,2,'c'))
|
||||
then {
|
||||
result := 0;
|
||||
}
|
||||
else {
|
||||
[ Boolean : b]
|
||||
result := entry("hello");
|
||||
}
|
||||
result := c(f);
|
||||
return result;
|
||||
}
|
75
tests/carl/NoErrors/functionValue.alpha.asc
Normal file
75
tests/carl/NoErrors/functionValue.alpha.asc
Normal file
@ -0,0 +1,75 @@
|
||||
alpha parser, version 0.2 (2023-03-04) - Annotated Source Code for file functionValue.alpha
|
||||
001: (* Type definitions *)
|
||||
002:
|
||||
003: (* mapping type *)
|
||||
004: type string2int: string -> integer
|
||||
005:
|
||||
006: (* array of functions *)
|
||||
007: type funArray: 1 -> string2int
|
||||
008:
|
||||
009: (* record of functions *)
|
||||
010: type funRec: [ string2int: f; string2int: g ]
|
||||
011:
|
||||
012: (* function returning function *)
|
||||
013: type integer_2_string2int: integer -> string2int
|
||||
014:
|
||||
015: (* function returning function *)
|
||||
016: type string2int_2_integer: string2int -> integer
|
||||
017:
|
||||
018:
|
||||
019: type iXiXc: [integer: a; integer: b; character: c]
|
||||
020:
|
||||
021: type iic2b: iXiXc -> Boolean
|
||||
022:
|
||||
023: (* Function declarations using the above type definitions *)
|
||||
024: function a: string2int
|
||||
025: function b: integer_2_string2int
|
||||
026: function c: string2int_2_integer
|
||||
027:
|
||||
028: function d: iic2b
|
||||
029:
|
||||
030: d(x,y,z) := {
|
||||
031: return (x < y & z < 'm');
|
||||
032: }
|
||||
033:
|
||||
034: function entry: string2int
|
||||
035:
|
||||
036: a(x) := {
|
||||
037: [string : s]
|
||||
038: s := x;
|
||||
039: return 0;
|
||||
040: }
|
||||
041:
|
||||
042: b(x) := {
|
||||
043: [integer: i]
|
||||
044: i := x;
|
||||
045: return a;
|
||||
046: }
|
||||
047:
|
||||
048: c(x) := {
|
||||
049: [string: s]
|
||||
050: s := "Hi!";
|
||||
051: return x(s);
|
||||
052: }
|
||||
053:
|
||||
054:
|
||||
055: (* Function definition
|
||||
056: entry is the first function called
|
||||
057: *)
|
||||
058: entry(arg) := {
|
||||
059: [integer: result; string2int: f; integer: temp]
|
||||
060: temp := a("Hello");
|
||||
061: f := b(temp);
|
||||
062: result := c(f);
|
||||
063: if (d(1,2,'c'))
|
||||
064: then {
|
||||
065: result := 0;
|
||||
066: }
|
||||
067: else {
|
||||
068: [ Boolean : b]
|
||||
069: result := entry("hello");
|
||||
070: }
|
||||
071: result := c(f);
|
||||
072: return result;
|
||||
073: }
|
||||
074:
|
29
tests/carl/NoErrors/sample.good.alpha
Normal file
29
tests/carl/NoErrors/sample.good.alpha
Normal file
@ -0,0 +1,29 @@
|
||||
|
||||
(* Type definitions *)
|
||||
type int2int: integer -> integer
|
||||
type string2int: string -> integer
|
||||
|
||||
(* Function declarations
|
||||
They use the above type definitions
|
||||
*)
|
||||
function square : int2int
|
||||
function entry : string2int
|
||||
|
||||
(* Function definition
|
||||
Functions must be declared before they are defined
|
||||
*)
|
||||
square(x) := {
|
||||
return x * x;
|
||||
}
|
||||
|
||||
(* Function definition
|
||||
entry is the first function called
|
||||
*)
|
||||
entry(arg) := {
|
||||
[ integer: input ; integer: expected ; integer: actual ; Boolean: result ]
|
||||
input := 7;
|
||||
expected := 49;
|
||||
actual := square(input);
|
||||
result := expected = actual;
|
||||
return 0;
|
||||
}
|
31
tests/carl/NoErrors/sample.good.alpha.asc
Normal file
31
tests/carl/NoErrors/sample.good.alpha.asc
Normal file
@ -0,0 +1,31 @@
|
||||
alpha parser, version 0.2 (2023-03-04) - Annotated Source Code for file sample.good.alpha
|
||||
001:
|
||||
001: (* Type definitions *)
|
||||
003: type int2int: integer -> integer
|
||||
004: type string2int: string -> integer
|
||||
005:
|
||||
006: (* Function declarations
|
||||
007: They use the above type definitions
|
||||
008: *)
|
||||
009: function square : int2int
|
||||
010: function entry : string2int
|
||||
011:
|
||||
012: (* Function definition
|
||||
013: Functions must be declared before they are defined
|
||||
014: *)
|
||||
015: square(x) := {
|
||||
016: return x * x;
|
||||
017: }
|
||||
018:
|
||||
019: (* Function definition
|
||||
020: entry is the first function called
|
||||
021: *)
|
||||
022: entry(arg) := {
|
||||
023: [ integer: input ; integer: expected ; integer: actual ; Boolean: result ]
|
||||
024: input := 7;
|
||||
025: expected := 49;
|
||||
026: actual := square(input);
|
||||
027: result := expected = actual;
|
||||
028: return 0;
|
||||
029: }
|
||||
030:
|
68
tests/carl/NoErrors/selectionSort.alpha
Normal file
68
tests/carl/NoErrors/selectionSort.alpha
Normal file
@ -0,0 +1,68 @@
|
||||
(* Type definitions *)
|
||||
|
||||
type string2int: string -> integer
|
||||
type intArray: 1 -> integer
|
||||
type intArrayXinteger: [ intArray: data; integer: index ]
|
||||
type intArrayXinteger2integer: intArrayXinteger -> integer
|
||||
type intArray2Boolean: intArray -> Boolean
|
||||
|
||||
|
||||
(* Function declarations
|
||||
They use the above type definitions
|
||||
*)
|
||||
function indexOfSmallest: intArrayXinteger2integer
|
||||
function selectionSort: intArray2Boolean
|
||||
function entry : string2int
|
||||
|
||||
(* indexOfSmallest *)
|
||||
indexOfSmallest (* as *) (data, startingIndex) := {
|
||||
[ integer: indexOfSmallestSoFar; integer: i ]
|
||||
indexOfSmallestSoFar := startingIndex;
|
||||
i := 0 ;
|
||||
while (i < data._1 ) {
|
||||
if ( data(i) < data(indexOfSmallestSoFar) )
|
||||
then {
|
||||
indexOfSmallestSoFar := i;
|
||||
}
|
||||
else {
|
||||
i := i;
|
||||
}
|
||||
i := i + 1;
|
||||
}
|
||||
return indexOfSmallestSoFar;
|
||||
}
|
||||
|
||||
|
||||
(* selectionSort *)
|
||||
selectionSort(data) := {
|
||||
[ integer: i ]
|
||||
i := 0 ;
|
||||
while (i < data._1 ) {
|
||||
[ integer: index; integer: temp ]
|
||||
index := indexOfSmallest(data,i);
|
||||
temp := data(index);
|
||||
data(index) := data(i);
|
||||
data(i) := temp;
|
||||
i := i + 1;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
(* Function definition
|
||||
entry is the first function called
|
||||
*)
|
||||
entry(arg) := {
|
||||
[ intArray: data; Boolean: _ ]
|
||||
data := reserve data(8);
|
||||
data(0) := 60;
|
||||
data(1) := 80;
|
||||
data(2) := 10;
|
||||
data(3) := 50;
|
||||
data(4) := 30;
|
||||
data(5) := 40;
|
||||
data(6) := 20;
|
||||
data(7) := 70;
|
||||
_ := selectionSort(data);
|
||||
return 0;
|
||||
}
|
70
tests/carl/NoErrors/selectionSort.alpha.asc
Normal file
70
tests/carl/NoErrors/selectionSort.alpha.asc
Normal file
@ -0,0 +1,70 @@
|
||||
alpha parser, version 0.2 (2023-03-04) - Annotated Source Code for file selectionSort.alpha
|
||||
001: (* Type definitions *)
|
||||
002:
|
||||
003: type string2int: string -> integer
|
||||
004: type intArray: 1 -> integer
|
||||
005: type intArrayXinteger: [ intArray: data; integer: index ]
|
||||
006: type intArrayXinteger2integer: intArrayXinteger -> integer
|
||||
007: type intArray2Boolean: intArray -> Boolean
|
||||
008:
|
||||
009:
|
||||
010: (* Function declarations
|
||||
011: They use the above type definitions
|
||||
012: *)
|
||||
013: function indexOfSmallest: intArrayXinteger2integer
|
||||
014: function selectionSort: intArray2Boolean
|
||||
015: function entry : string2int
|
||||
016:
|
||||
017: (* indexOfSmallest *)
|
||||
018: indexOfSmallest (* as *) (data, startingIndex) := {
|
||||
019: [ integer: indexOfSmallestSoFar; integer: i ]
|
||||
020: indexOfSmallestSoFar := startingIndex;
|
||||
021: i := 0 ;
|
||||
022: while (i < data._1 ) {
|
||||
023: if ( data(i) < data(indexOfSmallestSoFar) )
|
||||
024: then {
|
||||
025: indexOfSmallestSoFar := i;
|
||||
026: }
|
||||
027: else {
|
||||
028: i := i;
|
||||
029: }
|
||||
030: i := i + 1;
|
||||
031: }
|
||||
032: return indexOfSmallestSoFar;
|
||||
033: }
|
||||
034:
|
||||
035:
|
||||
036: (* selectionSort *)
|
||||
037: selectionSort(data) := {
|
||||
038: [ integer: i ]
|
||||
039: i := 0 ;
|
||||
040: while (i < data._1 ) {
|
||||
041: [ integer: index; integer: temp ]
|
||||
042: index := indexOfSmallest(data,i);
|
||||
043: temp := data(index);
|
||||
044: data(index) := data(i);
|
||||
045: data(i) := temp;
|
||||
046: i := i + 1;
|
||||
047: }
|
||||
048: return true;
|
||||
049: }
|
||||
050:
|
||||
051:
|
||||
052: (* Function definition
|
||||
053: entry is the first function called
|
||||
054: *)
|
||||
055: entry(arg) := {
|
||||
056: [ intArray: data; Boolean: _ ]
|
||||
057: data := reserve data(8);
|
||||
058: data(0) := 60;
|
||||
059: data(1) := 80;
|
||||
060: data(2) := 10;
|
||||
061: data(3) := 50;
|
||||
062: data(4) := 30;
|
||||
063: data(5) := 40;
|
||||
064: data(6) := 20;
|
||||
065: data(7) := 70;
|
||||
066: _ := selectionSort(data);
|
||||
067: return 0;
|
||||
068: }
|
||||
069:
|
1
tests/carl/NoErrors/type.array.alpha
Normal file
1
tests/carl/NoErrors/type.array.alpha
Normal file
@ -0,0 +1 @@
|
||||
type A : 1 -> integer
|
3
tests/carl/NoErrors/type.array.alpha.asc
Normal file
3
tests/carl/NoErrors/type.array.alpha.asc
Normal file
@ -0,0 +1,3 @@
|
||||
alpha parser, version 0.2 (2023-03-04) - Annotated Source Code for file type.array.alpha
|
||||
001: type A : 1 -> integer
|
||||
002:
|
2
tests/carl/NoErrors/type.mapping.alpha
Normal file
2
tests/carl/NoErrors/type.mapping.alpha
Normal file
@ -0,0 +1,2 @@
|
||||
type M : integer -> character
|
||||
|
4
tests/carl/NoErrors/type.mapping.alpha.asc
Normal file
4
tests/carl/NoErrors/type.mapping.alpha.asc
Normal file
@ -0,0 +1,4 @@
|
||||
alpha parser, version 0.2 (2023-03-04) - Annotated Source Code for file type.mapping.alpha
|
||||
001: type M : integer -> character
|
||||
002:
|
||||
003:
|
1
tests/carl/NoErrors/type.record.alpha
Normal file
1
tests/carl/NoErrors/type.record.alpha
Normal file
@ -0,0 +1 @@
|
||||
type R : [ integer : i ; character : c ]
|
3
tests/carl/NoErrors/type.record.alpha.asc
Normal file
3
tests/carl/NoErrors/type.record.alpha.asc
Normal file
@ -0,0 +1,3 @@
|
||||
alpha parser, version 0.2 (2023-03-04) - Annotated Source Code for file type.record.alpha
|
||||
001: type R : [ integer : i ; character : c ]
|
||||
002:
|
75
tests/carl/NoErrors/types.alpha
Normal file
75
tests/carl/NoErrors/types.alpha
Normal file
@ -0,0 +1,75 @@
|
||||
(*
|
||||
|
||||
At compiler start-up your program should
|
||||
create symbol table entries for the following
|
||||
built-in types:
|
||||
|
||||
Boolean (1 byte)
|
||||
character (1 byte)
|
||||
integer (4 bytes)
|
||||
address (8 bytes)
|
||||
|
||||
and the following privileged type (it has literals):
|
||||
|
||||
type string: 1 -> character
|
||||
|
||||
Your compiler can define other types during
|
||||
its start-up routine as well, if it is helpful
|
||||
to do so.
|
||||
|
||||
*)
|
||||
|
||||
|
||||
|
||||
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
|
||||
|
||||
type character2integer: character -> integer
|
||||
type Boolean2integer: Boolean -> integer
|
||||
type string2integer: string -> integer
|
||||
|
||||
type integerXinteger2integer: integerXinteger -> integer
|
||||
|
||||
type integerXinteger2Boolean: integerXinteger -> Boolean
|
||||
type characterXcharacter2Boolean: characterXcharacter -> Boolean
|
||||
type BooleanXBoolean2Boolean: BooleanXBoolean -> Boolean
|
||||
|
||||
|
||||
type integer2address: integer -> address
|
||||
type address2integer: address -> integer
|
||||
|
||||
|
||||
(* The alpha library functions
|
||||
You will be provided with x86-64 assembly
|
||||
code implementations of these.
|
||||
*)
|
||||
|
||||
external function printInteger: integer2integer
|
||||
external function printCharacter: character2integer
|
||||
external function printBoolean: Boolean2integer
|
||||
|
||||
(*
|
||||
A declaration of the entry point function for your program
|
||||
|
||||
You may assume that when starting this function will behave as if
|
||||
it had been called from the C language main function like this:
|
||||
|
||||
int main(int argc, char * argv[]) {
|
||||
if (argc == 1) {
|
||||
return entry(NULL);
|
||||
}
|
||||
else {
|
||||
return entry(makeAlphaString(argv[1]));
|
||||
}
|
||||
}
|
||||
|
||||
for some suitable definition of makeAlphaString which creates
|
||||
an alpha string representation of its argument C string in memory
|
||||
and returns a pointer to that alpha string.
|
||||
*)
|
||||
|
||||
function entry: string2integer
|
77
tests/carl/NoErrors/types.alpha.asc
Normal file
77
tests/carl/NoErrors/types.alpha.asc
Normal file
@ -0,0 +1,77 @@
|
||||
alpha parser, version 0.2 (2023-03-04) - Annotated Source Code for file types.alpha
|
||||
001: (*
|
||||
001:
|
||||
002: At compiler start-up your program should
|
||||
003: create symbol table entries for the following
|
||||
004: built-in types:
|
||||
005:
|
||||
006: Boolean (1 byte)
|
||||
007: character (1 byte)
|
||||
008: integer (4 bytes)
|
||||
009: address (8 bytes)
|
||||
010:
|
||||
011: and the following privileged type (it has literals):
|
||||
012:
|
||||
013: type string: 1 -> character
|
||||
014:
|
||||
015: Your compiler can define other types during
|
||||
016: its start-up routine as well, if it is helpful
|
||||
017: to do so.
|
||||
018:
|
||||
019: *)
|
||||
021:
|
||||
022:
|
||||
023:
|
||||
024: type BooleanXBoolean: [Boolean: x; Boolean: y]
|
||||
025: type characterXcharacter: [character: x; character: y]
|
||||
026: type integerXinteger: [integer: x; integer: y]
|
||||
027:
|
||||
028: type Boolean2Boolean: Boolean -> Boolean
|
||||
029: type integer2integer: integer -> integer
|
||||
030:
|
||||
031: type character2integer: character -> integer
|
||||
032: type Boolean2integer: Boolean -> integer
|
||||
033: type string2integer: string -> integer
|
||||
034:
|
||||
035: type integerXinteger2integer: integerXinteger -> integer
|
||||
036:
|
||||
037: type integerXinteger2Boolean: integerXinteger -> Boolean
|
||||
038: type characterXcharacter2Boolean: characterXcharacter -> Boolean
|
||||
039: type BooleanXBoolean2Boolean: BooleanXBoolean -> Boolean
|
||||
040:
|
||||
041:
|
||||
042: type integer2address: integer -> address
|
||||
043: type address2integer: address -> integer
|
||||
044:
|
||||
045:
|
||||
046: (* The alpha library functions
|
||||
047: You will be provided with x86-64 assembly
|
||||
048: code implementations of these.
|
||||
049: *)
|
||||
050:
|
||||
051: external function printInteger: integer2integer
|
||||
052: external function printCharacter: character2integer
|
||||
053: external function printBoolean: Boolean2integer
|
||||
054:
|
||||
055: (*
|
||||
056: A declaration of the entry point function for your program
|
||||
057:
|
||||
058: You may assume that when starting this function will behave as if
|
||||
059: it had been called from the C language main function like this:
|
||||
060:
|
||||
061: int main(int argc, char * argv[]) {
|
||||
062: if (argc == 1) {
|
||||
063: return entry(NULL);
|
||||
064: }
|
||||
065: else {
|
||||
066: return entry(makeAlphaString(argv[1]));
|
||||
067: }
|
||||
068: }
|
||||
069:
|
||||
070: for some suitable definition of makeAlphaString which creates
|
||||
071: an alpha string representation of its argument C string in memory
|
||||
072: and returns a pointer to that alpha string.
|
||||
073: *)
|
||||
074:
|
||||
075: function entry: string2integer
|
||||
076:
|
@ -1 +1 @@
|
||||
daskmskdfm
|
||||
1 1 700 "(***)"
|
||||
|
3
tests/sprint1/expected/sp1_comment_fix2.expected
Normal file
3
tests/sprint1/expected/sp1_comment_fix2.expected
Normal file
@ -0,0 +1,3 @@
|
||||
1 1 700 "(*(**)"
|
||||
1 7 603 "*"
|
||||
1 8 502 ")"
|
22
tests/sprint1/expected/sp1_comment_issues.expected
Normal file
22
tests/sprint1/expected/sp1_comment_issues.expected
Normal file
@ -0,0 +1,22 @@
|
||||
1 1 700 "(*(**)"
|
||||
1 7 603 "*"
|
||||
1 8 502 ")"
|
||||
2 1 700 "(***)"
|
||||
3 1 700 "(******)"
|
||||
3 9 700 "(*\kpp*********)"
|
||||
4 1 501 "("
|
||||
4 2 700 "(*((*)"
|
||||
4 8 502 ")"
|
||||
5 1 700 "(***)"
|
||||
5 6 700 "(*)
|
||||
(* *)"
|
||||
7 1 700 "(***)"
|
||||
7 6 502 ")"
|
||||
7 7 502 ")"
|
||||
7 8 502 ")"
|
||||
7 9 502 ")"
|
||||
7 10 502 ")"
|
||||
7 11 502 ")"
|
||||
7 12 603 "*"
|
||||
7 13 700 "(*))))))))*)"
|
||||
7 25 502 ")"
|
9
tests/sprint1/expected/sp1_comments.expected
Normal file
9
tests/sprint1/expected/sp1_comments.expected
Normal file
@ -0,0 +1,9 @@
|
||||
1 1 700 "(* hello *)"
|
||||
2 1 700 "(* hello *)"
|
||||
3 1 700 "(* I'd think this is a legal "string" that contains several \n \t
|
||||
escaped characters, isn't it? *)"
|
||||
5 1 700 "(* \ *)"
|
||||
6 1 700 "(* *)"
|
||||
7 1 700 "(*{COMMENT}+ *)"
|
||||
8 1 700 "(* * *)"
|
||||
9 1 700 "(* (hello) *)"
|
68
tests/sprint1/expected/sp1_general_token.expected
Normal file
68
tests/sprint1/expected/sp1_general_token.expected
Normal file
@ -0,0 +1,68 @@
|
||||
1 1 101 "This"
|
||||
1 6 101 "is"
|
||||
1 9 101 "a"
|
||||
1 11 101 "test"
|
||||
2 1 301 "9"
|
||||
2 2 101 "combined"
|
||||
2 11 301 "7"
|
||||
2 12 101 "okens"
|
||||
3 1 301 "12345"
|
||||
4 1 301 "893247892"
|
||||
5 1 101 "combined"
|
||||
5 10 101 "DueToUnknownChar"
|
||||
5 27 101 "_validtoken"
|
||||
5 39 101 "__validtoken1"
|
||||
5 53 101 "_valid_token2"
|
||||
5 67 101 "validToken3_"
|
||||
6 1 305 "true"
|
||||
6 6 306 "false"
|
||||
7 1 302 "null"
|
||||
7 6 401 "while"
|
||||
7 12 609 "!"
|
||||
7 13 101 "wrong"
|
||||
7 19 402 "if"
|
||||
7 22 101 "when"
|
||||
8 1 404 "else"
|
||||
8 6 405 "type"
|
||||
8 11 406 "function"
|
||||
9 1 407 "return"
|
||||
9 9 408 "external"
|
||||
9 25 409 "as"
|
||||
10 1 101 "string"
|
||||
10 8 101 "_NOte_that_was_not_reserved"
|
||||
11 1 501 "("
|
||||
11 2 503 "["
|
||||
11 3 502 ")"
|
||||
11 4 504 "]"
|
||||
11 5 505 "{"
|
||||
11 6 506 "}"
|
||||
11 7 508 ":"
|
||||
11 8 507 ";"
|
||||
11 9 509 ","
|
||||
11 10 510 "->"
|
||||
12 1 601 "+"
|
||||
12 2 602 "-"
|
||||
12 3 603 "*"
|
||||
12 4 604 "/"
|
||||
12 5 605 "%"
|
||||
13 1 606 "<"
|
||||
13 2 607 "="
|
||||
14 1 608 ":="
|
||||
15 2 101 "This"
|
||||
15 7 101 "is"
|
||||
15 10 101 "not"
|
||||
15 14 101 "a"
|
||||
15 16 101 "valid"
|
||||
16 1 101 "String"
|
||||
17 1 304 ""This is a valid String""
|
||||
18 1 609 "!"
|
||||
18 2 611 "|"
|
||||
19 1 612 "."
|
||||
19 2 612 "."
|
||||
20 1 700 "(* this is a comment *)"
|
||||
21 1 501 "("
|
||||
21 2 603 "*"
|
||||
21 3 101 "Not"
|
||||
21 7 101 "a"
|
||||
21 9 101 "comment"
|
||||
22 3 610 "&"
|
29
tests/sprint1/expected/sp1_keywords.expected
Normal file
29
tests/sprint1/expected/sp1_keywords.expected
Normal file
@ -0,0 +1,29 @@
|
||||
1 1 401 "while"
|
||||
2 1 101 "While"
|
||||
3 1 101 "whiLe"
|
||||
4 1 402 "if"
|
||||
5 1 101 "IF"
|
||||
6 1 101 "If"
|
||||
7 1 101 "iF"
|
||||
8 1 403 "then"
|
||||
9 1 101 "Then"
|
||||
10 1 101 "theN"
|
||||
11 1 404 "else"
|
||||
12 1 101 "eLse"
|
||||
13 1 101 "elSe"
|
||||
14 1 101 "Else"
|
||||
15 1 405 "type"
|
||||
16 1 101 "Type"
|
||||
17 1 101 "tyPe"
|
||||
18 1 406 "function"
|
||||
19 1 101 "Function"
|
||||
20 1 101 "functioN"
|
||||
21 1 407 "return"
|
||||
22 1 101 "Return"
|
||||
23 1 101 "returN"
|
||||
24 1 408 "external"
|
||||
25 1 101 "External"
|
||||
26 1 101 "exteRnal"
|
||||
27 1 409 "as"
|
||||
28 1 101 "As"
|
||||
29 1 101 "aS"
|
22
tests/sprint1/expected/sp1_operators.expected
Normal file
22
tests/sprint1/expected/sp1_operators.expected
Normal file
@ -0,0 +1,22 @@
|
||||
1 1 601 "+"
|
||||
2 1 602 "-"
|
||||
3 1 603 "*"
|
||||
4 1 604 "/"
|
||||
6 1 605 "%"
|
||||
7 1 606 "<"
|
||||
9 1 607 "="
|
||||
10 1 608 ":="
|
||||
11 1 607 "="
|
||||
11 2 508 ":"
|
||||
12 1 508 ":"
|
||||
13 1 607 "="
|
||||
14 1 609 "!"
|
||||
15 1 610 "&"
|
||||
16 1 611 "|"
|
||||
17 1 612 "."
|
||||
18 1 101 "relEASE"
|
||||
19 1 614 "release"
|
||||
20 1 101 "RELEASE"
|
||||
21 1 613 "reserve"
|
||||
22 1 101 "RESERVE"
|
||||
23 1 101 "reSERVe"
|
7
tests/sprint1/expected/sp1_other_punc.expected
Normal file
7
tests/sprint1/expected/sp1_other_punc.expected
Normal file
@ -0,0 +1,7 @@
|
||||
1 1 507 ";"
|
||||
2 1 508 ":"
|
||||
3 1 509 ","
|
||||
4 1 510 "->"
|
||||
5 1 510 "->"
|
||||
6 1 602 "-"
|
||||
6 2 510 "->"
|
59
tests/sprint1/expected/sp1_punc_grouping.expected
Normal file
59
tests/sprint1/expected/sp1_punc_grouping.expected
Normal file
@ -0,0 +1,59 @@
|
||||
1 1 502 ")"
|
||||
2 1 101 "a"
|
||||
2 2 502 ")"
|
||||
3 1 502 ")"
|
||||
3 2 101 "a"
|
||||
4 1 502 ")"
|
||||
4 2 603 "*"
|
||||
5 1 603 "*"
|
||||
5 2 502 ")"
|
||||
7 1 700 "(* jellsls
|
||||
well this seems to work
|
||||
|
||||
|
||||
*)"
|
||||
13 1 501 "("
|
||||
14 1 101 "a"
|
||||
14 2 501 "("
|
||||
15 1 501 "("
|
||||
15 2 101 "a"
|
||||
16 1 501 "("
|
||||
16 2 603 "*"
|
||||
17 1 603 "*"
|
||||
17 2 501 "("
|
||||
20 1 505 "{"
|
||||
21 1 101 "a"
|
||||
21 2 505 "{"
|
||||
22 1 505 "{"
|
||||
22 2 101 "a"
|
||||
23 1 505 "{"
|
||||
23 2 603 "*"
|
||||
24 1 603 "*"
|
||||
24 2 505 "{"
|
||||
25 1 506 "}"
|
||||
26 1 101 "a"
|
||||
26 2 506 "}"
|
||||
27 1 506 "}"
|
||||
27 2 101 "a"
|
||||
28 1 506 "}"
|
||||
28 2 603 "*"
|
||||
29 1 603 "*"
|
||||
29 2 506 "}"
|
||||
33 1 503 "["
|
||||
34 1 101 "a"
|
||||
34 2 503 "["
|
||||
35 1 503 "["
|
||||
35 2 101 "a"
|
||||
36 1 503 "["
|
||||
36 2 603 "*"
|
||||
37 1 603 "*"
|
||||
37 2 503 "["
|
||||
38 1 504 "]"
|
||||
39 1 101 "a"
|
||||
39 2 504 "]"
|
||||
40 1 504 "]"
|
||||
40 2 101 "a"
|
||||
41 1 504 "]"
|
||||
41 2 603 "*"
|
||||
42 1 603 "*"
|
||||
42 2 504 "]"
|
145
tests/sprint1/expected/sp1_real_alpha_file1.expected
Normal file
145
tests/sprint1/expected/sp1_real_alpha_file1.expected
Normal file
@ -0,0 +1,145 @@
|
||||
1 1 405 "type"
|
||||
1 6 101 "rec"
|
||||
1 9 508 ":"
|
||||
1 11 503 "["
|
||||
1 12 201 "integer"
|
||||
1 19 508 ":"
|
||||
1 21 101 "x"
|
||||
1 22 507 ";"
|
||||
1 24 201 "integer"
|
||||
1 31 508 ":"
|
||||
1 33 101 "y"
|
||||
1 34 504 "]"
|
||||
2 1 405 "type"
|
||||
2 6 101 "T1"
|
||||
2 8 508 ":"
|
||||
2 10 201 "integer"
|
||||
2 18 510 "->"
|
||||
2 21 201 "integer"
|
||||
3 1 405 "type"
|
||||
3 6 101 "T2"
|
||||
3 8 508 ":"
|
||||
3 10 101 "rec"
|
||||
3 14 510 "->"
|
||||
3 17 201 "integer"
|
||||
4 1 406 "function"
|
||||
4 10 101 "foo"
|
||||
4 14 508 ":"
|
||||
4 16 101 "T1"
|
||||
5 1 406 "function"
|
||||
5 10 101 "bar1"
|
||||
5 15 508 ":"
|
||||
5 17 101 "T2"
|
||||
6 1 406 "function"
|
||||
6 10 101 "bar2"
|
||||
6 15 508 ":"
|
||||
6 17 101 "T2"
|
||||
7 1 101 "foo"
|
||||
7 4 501 "("
|
||||
7 5 101 "x"
|
||||
7 6 502 ")"
|
||||
7 8 608 ":="
|
||||
7 11 505 "{"
|
||||
8 2 407 "return"
|
||||
8 9 101 "x"
|
||||
8 11 603 "*"
|
||||
8 13 101 "x"
|
||||
8 14 507 ";"
|
||||
9 9 506 "}"
|
||||
10 1 101 "bar1"
|
||||
10 5 501 "("
|
||||
10 6 101 "a"
|
||||
10 7 502 ")"
|
||||
10 9 608 ":="
|
||||
10 12 505 "{"
|
||||
11 9 407 "return"
|
||||
11 16 101 "a"
|
||||
11 17 612 "."
|
||||
11 18 101 "x"
|
||||
11 20 603 "*"
|
||||
11 22 101 "a"
|
||||
11 23 612 "."
|
||||
11 24 101 "y"
|
||||
11 25 507 ";"
|
||||
12 9 506 "}"
|
||||
13 1 101 "bar2"
|
||||
13 6 409 "as"
|
||||
13 9 501 "("
|
||||
13 10 101 "r"
|
||||
13 11 509 ","
|
||||
13 12 101 "s"
|
||||
13 13 502 ")"
|
||||
13 15 608 ":="
|
||||
13 18 505 "{"
|
||||
14 9 407 "return"
|
||||
14 16 101 "r"
|
||||
14 18 603 "*"
|
||||
14 20 101 "s"
|
||||
14 21 507 ";"
|
||||
15 9 506 "}"
|
||||
16 1 101 "entry"
|
||||
16 6 501 "("
|
||||
16 7 101 "arg"
|
||||
16 10 502 ")"
|
||||
16 12 608 ":="
|
||||
16 15 505 "{"
|
||||
17 9 503 "["
|
||||
17 11 201 "integer"
|
||||
17 18 508 ":"
|
||||
17 20 101 "result"
|
||||
17 27 507 ";"
|
||||
17 29 101 "rec"
|
||||
17 32 508 ":"
|
||||
17 34 101 "w"
|
||||
17 35 504 "]"
|
||||
18 9 101 "result"
|
||||
18 16 608 ":="
|
||||
18 19 101 "foo"
|
||||
18 22 501 "("
|
||||
18 23 301 "5"
|
||||
18 24 502 ")"
|
||||
18 25 507 ";"
|
||||
19 9 101 "w"
|
||||
19 11 608 ":="
|
||||
19 14 613 "reserve"
|
||||
19 21 501 "("
|
||||
19 22 101 "w"
|
||||
19 23 502 ")"
|
||||
19 24 507 ";"
|
||||
19 26 700 "(* see types.alpha – reserve returns a value of type address,
|
||||
which can be assigned to array and record variables
|
||||
*)"
|
||||
22 9 101 "w"
|
||||
22 10 612 "."
|
||||
22 11 101 "x"
|
||||
22 13 608 ":="
|
||||
22 16 301 "5"
|
||||
22 17 507 ";"
|
||||
23 9 101 "w"
|
||||
23 10 612 "."
|
||||
23 11 101 "y"
|
||||
23 13 608 ":="
|
||||
23 16 301 "7"
|
||||
23 17 507 ";"
|
||||
24 9 101 "result"
|
||||
24 16 608 ":="
|
||||
24 19 101 "bar1"
|
||||
24 23 501 "("
|
||||
24 24 101 "w"
|
||||
24 25 502 ")"
|
||||
24 26 507 ";"
|
||||
24 28 700 "(* pass w (a rec type value) to bar1 *)"
|
||||
25 9 101 "result"
|
||||
25 16 608 ":="
|
||||
25 19 101 "bar2"
|
||||
25 23 501 "("
|
||||
25 24 301 "5"
|
||||
25 25 509 ","
|
||||
25 26 301 "7"
|
||||
25 27 502 ")"
|
||||
25 28 507 ";"
|
||||
25 30 700 "(* implicitly build a rec type value, assign 5 and 7 to fields x and y, but call them r and s *)"
|
||||
27 9 407 "return"
|
||||
27 16 301 "0"
|
||||
27 17 507 ";"
|
||||
28 1 506 "}"
|
100
tests/sprint1/expected/sp1_real_alpha_file2.expected
Normal file
100
tests/sprint1/expected/sp1_real_alpha_file2.expected
Normal file
@ -0,0 +1,100 @@
|
||||
1 1 700 "(* Type definitions *)"
|
||||
2 1 405 "type"
|
||||
2 6 101 "string"
|
||||
2 12 508 ":"
|
||||
2 14 301 "1"
|
||||
2 16 510 "->"
|
||||
2 19 204 "character"
|
||||
3 1 405 "type"
|
||||
3 6 101 "int2int"
|
||||
3 13 508 ":"
|
||||
3 15 201 "integer"
|
||||
3 23 510 "->"
|
||||
3 26 201 "integer"
|
||||
4 1 405 "type"
|
||||
4 6 101 "string2int"
|
||||
4 16 508 ":"
|
||||
4 18 101 "string"
|
||||
4 25 510 "->"
|
||||
4 28 201 "integer"
|
||||
5 1 700 "(* Function prototypes
|
||||
They use the above type definitions
|
||||
*)"
|
||||
8 1 406 "function"
|
||||
8 10 101 "square"
|
||||
8 17 508 ":"
|
||||
8 19 101 "int2int"
|
||||
9 1 406 "function"
|
||||
9 10 101 "entry"
|
||||
9 16 508 ":"
|
||||
9 18 101 "string2int"
|
||||
10 1 700 "(* Function definition
|
||||
Functions must be declared before they are defined
|
||||
*)"
|
||||
13 1 101 "square"
|
||||
13 7 501 "("
|
||||
13 8 101 "x"
|
||||
13 9 502 ")"
|
||||
13 11 608 ":="
|
||||
13 14 505 "{"
|
||||
14 1 407 "return"
|
||||
14 8 101 "x"
|
||||
14 10 603 "*"
|
||||
14 12 101 "x"
|
||||
14 13 507 ";"
|
||||
15 1 506 "}"
|
||||
16 1 700 "(* Function definition
|
||||
entry is the first function called
|
||||
*)"
|
||||
19 1 101 "entry"
|
||||
19 6 501 "("
|
||||
19 7 101 "arg"
|
||||
19 10 502 ")"
|
||||
19 12 608 ":="
|
||||
19 15 505 "{"
|
||||
20 1 101 "input"
|
||||
20 7 607 "="
|
||||
20 9 301 "7"
|
||||
20 10 507 ";"
|
||||
21 1 101 "expected"
|
||||
21 10 607 "="
|
||||
21 12 301 "49"
|
||||
21 14 507 ";"
|
||||
22 1 101 "actual"
|
||||
22 8 608 ":="
|
||||
22 11 101 "square"
|
||||
22 17 501 "("
|
||||
22 18 101 "input"
|
||||
22 23 502 ")"
|
||||
22 24 507 ";"
|
||||
23 1 101 "rseult"
|
||||
23 8 608 ":="
|
||||
23 11 101 "expected"
|
||||
23 20 607 "="
|
||||
23 22 101 "actual"
|
||||
23 28 507 ";"
|
||||
24 1 407 "return"
|
||||
24 8 301 "0"
|
||||
24 9 507 ";"
|
||||
25 1 503 "["
|
||||
25 3 201 "integer"
|
||||
25 10 508 ":"
|
||||
25 12 101 "input"
|
||||
25 17 507 ";"
|
||||
25 19 201 "integer"
|
||||
25 26 508 ":"
|
||||
25 28 101 "expected"
|
||||
25 36 507 ";"
|
||||
25 38 201 "integer"
|
||||
25 45 508 ":"
|
||||
25 47 101 "actual"
|
||||
25 53 507 ";"
|
||||
25 55 101 "boolean"
|
||||
25 62 508 ":"
|
||||
25 64 101 "result"
|
||||
25 70 507 ";"
|
||||
25 72 101 "string"
|
||||
25 78 508 ":"
|
||||
25 80 101 "input"
|
||||
25 86 504 "]"
|
||||
26 1 506 "}"
|
8
tests/sprint1/expected/sp1_simple_int.expected
Normal file
8
tests/sprint1/expected/sp1_simple_int.expected
Normal file
@ -0,0 +1,8 @@
|
||||
1 1 301 "45"
|
||||
2 1 301 "123"
|
||||
3 1 301 "8392"
|
||||
4 1 301 "40"
|
||||
4 4 301 "40"
|
||||
5 2 301 "200"
|
||||
5 6 301 "50"
|
||||
5 9 301 "21783"
|
64
tests/sprint1/expected/sp1_simple_literals.expected
Normal file
64
tests/sprint1/expected/sp1_simple_literals.expected
Normal file
@ -0,0 +1,64 @@
|
||||
1 1 304 ""this is a string""
|
||||
1 20 301 "721398"
|
||||
1 27 303 "'g'"
|
||||
1 32 604 "/"
|
||||
1 33 101 "n"
|
||||
1 36 700 "(* should print 3 tokens before this *)"
|
||||
4 1 301 "12893"
|
||||
4 8 101 "this"
|
||||
4 13 101 "is"
|
||||
4 16 101 "not"
|
||||
4 20 101 "a"
|
||||
4 22 101 "string"
|
||||
4 29 700 "(*one valid token before this*)"
|
||||
5 1 700 "(* spacey comment here
|
||||
over multiple lines
|
||||
will it work? *)"
|
||||
7 18 306 "false"
|
||||
11 1 306 "false"
|
||||
12 1 700 "(**)"
|
||||
14 1 101 "nullfalse"
|
||||
15 2 101 "nulltrue"
|
||||
16 1 302 "null"
|
||||
17 1 303 "'7'"
|
||||
18 1 305 "true"
|
||||
19 2 301 "189"
|
||||
20 1 303 "'\t'"
|
||||
21 1 303 "'"'"
|
||||
22 1 303 "'/'"
|
||||
23 1 303 "'\n'"
|
||||
24 1 303 "'\''"
|
||||
25 1 303 "'\t'"
|
||||
26 1 303 "'\\'"
|
||||
27 1 303 "'n'"
|
||||
29 2 101 "fdsf"
|
||||
30 1 700 "(*/jnewjno2893u86^ Lots of random characters /n /t '") *)"
|
||||
35 1 304 ""STRINGwithnotSPaces""
|
||||
36 1 303 "' '"
|
||||
38 1 304 ""J""
|
||||
39 1 304 """"
|
||||
40 1 304 "" ""
|
||||
42 1 304 ""{SCHAR}""
|
||||
43 1 304 ""SCHAR""
|
||||
44 1 304 ""[SCHAR]""
|
||||
45 1 304 ""FINAL: I'd think this is a legal \"string\" that contains \n \t several escaped characters, isn't it?""
|
||||
46 2 101 "I"
|
||||
46 4 101 "d"
|
||||
46 6 101 "think"
|
||||
46 12 101 "this"
|
||||
46 17 101 "is"
|
||||
46 20 101 "a"
|
||||
46 22 101 "legal"
|
||||
46 30 101 "string"
|
||||
46 39 101 "that"
|
||||
46 44 101 "contains"
|
||||
46 53 101 "several"
|
||||
46 63 101 "n"
|
||||
46 66 101 "t"
|
||||
46 68 101 "escaped"
|
||||
46 76 101 "characters"
|
||||
46 86 509 ","
|
||||
46 88 101 "isn"
|
||||
46 92 101 "t"
|
||||
46 94 101 "it"
|
||||
47 1 101 "nullLike"
|
13
tests/sprint1/expected/sp1_variables.expected
Normal file
13
tests/sprint1/expected/sp1_variables.expected
Normal file
@ -0,0 +1,13 @@
|
||||
1 1 101 "valid1"
|
||||
2 1 101 "Valid2"
|
||||
3 1 101 "_valid3"
|
||||
4 1 101 "_valid_name_4"
|
||||
5 1 101 "VALID"
|
||||
6 1 301 "0"
|
||||
6 2 101 "Invalid"
|
||||
7 1 301 "1"
|
||||
7 2 101 "invalid"
|
||||
8 2 101 "invalid"
|
||||
9 1 101 "invalid"
|
||||
9 8 607 "="
|
||||
10 1 101 "String"
|
35
tests/sprint2/expected/sp2_carls_mistake.expected
Normal file
35
tests/sprint2/expected/sp2_carls_mistake.expected
Normal file
@ -0,0 +1,35 @@
|
||||
NAME : SCOPE : PARENT : TYPE : EXTRA ANNOTATION :
|
||||
------------------------------:--------:--------:-----------------------------------:-----------------------------------:
|
||||
bar2 : 001001 : : undefined : Function Definition
|
||||
bar1 : 001001 : : undefined : Function Definition
|
||||
foo : 001001 : : undefined : Function Definition
|
||||
entry : 001001 : : undefined : Function Definition
|
||||
main : 001001 : : string -> integer : Type of Function
|
||||
arr : 001001 : : 1 -> integer : Type of Array
|
||||
T2 : 001001 : : rec -> integer : Type of Function
|
||||
T1 : 001001 : : integer -> integer : Type of Function
|
||||
rec : 001001 : : Record Type : elements-2 size-8 bytes
|
||||
integer : 001001 : : Primitive Type : size-4 bytes
|
||||
address : 001001 : : Primitive Type : size-8 bytes
|
||||
character : 001001 : : Primitive Type : size-1 bytes
|
||||
string : 001001 : : 1 -> character : Type of Array
|
||||
Boolean : 001001 : : Primitive Type : size-4 bytes
|
||||
reserve type : 001001 : : integer -> address : Type of Function
|
||||
reserve : 001001 : : undefined : Function Definition
|
||||
release type : 001001 : : address -> integer : Type of Function
|
||||
release : 001001 : : undefined : Function Definition
|
||||
------------------------------:--------:--------:-----------------------------------:-----------------------------------:
|
||||
w : 025000 : 001001 : rec : Record Instance
|
||||
result : 025000 : 001001 : integer : Primitive Instance
|
||||
arg : 025000 : 001001 : string : Array Instance
|
||||
------------------------------:--------:--------:-----------------------------------:-----------------------------------:
|
||||
r : 021000 : 001001 : integer : Primitive Instance
|
||||
s : 021000 : 001001 : integer : Primitive Instance
|
||||
------------------------------:--------:--------:-----------------------------------:-----------------------------------:
|
||||
x : 017000 : 001001 : integer : Primitive Instance
|
||||
y : 017000 : 001001 : integer : Primitive Instance
|
||||
------------------------------:--------:--------:-----------------------------------:-----------------------------------:
|
||||
x : 013000 : 001001 : integer : Primitive Instance
|
||||
------------------------------:--------:--------:-----------------------------------:-----------------------------------:
|
||||
y : 001000 : 001001 : integer : Primitive Instance
|
||||
x : 001000 : 001001 : integer : Primitive Instance
|
29
tests/sprint2/expected/sp2_function_types.expected
Normal file
29
tests/sprint2/expected/sp2_function_types.expected
Normal file
@ -0,0 +1,29 @@
|
||||
NAME : SCOPE : PARENT : TYPE : EXTRA ANNOTATION :
|
||||
------------------------------:--------:--------:-----------------------------------:-----------------------------------:
|
||||
entry : 001001 : : undefined : Function Definition
|
||||
integer2integer2integerFunc : 001001 : : undefined : Function Definition
|
||||
released : 001001 : : undefined : Function Definition
|
||||
reserved : 001001 : : undefined : Function Definition
|
||||
printBoolean : 001001 : : undefined : Function Definition
|
||||
printCharacter : 001001 : : undefined : Function Definition
|
||||
printInteger : 001001 : : undefined : Function Definition
|
||||
integer2integer2integer : 001001 : : integer2integer -> integer : Type of Function
|
||||
address2integer : 001001 : : address -> integer : Type of Function
|
||||
integer2address : 001001 : : integer -> address : Type of Function
|
||||
Boolean2Boolean2Boolean : 001001 : : Boolean2Boolean -> Boolean : Type of Function
|
||||
character2character2Boolean : 001001 : : undefined -> undefined : Type of Function
|
||||
integer2integer2Boolean : 001001 : : integer2integer -> Boolean : Type of Function
|
||||
string2integer : 001001 : : string -> integer : Type of Function
|
||||
Boolean2integer : 001001 : : Boolean -> integer : Type of Function
|
||||
character2integer : 001001 : : character -> integer : Type of Function
|
||||
integer2integer : 001001 : : integer -> integer : Type of Function
|
||||
Boolean2Boolean : 001001 : : Boolean -> Boolean : Type of Function
|
||||
integer : 001001 : : Primitive Type : size-4 bytes
|
||||
address : 001001 : : Primitive Type : size-8 bytes
|
||||
character : 001001 : : Primitive Type : size-1 bytes
|
||||
string : 001001 : : 1 -> character : Type of Array
|
||||
Boolean : 001001 : : Primitive Type : size-4 bytes
|
||||
reserve type : 001001 : : integer -> address : Type of Function
|
||||
reserve : 001001 : : undefined : Function Definition
|
||||
release type : 001001 : : address -> integer : Type of Function
|
||||
release : 001001 : : undefined : Function Definition
|
21
tests/sprint2/expected/sp2_integer_binary_op.expected
Normal file
21
tests/sprint2/expected/sp2_integer_binary_op.expected
Normal file
@ -0,0 +1,21 @@
|
||||
NAME : SCOPE : PARENT : TYPE : EXTRA ANNOTATION :
|
||||
------------------------------:--------:--------:-----------------------------------:-----------------------------------:
|
||||
testarr : 001001 : : 1 -> integer : Type of Array
|
||||
entry : 001001 : : undefined : Function Definition
|
||||
main : 001001 : : string -> integer : Type of Function
|
||||
integer : 001001 : : Primitive Type : size-4 bytes
|
||||
address : 001001 : : Primitive Type : size-8 bytes
|
||||
character : 001001 : : Primitive Type : size-1 bytes
|
||||
string : 001001 : : 1 -> character : Type of Array
|
||||
Boolean : 001001 : : Primitive Type : size-4 bytes
|
||||
reserve type : 001001 : : integer -> address : Type of Function
|
||||
reserve : 001001 : : undefined : Function Definition
|
||||
release type : 001001 : : address -> integer : Type of Function
|
||||
release : 001001 : : undefined : Function Definition
|
||||
------------------------------:--------:--------:-----------------------------------:-----------------------------------:
|
||||
b1 : 005000 : 001001 : Boolean : Primitive Instance
|
||||
b2 : 005000 : 001001 : Boolean : Primitive Instance
|
||||
arr2 : 005000 : 001001 : testarr : Array Instance
|
||||
arr : 005000 : 001001 : testarr : Array Instance
|
||||
x : 005000 : 001001 : integer : Primitive Instance
|
||||
arg : 005000 : 001001 : string : Array Instance
|
@ -0,0 +1,20 @@
|
||||
NAME : SCOPE : PARENT : TYPE : EXTRA ANNOTATION :
|
||||
------------------------------:--------:--------:-----------------------------------:-----------------------------------:
|
||||
test : 001001 : : undefined : Function Definition
|
||||
main : 001001 : : rec -> integer : Type of Function
|
||||
rec : 001001 : : Record Type : elements-2 size-8 bytes
|
||||
integer : 001001 : : Primitive Type : size-4 bytes
|
||||
address : 001001 : : Primitive Type : size-8 bytes
|
||||
character : 001001 : : Primitive Type : size-1 bytes
|
||||
string : 001001 : : 1 -> character : Type of Array
|
||||
Boolean : 001001 : : Primitive Type : size-4 bytes
|
||||
reserve type : 001001 : : integer -> address : Type of Function
|
||||
reserve : 001001 : : undefined : Function Definition
|
||||
release type : 001001 : : address -> integer : Type of Function
|
||||
release : 001001 : : undefined : Function Definition
|
||||
------------------------------:--------:--------:-----------------------------------:-----------------------------------:
|
||||
arg : 005000 : 001001 : integer : Primitive Instance
|
||||
arg2 : 005000 : 001001 : integer : Primitive Instance
|
||||
------------------------------:--------:--------:-----------------------------------:-----------------------------------:
|
||||
y : 001000 : 001001 : integer : Primitive Instance
|
||||
x : 001000 : 001001 : integer : Primitive Instance
|
20
tests/sprint2/expected/sp2_invalid_recop.expected
Normal file
20
tests/sprint2/expected/sp2_invalid_recop.expected
Normal file
@ -0,0 +1,20 @@
|
||||
NAME : SCOPE : PARENT : TYPE : EXTRA ANNOTATION :
|
||||
------------------------------:--------:--------:-----------------------------------:-----------------------------------:
|
||||
rec : 001001 : : Record Type : elements-2 size-8 bytes
|
||||
entry : 001001 : : undefined : Function Definition
|
||||
main : 001001 : : string -> integer : Type of Function
|
||||
integer : 001001 : : Primitive Type : size-4 bytes
|
||||
address : 001001 : : Primitive Type : size-8 bytes
|
||||
character : 001001 : : Primitive Type : size-1 bytes
|
||||
string : 001001 : : 1 -> character : Type of Array
|
||||
Boolean : 001001 : : Primitive Type : size-4 bytes
|
||||
reserve type : 001001 : : integer -> address : Type of Function
|
||||
reserve : 001001 : : undefined : Function Definition
|
||||
release type : 001001 : : address -> integer : Type of Function
|
||||
release : 001001 : : undefined : Function Definition
|
||||
------------------------------:--------:--------:-----------------------------------:-----------------------------------:
|
||||
w : 006000 : 001001 : rec : Record Instance
|
||||
arg : 006000 : 001001 : string : Array Instance
|
||||
------------------------------:--------:--------:-----------------------------------:-----------------------------------:
|
||||
y : 004000 : 001001 : integer : Primitive Instance
|
||||
x : 004000 : 001001 : integer : Primitive Instance
|
17
tests/sprint2/expected/sp2_invalid_release.expected
Normal file
17
tests/sprint2/expected/sp2_invalid_release.expected
Normal file
@ -0,0 +1,17 @@
|
||||
NAME : SCOPE : PARENT : TYPE : EXTRA ANNOTATION :
|
||||
------------------------------:--------:--------:-----------------------------------:-----------------------------------:
|
||||
rec : 001001 : : Record Type : elements-2 size-8 bytes
|
||||
integer : 001001 : : Primitive Type : size-4 bytes
|
||||
address : 001001 : : Primitive Type : size-8 bytes
|
||||
character : 001001 : : Primitive Type : size-1 bytes
|
||||
string : 001001 : : 1 -> character : Type of Array
|
||||
Boolean : 001001 : : Primitive Type : size-4 bytes
|
||||
reserve type : 001001 : : integer -> address : Type of Function
|
||||
reserve : 001001 : : undefined : Function Definition
|
||||
release type : 001001 : : address -> integer : Type of Function
|
||||
release : 001001 : : undefined : Function Definition
|
||||
------------------------------:--------:--------:-----------------------------------:-----------------------------------:
|
||||
w : 003000 : 001001 : rec : Record Instance
|
||||
------------------------------:--------:--------:-----------------------------------:-----------------------------------:
|
||||
y : 001000 : 001001 : integer : Primitive Instance
|
||||
x : 001000 : 001001 : integer : Primitive Instance
|
39
tests/sprint2/expected/sp2_library.expected
Normal file
39
tests/sprint2/expected/sp2_library.expected
Normal file
@ -0,0 +1,39 @@
|
||||
NAME : SCOPE : PARENT : TYPE : EXTRA ANNOTATION :
|
||||
------------------------------:--------:--------:-----------------------------------:-----------------------------------:
|
||||
entry : 001001 : : undefined : Function Definition
|
||||
printBoolean : 001001 : : undefined : Function Definition
|
||||
printCharacter : 001001 : : undefined : Function Definition
|
||||
printInteger : 001001 : : undefined : Function Definition
|
||||
address2integer : 001001 : : address -> integer : Type of Function
|
||||
integer2address : 001001 : : integer -> address : Type of Function
|
||||
BooleanXBoolean2Boolean : 001001 : : BooleanXBoolean -> Boolean : Type of Function
|
||||
characterXcharacter2Boolean : 001001 : : characterXcharacter -> Boolean : Type of Function
|
||||
integerXinteger2Boolean : 001001 : : integerXinteger -> Boolean : Type of Function
|
||||
integerXinteger2integer : 001001 : : integerXinteger -> integer : Type of Function
|
||||
string2integer : 001001 : : string -> integer : Type of Function
|
||||
Boolean2integer : 001001 : : Boolean -> integer : Type of Function
|
||||
character2integer : 001001 : : character -> integer : Type of Function
|
||||
integer2integer : 001001 : : integer -> integer : Type of Function
|
||||
Boolean2Boolean : 001001 : : Boolean -> Boolean : Type of Function
|
||||
integerXinteger : 001001 : : Record Type : elements-2 size-8 bytes
|
||||
characterXcharacter : 001001 : : Record Type : elements-2 size-2 bytes
|
||||
BooleanXBoolean : 001001 : : Record Type : elements-2 size-8 bytes
|
||||
string : 001001 : : 1 -> character : Type of Array
|
||||
integer : 001001 : : Primitive Type : size-4 bytes
|
||||
address : 001001 : : Primitive Type : size-8 bytes
|
||||
character : 001001 : : Primitive Type : size-1 bytes
|
||||
string : 001001 : : 1 -> character : Type of Array
|
||||
Boolean : 001001 : : Primitive Type : size-4 bytes
|
||||
reserve type : 001001 : : integer -> address : Type of Function
|
||||
reserve : 001001 : : undefined : Function Definition
|
||||
release type : 001001 : : address -> integer : Type of Function
|
||||
release : 001001 : : undefined : Function Definition
|
||||
------------------------------:--------:--------:-----------------------------------:-----------------------------------:
|
||||
y : 015000 : 001001 : integer : Primitive Instance
|
||||
x : 015000 : 001001 : integer : Primitive Instance
|
||||
------------------------------:--------:--------:-----------------------------------:-----------------------------------:
|
||||
y : 014000 : 001001 : character : Primitive Instance
|
||||
x : 014000 : 001001 : character : Primitive Instance
|
||||
------------------------------:--------:--------:-----------------------------------:-----------------------------------:
|
||||
y : 013000 : 001001 : Boolean : Primitive Instance
|
||||
x : 013000 : 001001 : Boolean : Primitive Instance
|
66
tests/sprint2/expected/sp2_llnode.expected
Normal file
66
tests/sprint2/expected/sp2_llnode.expected
Normal file
@ -0,0 +1,66 @@
|
||||
NAME : SCOPE : PARENT : TYPE : EXTRA ANNOTATION :
|
||||
------------------------------:--------:--------:-----------------------------------:-----------------------------------:
|
||||
make_list : 001001 : : undefined : Function Definition
|
||||
bar2 : 001001 : : undefined : Function Definition
|
||||
bar1 : 001001 : : undefined : Function Definition
|
||||
foo : 001001 : : undefined : Function Definition
|
||||
list : 001001 : : integer -> llnode : Type of Function
|
||||
llnode : 001001 : : Record Type : elements-3 size-24 bytes
|
||||
T2 : 001001 : : rec -> integer : Type of Function
|
||||
T1 : 001001 : : integer -> integer : Type of Function
|
||||
rec : 001001 : : Record Type : elements-2 size-8 bytes
|
||||
entry : 001001 : : undefined : Function Definition
|
||||
main : 001001 : : string -> integer : Type of Function
|
||||
integer : 001001 : : Primitive Type : size-4 bytes
|
||||
address : 001001 : : Primitive Type : size-8 bytes
|
||||
character : 001001 : : Primitive Type : size-1 bytes
|
||||
string : 001001 : : 1 -> character : Type of Array
|
||||
Boolean : 001001 : : Primitive Type : size-4 bytes
|
||||
reserve type : 001001 : : integer -> address : Type of Function
|
||||
reserve : 001001 : : undefined : Function Definition
|
||||
release type : 001001 : : address -> integer : Type of Function
|
||||
release : 001001 : : undefined : Function Definition
|
||||
------------------------------:--------:--------:-----------------------------------:-----------------------------------:
|
||||
li : 069000 : 001001 : llnode : Record Instance
|
||||
w : 069000 : 001001 : rec : Record Instance
|
||||
result : 069000 : 001001 : integer : Primitive Instance
|
||||
arg : 069000 : 001001 : string : Array Instance
|
||||
------------------------------:--------:--------:-----------------------------------:-----------------------------------:
|
||||
r : 054000 : 001001 : integer : Primitive Instance
|
||||
s : 054000 : 001001 : integer : Primitive Instance
|
||||
------------------------------:--------:--------:-----------------------------------:-----------------------------------:
|
||||
x : 059012 : 054000 : integer : Primitive Instance
|
||||
------------------------------:--------:--------:-----------------------------------:-----------------------------------:
|
||||
: 062028 : 059012 : : Empty Scope
|
||||
------------------------------:--------:--------:-----------------------------------:-----------------------------------:
|
||||
: 055021 : 054000 : : Empty Scope
|
||||
------------------------------:--------:--------:-----------------------------------:-----------------------------------:
|
||||
: 056026 : 055021 : : Empty Scope
|
||||
------------------------------:--------:--------:-----------------------------------:-----------------------------------:
|
||||
a : 050000 : 001001 : integer : Primitive Instance
|
||||
b : 050000 : 001001 : integer : Primitive Instance
|
||||
------------------------------:--------:--------:-----------------------------------:-----------------------------------:
|
||||
x : 046000 : 001001 : integer : Primitive Instance
|
||||
------------------------------:--------:--------:-----------------------------------:-----------------------------------:
|
||||
temp : 016000 : 001001 : address : Primitive Instance
|
||||
curr : 016000 : 001001 : address : Primitive Instance
|
||||
ret : 016000 : 001001 : address : Primitive Instance
|
||||
orig_a : 016000 : 001001 : integer : Primitive Instance
|
||||
a : 016000 : 001001 : integer : Primitive Instance
|
||||
------------------------------:--------:--------:-----------------------------------:-----------------------------------:
|
||||
: 021012 : 016000 : : Empty Scope
|
||||
------------------------------:--------:--------:-----------------------------------:-----------------------------------:
|
||||
: 026023 : 021012 : : Empty Scope
|
||||
------------------------------:--------:--------:-----------------------------------:-----------------------------------:
|
||||
: 035020 : 026023 : : Empty Scope
|
||||
------------------------------:--------:--------:-----------------------------------:-----------------------------------:
|
||||
: 031034 : 026023 : : Empty Scope
|
||||
------------------------------:--------:--------:-----------------------------------:-----------------------------------:
|
||||
: 019029 : 016000 : : Empty Scope
|
||||
------------------------------:--------:--------:-----------------------------------:-----------------------------------:
|
||||
next : 008000 : 001001 : llnode : Record Instance
|
||||
val : 008000 : 001001 : integer : Primitive Instance
|
||||
prev : 008000 : 001001 : llnode : Record Instance
|
||||
------------------------------:--------:--------:-----------------------------------:-----------------------------------:
|
||||
y : 004000 : 001001 : integer : Primitive Instance
|
||||
x : 004000 : 001001 : integer : Primitive Instance
|
29
tests/sprint2/expected/sp2_one_line.expected
Normal file
29
tests/sprint2/expected/sp2_one_line.expected
Normal file
@ -0,0 +1,29 @@
|
||||
NAME : SCOPE : PARENT : TYPE : EXTRA ANNOTATION :
|
||||
------------------------------:--------:--------:-----------------------------------:-----------------------------------:
|
||||
bar2 : 001001 : : undefined : Function Definition
|
||||
bar1 : 001001 : : undefined : Function Definition
|
||||
foo : 001001 : : undefined : Function Definition
|
||||
T2 : 001001 : : rec -> integer : Type of Function
|
||||
T1 : 001001 : : integer -> integer : Type of Function
|
||||
rec : 001001 : : Record Type : elements-2 size-8 bytes
|
||||
entry : 001001 : : undefined : Function Definition
|
||||
main : 001001 : : string -> integer : Type of Function
|
||||
integer : 001001 : : Primitive Type : size-4 bytes
|
||||
address : 001001 : : Primitive Type : size-8 bytes
|
||||
character : 001001 : : Primitive Type : size-1 bytes
|
||||
string : 001001 : : 1 -> character : Type of Array
|
||||
Boolean : 001001 : : Primitive Type : size-4 bytes
|
||||
reserve type : 001001 : : integer -> address : Type of Function
|
||||
reserve : 001001 : : undefined : Function Definition
|
||||
release type : 001001 : : address -> integer : Type of Function
|
||||
release : 001001 : : undefined : Function Definition
|
||||
------------------------------:--------:--------:-----------------------------------:-----------------------------------:
|
||||
: 000000 : 001001 : : Empty Scope
|
||||
------------------------------:--------:--------:-----------------------------------:-----------------------------------:
|
||||
a : 001000 : 001001 : integer : Primitive Instance
|
||||
undefined : 001000 : 001001 : integer : Primitive Instance
|
||||
------------------------------:--------:--------:-----------------------------------:-----------------------------------:
|
||||
x : 001000 : 001001 : integer : Primitive Instance
|
||||
------------------------------:--------:--------:-----------------------------------:-----------------------------------:
|
||||
y : 001000 : 001001 : integer : Primitive Instance
|
||||
x : 001000 : 001001 : integer : Primitive Instance
|
23
tests/sprint2/expected/sp2_presidence.expected
Normal file
23
tests/sprint2/expected/sp2_presidence.expected
Normal file
@ -0,0 +1,23 @@
|
||||
NAME : SCOPE : PARENT : TYPE : EXTRA ANNOTATION :
|
||||
------------------------------:--------:--------:-----------------------------------:-----------------------------------:
|
||||
entry : 001001 : : undefined : Function Definition
|
||||
rec : 001001 : : Record Type : elements-2 size-8 bytes
|
||||
main : 001001 : : string -> integer : Type of Function
|
||||
integer : 001001 : : Primitive Type : size-4 bytes
|
||||
address : 001001 : : Primitive Type : size-8 bytes
|
||||
character : 001001 : : Primitive Type : size-1 bytes
|
||||
string : 001001 : : 1 -> character : Type of Array
|
||||
Boolean : 001001 : : Primitive Type : size-4 bytes
|
||||
reserve type : 001001 : : integer -> address : Type of Function
|
||||
reserve : 001001 : : undefined : Function Definition
|
||||
release type : 001001 : : address -> integer : Type of Function
|
||||
release : 001001 : : undefined : Function Definition
|
||||
------------------------------:--------:--------:-----------------------------------:-----------------------------------:
|
||||
arg_bool : 006000 : 001001 : Boolean : Primitive Instance
|
||||
arg_record : 006000 : 001001 : rec : Record Instance
|
||||
arg_y : 006000 : 001001 : integer : Primitive Instance
|
||||
arg_x : 006000 : 001001 : integer : Primitive Instance
|
||||
arg : 006000 : 001001 : string : Array Instance
|
||||
------------------------------:--------:--------:-----------------------------------:-----------------------------------:
|
||||
rec_y : 002000 : 001001 : integer : Primitive Instance
|
||||
rec_x : 002000 : 001001 : integer : Primitive Instance
|
16
tests/sprint2/expected/sp2_simple.expected
Normal file
16
tests/sprint2/expected/sp2_simple.expected
Normal file
@ -0,0 +1,16 @@
|
||||
NAME : SCOPE : PARENT : TYPE : EXTRA ANNOTATION :
|
||||
------------------------------:--------:--------:-----------------------------------:-----------------------------------:
|
||||
entry : 001001 : : undefined : Function Definition
|
||||
main : 001001 : : string -> integer : Type of Function
|
||||
integer : 001001 : : Primitive Type : size-4 bytes
|
||||
address : 001001 : : Primitive Type : size-8 bytes
|
||||
character : 001001 : : Primitive Type : size-1 bytes
|
||||
string : 001001 : : 1 -> character : Type of Array
|
||||
Boolean : 001001 : : Primitive Type : size-4 bytes
|
||||
reserve type : 001001 : : integer -> address : Type of Function
|
||||
reserve : 001001 : : undefined : Function Definition
|
||||
release type : 001001 : : address -> integer : Type of Function
|
||||
release : 001001 : : undefined : Function Definition
|
||||
------------------------------:--------:--------:-----------------------------------:-----------------------------------:
|
||||
x : 004000 : 001001 : integer : Primitive Instance
|
||||
arg : 004000 : 001001 : string : Array Instance
|
17
tests/sprint2/expected/sp2_sp2_arrayargs.expected
Normal file
17
tests/sprint2/expected/sp2_sp2_arrayargs.expected
Normal file
@ -0,0 +1,17 @@
|
||||
NAME : SCOPE : PARENT : TYPE : EXTRA ANNOTATION :
|
||||
------------------------------:--------:--------:-----------------------------------:-----------------------------------:
|
||||
a_of_s : 001001 : : 1 -> string : Type of Array
|
||||
string : 001001 : : 1 -> character : Type of Array
|
||||
integer : 001001 : : Primitive Type : size-4 bytes
|
||||
address : 001001 : : Primitive Type : size-8 bytes
|
||||
character : 001001 : : Primitive Type : size-1 bytes
|
||||
string : 001001 : : 1 -> character : Type of Array
|
||||
Boolean : 001001 : : Primitive Type : size-4 bytes
|
||||
reserve type : 001001 : : integer -> address : Type of Function
|
||||
reserve : 001001 : : undefined : Function Definition
|
||||
release type : 001001 : : address -> integer : Type of Function
|
||||
release : 001001 : : undefined : Function Definition
|
||||
------------------------------:--------:--------:-----------------------------------:-----------------------------------:
|
||||
many_names : 006000 : 001001 : a_of_s : Array Instance
|
||||
another_name : 006000 : 001001 : string : Array Instance
|
||||
one_name : 006000 : 001001 : string : Array Instance
|
21
tests/sprint2/expected/sp2_valid_assignable_and_mem.expected
Normal file
21
tests/sprint2/expected/sp2_valid_assignable_and_mem.expected
Normal file
@ -0,0 +1,21 @@
|
||||
NAME : SCOPE : PARENT : TYPE : EXTRA ANNOTATION :
|
||||
------------------------------:--------:--------:-----------------------------------:-----------------------------------:
|
||||
T2 : 001001 : : rec -> integer : Type of Function
|
||||
rec : 001001 : : Record Type : elements-2 size-8 bytes
|
||||
entry : 001001 : : undefined : Function Definition
|
||||
main : 001001 : : string -> integer : Type of Function
|
||||
integer : 001001 : : Primitive Type : size-4 bytes
|
||||
address : 001001 : : Primitive Type : size-8 bytes
|
||||
character : 001001 : : Primitive Type : size-1 bytes
|
||||
string : 001001 : : 1 -> character : Type of Array
|
||||
Boolean : 001001 : : Primitive Type : size-4 bytes
|
||||
reserve type : 001001 : : integer -> address : Type of Function
|
||||
reserve : 001001 : : undefined : Function Definition
|
||||
release type : 001001 : : address -> integer : Type of Function
|
||||
release : 001001 : : undefined : Function Definition
|
||||
------------------------------:--------:--------:-----------------------------------:-----------------------------------:
|
||||
w : 007000 : 001001 : rec : Record Instance
|
||||
arg : 007000 : 001001 : string : Array Instance
|
||||
------------------------------:--------:--------:-----------------------------------:-----------------------------------:
|
||||
y : 004000 : 001001 : integer : Primitive Instance
|
||||
x : 004000 : 001001 : integer : Primitive Instance
|
@ -1,48 +0,0 @@
|
||||
/* Function type. */
|
||||
typedef double (func_t) (double);
|
||||
/* Data type for links in the chain of symbols. */
|
||||
struct symrec
|
||||
{
|
||||
char *name; /* name of symbol */
|
||||
int type; /* type of symbol: either VAR or FUN */
|
||||
union
|
||||
{
|
||||
double var; /* value of a VAR */
|
||||
func_t *fun; /* value of a FUN */
|
||||
} value;
|
||||
struct symrec *next; /* link field */
|
||||
};
|
||||
typedef struct symrec symrec;
|
||||
|
||||
/* The symbol table: a chain of 'struct symrec'. */
|
||||
extern symrec *sym_table;
|
||||
|
||||
symrec *putsym (char const *name, int sym_type);
|
||||
symrec *getsym (char const *name);
|
||||
struct init
|
||||
{
|
||||
char const *name;
|
||||
func_t *fun;
|
||||
};
|
||||
struct init const funs[] =
|
||||
{
|
||||
{ "atan", atan },
|
||||
{ "cos", cos },
|
||||
{ "exp", exp },
|
||||
{ "ln", log },
|
||||
{ "sin", sin },
|
||||
{ "sqrt", sqrt },
|
||||
{ 0, 0 },
|
||||
};
|
||||
/* The symbol table: a chain of 'struct symrec'. */
|
||||
symrec *sym_table;
|
||||
/* Put functions in table. */
|
||||
static void
|
||||
init_table (void)
|
||||
{
|
||||
for (int i = 0; funs[i].name; i++)
|
||||
{
|
||||
symrec *ptr = putsym (funs[i].name, FUN);
|
||||
ptr->value.fun = funs[i].fun;
|
||||
}
|
||||
}
|
@ -1,74 +0,0 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "symbol_table.h"
|
||||
|
||||
int main(void){
|
||||
char *prim = strdup("primitive");
|
||||
char *inte = strdup("integer");
|
||||
SymbolTable * parant = CreateScope(NULL, 1,1);
|
||||
char *boole = strdup("Boolean");
|
||||
char *chare = strdup("character");
|
||||
char *str = strdup("string");
|
||||
char *arg = strdup("arg");
|
||||
char *one_to_char = strdup("1 -> character");
|
||||
char *int_to_int = strdup("integer -> integer");
|
||||
char *int2int = strdup("int2int");
|
||||
char *str_to_int = strdup("string -> integer");
|
||||
char *str2int = strdup("string2int");
|
||||
char *square = strdup("square");
|
||||
char *string2int = strdup("string2int");
|
||||
char *entry = strdup("entry");
|
||||
char *x = strdup("x");
|
||||
char *input = strdup("input");
|
||||
char *expected = strdup("expected");
|
||||
char *actual = strdup("actual");
|
||||
char *$_und_type = strdup("$_undefined_type");
|
||||
char *result = strdup("result");
|
||||
char *BOO = strdup("BOO");
|
||||
char *YAZOO = strdup("YAZOO");
|
||||
|
||||
CreateEntry(parant, prim, boole);
|
||||
CreateEntry(parant, prim, chare);
|
||||
CreateEntry(parant, prim, inte);
|
||||
CreateEntry(parant, one_to_char, str);
|
||||
CreateEntry(parant, int_to_int, int2int);
|
||||
CreateEntry(parant, str_to_int, str2int);
|
||||
CreateEntry(parant, int2int, square);
|
||||
CreateEntry(parant, string2int, entry);
|
||||
SymbolTable * child = CreateScope(parant, 14,14);
|
||||
CreateEntry(child, inte, x);
|
||||
SymbolTable * second = CreateScope(parant, 21,15);
|
||||
CreateEntry(second, str, arg);
|
||||
CreateEntry(second, inte, input);
|
||||
CreateEntry(second, inte, expected);
|
||||
CreateEntry(second, inte, actual);
|
||||
CreateEntry(second, $_und_type, result);
|
||||
SymbolTable * third = CreateScope(second, 33,44);
|
||||
CreateEntry(third, BOO, arg);
|
||||
CreateEntry(third, YAZOO, input);
|
||||
|
||||
TableNode *ret = table_lookup(third, "arg");
|
||||
printf("%s == %s\n", ret->theName, "arg");
|
||||
|
||||
ret = table_lookup(third, "hello");
|
||||
printf("This should be nil %p != %s\n", ret, "BOO");
|
||||
|
||||
ret = look_up(second, "input");
|
||||
printf("%s == %s\n", ret->theName, "input");
|
||||
|
||||
ret = look_up(second, "square");
|
||||
printf("%s == %s\n", ret->theName, "square");
|
||||
|
||||
ret = look_up(second, "spuare");
|
||||
printf("This should be nil %p == %s\n", ret, "square");
|
||||
|
||||
print_symbol_table(parant, stderr);
|
||||
free(inte);
|
||||
free(boole);
|
||||
free(prim);
|
||||
free(str);
|
||||
free(chare);
|
||||
free(arg);
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,41 +0,0 @@
|
||||
%{
|
||||
#include <stdio.h> /* For printf, etc. */
|
||||
#include <math.h> /* For pow, used in the grammar. */
|
||||
#include "calc.h" /* Contains definition of 'symrec'. */
|
||||
int yylex (void);
|
||||
void yyerror (char const *);
|
||||
%}
|
||||
%define api.value.type union /* Generate YYSTYPE from these types: */
|
||||
%token <double> NUM /* Double precision number. */
|
||||
%token <symrec*> VAR FUN /* Symbol table pointer: variable/function. */
|
||||
%nterm <double> exp
|
||||
%precedence '='
|
||||
%left '-' '+'
|
||||
%left '*' '/'
|
||||
%precedence NEG /* negation--unary minus */
|
||||
%right '^' /* exponentiation */
|
||||
%% /* The grammar follows. */
|
||||
input:
|
||||
%empty
|
||||
| input line
|
||||
;
|
||||
line:
|
||||
'\n'
|
||||
| exp '\n' { printf ("%.10g\n", $1); }
|
||||
| error '\n' { yyerrok; }
|
||||
;
|
||||
exp:
|
||||
NUM
|
||||
| VAR { $$ = $1->value.var; }
|
||||
| VAR '=' exp { $$ = $3; $1->value.var = $3; }
|
||||
| FUN '(' exp ')' { $$ = $1->value.fun ($3); }
|
||||
| exp '+' exp { $$ = $1 + $3; }
|
||||
| exp '-' exp { $$ = $1 - $3; }
|
||||
| exp '*' exp { $$ = $1 * $3; }
|
||||
| exp '/' exp { $$ = $1 / $3; }
|
||||
| '-' exp %prec NEG { $$ = -$2; }
|
||||
| exp '^' exp { $$ = pow ($1, $3); }
|
||||
| '(' exp ')' { $$ = $2; }
|
||||
;
|
||||
/* End of grammar. */
|
||||
%%
|
35
tests/sprint2/test/sp2_carls_mistake.alpha
Normal file
35
tests/sprint2/test/sp2_carls_mistake.alpha
Normal file
@ -0,0 +1,35 @@
|
||||
type rec: [integer: x; integer: y]
|
||||
|
||||
type T1: integer -> integer
|
||||
type T2: rec -> integer
|
||||
type arr: 1 -> integer
|
||||
|
||||
type main: string -> integer
|
||||
function entry: main
|
||||
function foo: T1
|
||||
function bar1: T2
|
||||
function bar2: T2
|
||||
|
||||
foo (x) := {
|
||||
return x * x;
|
||||
}
|
||||
|
||||
bar1 (x, y) := {
|
||||
return x * y;
|
||||
}
|
||||
|
||||
bar2 (r,s) := {
|
||||
return 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.x := 5;
|
||||
w.y := 7;
|
||||
ressult := 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;
|
||||
}
|
||||
|
21
tests/sprint2/test/sp2_function_types.alpha
Normal file
21
tests/sprint2/test/sp2_function_types.alpha
Normal file
@ -0,0 +1,21 @@
|
||||
type Boolean2Boolean: Boolean -> Boolean
|
||||
type integer2integer: integer -> integer
|
||||
type character2integer: character -> integer
|
||||
type Boolean2integer: Boolean -> integer
|
||||
type string2integer: string -> integer
|
||||
|
||||
type integer2integer2Boolean: integer2integer -> Boolean
|
||||
type character2character2Boolean: character2character -> Boolean
|
||||
type Boolean2Boolean2Boolean: Boolean2Boolean -> Boolean
|
||||
type integer2address: integer -> address
|
||||
type address2integer: address -> integer
|
||||
type integer2integer2integer: integer2integer -> integer
|
||||
|
||||
external function printInteger: integer2integer
|
||||
external function printCharacter: character2integer
|
||||
external function printBoolean: Boolean2integer
|
||||
external function reserved: integer2address
|
||||
external function released: address2integer
|
||||
|
||||
function integer2integer2integerFunc: integer2integer2integer
|
||||
function entry: string2integer
|
@ -1,12 +1,18 @@
|
||||
entry(arg) := {
|
||||
[integer:x; address: arr; address: arr2; Boolean : b2; Boolean : b1]
|
||||
x := 3 + 2 * 8;
|
||||
x := 3 - 2 / 8;
|
||||
x := 3 * 2 % 8;
|
||||
x := 3 * 2 % 8;
|
||||
x := 3 % 2 * 8;
|
||||
x := 3 + 2 - 8;
|
||||
arr2 := 1 * reserve x;
|
||||
type main: string -> integer
|
||||
function entry: main
|
||||
type testarr : 1 -> integer
|
||||
|
||||
entry (arg) := {
|
||||
[integer:x; testarr: arr; testarr: arr2; Boolean : b2; Boolean : b1]
|
||||
|
||||
x := 3 + 2 * 8;
|
||||
x := 3 - 2 / 8;
|
||||
x := 3 * 2 % 8;
|
||||
x := 3 * 2 % 8;
|
||||
x := 3 % 2 * 8;
|
||||
x := 3 + 2 - 8;
|
||||
|
||||
arr2 := 1 * reserve x;
|
||||
arr2 := release x;
|
||||
b2 := 3 < 2;
|
||||
b1 := 1 = 2;
|
||||
|
@ -0,0 +1,7 @@
|
||||
type rec: [integer: x; integer: y]
|
||||
type main: rec -> integer
|
||||
function test: main
|
||||
|
||||
test (arg, arg2) := {
|
||||
return 0;
|
||||
}
|
13
tests/sprint2/test/sp2_invalid_recop.alpha
Normal file
13
tests/sprint2/test/sp2_invalid_recop.alpha
Normal file
@ -0,0 +1,13 @@
|
||||
type main: string -> integer
|
||||
function entry: main
|
||||
|
||||
type rec: [integer: x; integer: y]
|
||||
|
||||
entry (arg) := {
|
||||
[rec: w]
|
||||
w := reserve w;
|
||||
w.x := 1;
|
||||
w.y := 2;
|
||||
w.z := 3;
|
||||
return 0;
|
||||
}
|
8
tests/sprint2/test/sp2_invalid_release.alpha
Normal file
8
tests/sprint2/test/sp2_invalid_release.alpha
Normal file
@ -0,0 +1,8 @@
|
||||
type rec: [integer: x; integer: y]
|
||||
|
||||
entry (arg) := {
|
||||
[rec: w]
|
||||
w := reserve w;
|
||||
w := release (w);
|
||||
return 0;
|
||||
}
|
@ -1,15 +1,18 @@
|
||||
(* At compiler start-up your program should create symbol table entries for the four primitive types:
|
||||
Boolean (1 byte)
|
||||
character (1 byte)
|
||||
integer (4 bytes)
|
||||
address (8 bytes)
|
||||
You should #include this file at the start of your alpha file.
|
||||
Some useful types are defined below.
|
||||
(*
|
||||
At compiler start-up your program should create symbol table entries for the four primitive types:
|
||||
Boolean (1 byte)
|
||||
character (1 byte)
|
||||
integer (4 bytes)
|
||||
address (8 bytes)
|
||||
|
||||
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
|
||||
@ -22,9 +25,9 @@ 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
|
||||
|
@ -1,3 +1,6 @@
|
||||
type main: string -> integer
|
||||
function entry: main
|
||||
|
||||
type rec: [integer: x; integer: y]
|
||||
type T1: integer -> integer
|
||||
type T2: rec -> integer
|
||||
@ -9,66 +12,69 @@ 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 {
|
||||
return null;
|
||||
} else {
|
||||
ret := reserve llnode;
|
||||
ret.prev := null;
|
||||
ret.next := null;
|
||||
ret.val := a;
|
||||
while (0 < a) {
|
||||
temp := reserve llnode;
|
||||
temp.prev := null;
|
||||
temp.next := null;
|
||||
temp.val := val;
|
||||
if (a = orig_a) then {
|
||||
ret.next := temp;
|
||||
temp.prev := ret;
|
||||
curr := temp;
|
||||
} else {
|
||||
curr.next := temp;
|
||||
temp.prev := curr;
|
||||
curr := temp;
|
||||
}
|
||||
a := a - 1;
|
||||
}
|
||||
return ret;
|
||||
|
||||
make_list (a) := {
|
||||
[integer:orig_a; llnode: ret; llnode: curr; llnode: temp]
|
||||
|
||||
if (a < 0 | a = 0) then {
|
||||
return null;
|
||||
} else {
|
||||
ret := reserve ret;
|
||||
ret.prev := null;
|
||||
ret.next := null;
|
||||
ret.val := a;
|
||||
while (0 < a) {
|
||||
temp := reserve temp;
|
||||
temp.prev := null;
|
||||
temp.next := null;
|
||||
temp.val := ret.val;
|
||||
if (a = orig_a) then {
|
||||
ret.next := temp;
|
||||
temp.prev := ret;
|
||||
curr := temp;
|
||||
} else {
|
||||
curr.next := temp;
|
||||
temp.prev := curr;
|
||||
curr := temp;
|
||||
}
|
||||
a := a - 1;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
foo(x) := {
|
||||
return x * x;
|
||||
}
|
||||
bar1(a) := {
|
||||
return a.x * a.y;
|
||||
}
|
||||
|
||||
bar2 as (r,s) := {
|
||||
if (r < s) then {
|
||||
while (!(r < s)) {
|
||||
r := r + 1;
|
||||
}
|
||||
} else {
|
||||
[integer: x]
|
||||
x := 0;
|
||||
while (x < 10) {
|
||||
r := r + s;
|
||||
}
|
||||
}
|
||||
return r * s;
|
||||
}
|
||||
entry(arg) := {
|
||||
[ integer: result ; rec: w; llnode: li]
|
||||
li := make_list(6);
|
||||
result := foo(5);
|
||||
w := reserve w;
|
||||
w.x := 5;
|
||||
w.y := 7;
|
||||
result := bar1(w);
|
||||
result := bar2(5,7);
|
||||
|
||||
return 0;
|
||||
foo (x) := {
|
||||
return x * x;
|
||||
}
|
||||
|
||||
bar1(a,b) := {
|
||||
return a * b;
|
||||
}
|
||||
|
||||
bar2(r,s) := {
|
||||
if (r < s) then {
|
||||
while (!(r < s)) {
|
||||
r := r + 1;
|
||||
}
|
||||
} else {
|
||||
[integer: x]
|
||||
x := 0;
|
||||
while (x < 10) {
|
||||
r := r + s;
|
||||
}
|
||||
}
|
||||
return r * s;
|
||||
}
|
||||
|
||||
entry (arg) := {
|
||||
[ integer: result ; rec: w; llnode: li]
|
||||
li := make_list(6);
|
||||
result := foo(5);
|
||||
w := reserve w;
|
||||
w.x := 5;
|
||||
w.y := 7;
|
||||
result := bar1(w);
|
||||
result := bar2(5,7);
|
||||
|
||||
return 0;
|
||||
}
|
@ -1 +1 @@
|
||||
type rec: [integer: x; integer: y] type T1: integer -> integer type T2: rec -> integer function foo : T1 function bar1 : T2 function bar2 : T2 foo(x) := { return x * x; } bar1(a) := { return a.x * a.y; } bar2 as (r,s) := { return r * s; } entry(arg) := { [ integer: result ; rec: w] result := foo(5); w := reserve w; w.x := 5; w.y := 7; result := bar1(w); result := bar2(5,7); return 0; }
|
||||
type main: string -> integer function entry: main type rec: [integer: x; integer: y] type T1: integer -> integer type T2: rec -> integer function foo : T1 function bar1 : T2 function bar2 : T2 foo(x) := { return x * x; } bar1(a) := { return a.x * a.y; } bar2 as (r,s) := { return r * s; } entry(arg) := { [ integer: result ; rec: w] result := foo(5); w := reserve w; w.x := 5; w.y := 7; result := bar1(w); result := bar2(5,7); return 0; }
|
||||
|
@ -1,4 +1,10 @@
|
||||
entry(arg) := {
|
||||
[integer:x]
|
||||
x := 3 + 2 * 8;
|
||||
type main: string -> integer
|
||||
type rec: [integer: rec_x; integer: rec_y]
|
||||
|
||||
function entry: main
|
||||
|
||||
entry (arg) := {
|
||||
[integer: arg_x; integer: arg_y; rec: arg_record; Boolean: arg_bool]
|
||||
arg_x := 3 + 2 * 8;
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,5 +1,7 @@
|
||||
type main: string -> integer
|
||||
function entry: main
|
||||
|
||||
entry(arg) := {
|
||||
[int : x]
|
||||
return 0;
|
||||
}
|
||||
[integer : x]
|
||||
return 2;
|
||||
}
|
16
tests/sprint2/test/sp2_sp2_arrayargs.alpha
Normal file
16
tests/sprint2/test/sp2_sp2_arrayargs.alpha
Normal file
@ -0,0 +1,16 @@
|
||||
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 ]
|
||||
another_name := reserve another_name(4); (* reserve space for an an array of character, with 4 members *)
|
||||
many_names := reserve a_of_s(many_names);
|
||||
many_names(0) := one_name;
|
||||
many_names(1) := another_name;
|
||||
many_names(2) := reserve a_of_s(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";
|
||||
|
||||
return 0;
|
||||
}
|
16
tests/sprint2/test/sp2_sp2_arrayargs.alpha~
Normal file
16
tests/sprint2/test/sp2_sp2_arrayargs.alpha~
Normal file
@ -0,0 +1,16 @@
|
||||
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 ]
|
||||
another_name := reserve another_name(4); (* reserve space for an an array of character, with 4 members *)
|
||||
many_names := reserve a_of_s(3);
|
||||
many_names(0) := one_name;
|
||||
many_names(1) := another_name;
|
||||
many_names(2) := reserve a_of_s(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";
|
||||
|
||||
return 0;
|
||||
}
|
16
tests/sprint2/test/sp2_valid_assignable_and_mem.alpha
Normal file
16
tests/sprint2/test/sp2_valid_assignable_and_mem.alpha
Normal file
@ -0,0 +1,16 @@
|
||||
type main: string -> integer
|
||||
function entry: main
|
||||
|
||||
type rec: [integer: x; integer: y]
|
||||
type T2: rec -> integer
|
||||
|
||||
entry(arg) := {
|
||||
[rec: w]
|
||||
|
||||
w := reserve w;
|
||||
w.x := 1;
|
||||
w.y := 2;
|
||||
w := release w;
|
||||
|
||||
return 0;
|
||||
}
|
50
tests/sprint3/expected/sp3_and_or_type_check.expected
Normal file
50
tests/sprint3/expected/sp3_and_or_type_check.expected
Normal file
@ -0,0 +1,50 @@
|
||||
001: type rec: [integer: x; integer: y]
|
||||
002: type main: rec -> integer
|
||||
003: function test: main
|
||||
004:
|
||||
005: test (arg) := {
|
||||
006: [integer:x; Boolean: b]
|
||||
007: while (true) {
|
||||
008: x := 0;
|
||||
009: }
|
||||
010:
|
||||
011: while (7) {
|
||||
012: x := 1;
|
||||
013: }
|
||||
014:
|
||||
015: if (true) then {
|
||||
016: x := 1;
|
||||
017: } else {
|
||||
018: x := 0;
|
||||
019: }
|
||||
020:
|
||||
021: if (x) then {
|
||||
022: x := 0;
|
||||
023: } else {
|
||||
024: x := 1;
|
||||
025: }
|
||||
026:
|
||||
027: b := b | b;
|
||||
028: b := b & b;
|
||||
029: b := 1 | b;
|
||||
LINE (29:12) ** TYPE ERROR: b != undefined
|
||||
|
||||
030: b := b | 1;
|
||||
LINE (30:12) ** TYPE ERROR: b != undefined
|
||||
|
||||
031: b := b & 1;
|
||||
LINE (31:12) ** TYPE ERROR: b != undefined
|
||||
|
||||
032: b := 1 & b;
|
||||
LINE (32:12) ** TYPE ERROR: b != undefined
|
||||
|
||||
033: b := 1 = 1;
|
||||
034:
|
||||
035:
|
||||
036:
|
||||
037: b := 1 = b;
|
||||
LINE (37:12) ** TYPE ERROR: b != undefined
|
||||
|
||||
038:
|
||||
039: return 0;
|
||||
040: }
|
@ -0,0 +1,16 @@
|
||||
001: type main: string -> integer
|
||||
002: function entry: main
|
||||
003:
|
||||
004: entry (arg) := {
|
||||
005: [integer:x; address: arr; address: arr2; Boolean : b2; Boolean : b1]
|
||||
006:
|
||||
007: b2 := 3 < x;
|
||||
008: b1 := arr = 2;
|
||||
LINE (8:18) ** TYPE ERROR: b1 != undefined
|
||||
|
||||
009: b1 := 6<7 & arr2=7;
|
||||
LINE (9:23) ** TYPE ERROR: b1 != undefined
|
||||
|
||||
010:
|
||||
011: return 0;
|
||||
012: }
|
@ -0,0 +1,13 @@
|
||||
001: type main: string -> integer
|
||||
002: function entry: main
|
||||
003:
|
||||
004: entry (arg) := {
|
||||
005: [integer:x; address: arr; address: arr2; Boolean : b2; Boolean : b1]
|
||||
006:
|
||||
007: b2 := !(3 < 2);
|
||||
008: b1 := !5;
|
||||
LINE (8:13) ** TYPE ERROR: b1 != undefined
|
||||
|
||||
009:
|
||||
010: return 0;
|
||||
011: }
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user