diff --git a/.gitignore b/.gitignore index a6fca1a..0416ca8 100644 --- a/.gitignore +++ b/.gitignore @@ -8,4 +8,5 @@ grammar.tab.h out tmp parser -*.save \ No newline at end of file +*.save +binaries \ No newline at end of file diff --git a/Makefile b/Makefile index 6fefed1..3e6cbc7 100644 --- a/Makefile +++ b/Makefile @@ -3,19 +3,15 @@ CC := gcc FLEX := flex BISON = bison -CFLAGS := -ggdb -BISONFLAGS := -d +CFLAGS := -ggdb -g -O0 #-fsanitize=address +# LDFLAGS := -fsanitize=address +BISONFLAGS := -d -Wcounterexamples LEX := src/lexicalStructure.lex YACC := src/grammar.y EXE := alpha 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) # ---------- @@ -24,11 +20,14 @@ TESTS-S4 := $(wildcard tests/sprint4/test/*.alpha) all: compiler compiler: clean tmp $(OBJS) - $(CC) $(CFLAGS) -o $(EXE) $(OBJS) + $(CC) $(CFLAGS) -o $(EXE) $(OBJS) $(LDFLAGS) + chmod +x ./genx.sh + chmod +x ./test.sh clean: rm -f $(EXE) rm -rf out + rm -rf binaries rm -rf tmp rm -f *.s rm -f *.out @@ -70,35 +69,36 @@ tmp/runner.o: src/runner.c src/runner.h tmp/flex.h tmp/grammar.tab.h # ----- 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 + chmod +x ./genx.sh + ./test.sh tests/sprint1/test/ -diff + ./test.sh tests/sprint2/test/ -diff + ./test.sh tests/sprint3/test/ -diff + ./test.sh tests/sprint4/test/ -diff + ./test.sh tests/given/test/ -diff test-s1: - chmod +x ./check.sh chmod +x ./test.sh - $(foreach test, $(TESTS-S1), (./$(EXE) -tok -debug $(test) || true);) - ./check.sh sp1 + chmod +x ./genx.sh + ./test.sh tests/sprint1/test/ -diff test-s2: - chmod +x ./check.sh chmod +x ./test.sh - ./test.sh sp2 - ./check.sh sp2 + chmod +x ./genx.sh + ./test.sh tests/sprint2/test/ -diff test-s3: - chmod +x ./check.sh chmod +x ./test.sh - ./test.sh sp3 - ./check.sh sp3 + chmod +x ./genx.sh + ./test.sh tests/sprint3/test/ -diff test-s4: - chmod +x ./check.sh chmod +x ./test.sh - ./test.sh sp4 - ./check.sh sp4 + chmod +x ./genx.sh + ./test.sh tests/sprint4/test/ -diff + +test-given: + chmod +x ./test.sh + chmod +x ./genx.sh + ./test.sh tests/given/test/ -diff # ----------- \ No newline at end of file diff --git a/README.MD b/README.MD index 525582f..365595f 100644 --- a/README.MD +++ b/README.MD @@ -1,17 +1,89 @@ # The Translators α Compiler #### Members: Annie Slenker, Meyer Simon, Partho Bhattacharya, & Scarlett Kadan -## Lexical Analyzer -* **Undefined Behavior:** - * Spaces are not required between tokens. For instance, an INTEGER and an ID are valid even if there is no space between them +## Alpha Compiler Flags & Expected Results: +### -tok +Prints the token stream provided by the Lexical Analyzer to a `.tok` file. Output can be found in `/out/.tok`. Tokenization follows the specified format found in the alpha language spec. + +### -st +Prints the symbol table to a file. Follows the format provided in the alpha language spec. if the `-ir` flag is also present, the symbol table will print out temporary variables. Output can be found in `out/.st`. + +### -asc +Prints the annotated alpha source code to a file. Will display any syntax errors that are present below the line they occur on. If more than one error is present, the messages will stack. Output can be found in `out/.asc`. + +### -tc +Throws type check errors to the asc output file. If the `-asc` flag is not present, no errors will be displayed. Output can be found in `out/.asc` + +### -ir +Prints the intermediate code representation stream to a file. Output can be found in `out/.ir`. This flag modifies the `-st` flag, allowing for temporary variables to print out. + +### -cg +Prints the alpha program's unique x86 assembly to a `.s` file. Assembly stream is valid x86 code that can be assembled and linked with other .s files. Output can be found in `out/.s` + +### -debug +Prints debug messages to the console if present. Our debug messages utilizes a wrapper function for `printf()` called `printdebug()`. This allows for us to file names, code lines, and colors! + +### -help +Prints a general help message. (If you read this far, you probably won't need this flag) + + +## Alpha Tools: Testing & Building +We have built a few tools to aid in the development processes. These include `./test.sh` and `./genx.sh`. Below you can find information about each. + +### ./test.sh +All tests under sprint 1, 2, 3, & 4 will work with the testing suite, along with running it directly with the alpha executable. These files do not use the `#include` directive, instead opting to define everything used within the file. +> **Arguments:**
+> `-exp` Generate expected output files
+> `-diff` Compare output files with expected output files
+> `-help` Show this help message
+ +> **Usage:**
+> `./test.sh [flags]` Run the test on a single file
+> `./test.sh [flags]` Run the test on all files in a directory
+ +> **Examples:**
+> `./test.sh test.alpha` Runs test flags in header on test.alpha
+> `./test.sh test/` Runs test flags in header on all .alpha files in test/
+> `./test.sh test/ -exp` Runs test flags in header on all .alpha files in test/ and generates expected output files
+> `./test.sh test/ -diff` Runs test flags in header on all .alpha files in test/ and compares output files with expected output files
+> `./test.sh test/ -exp -diff` Runs test flags in header on all .alpha files in test/ and generates expected output files and compares output files with expected output files
+ +> **Notes:**
+> To create a test file, on the first line of the .alpha file, add:
+> `(* TEST: [ ] *)`
+> where are the alpha flags to be used. Ex:
+> `(* TEST: [ -debug -asc -tc ] *)`
+ +### ./genx.sh +GenX is our preprocessor tool. It is able to handle `#include` statements within an alpha file. The tool allows for includes of `.alpha`, `.s`, and `.c` files, given a relative path to them. You can also include our library file `std.alpha` which does not require a relative path.
+ +**NOTE:** *Due to the nature of include statements, running the alpha compiler on alpha files that use include statements will most likely result in syntax/type errors. When dealing with a file with include statements, it is advised to use GenX.*
+ +*You can also use the following command to preprocess a file:* `cpp -P -x c -o simple.cpp.alpha simple.alpha` + +> **Arguments:**
+> `-help` Displays this message
+ +> **Usage:**
+> `./genx.sh `
Generates executable file from
+ +> **Notes:**
+> Generates .s and links alpha driver and general library and other includes.
+ +## Other Notes: + +### Lexical Analyzer: +**Undefined Behavior:**
+* Spaces are not required between tokens. For instance, an INTEGER and an ID are valid even if there is no space between them ``` Input: *5variable* Output: 2 14 301 "5" 1 1 101 "variable" ``` +* Added an `#include` token to stop syntax errors from being reported on certain alpha files. -## Syntax Analyzer -* *Incomplete* - -## Symbol Table -* *TODO: Create diagram.* \ No newline at end of file +### CG/IR Not Implemented: +* Arrays +* And conditionals not tested +* While loops may or may not be working (More testing needed) +* *...and other small issues* \ No newline at end of file diff --git a/check.sh b/check.sh deleted file mode 100755 index cf7c946..0000000 --- a/check.sh +++ /dev/null @@ -1,67 +0,0 @@ -#!/bin/bash - -# Diff-Check Tool # -# Checks if outputed TOK = exp # -# 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 -e "${RED}[ERROR] ${YELLOW}Directory $TOK_DIR does not exist.${NOCOLOR}" - exit 1 -fi - -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 \ No newline at end of file diff --git a/genx.sh b/genx.sh new file mode 100755 index 0000000..a1a9bd4 --- /dev/null +++ b/genx.sh @@ -0,0 +1,234 @@ +#!/bin/bash + +# GenX 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' + +alphaToInclude=() +cToInclude=() +sToInclude=() +cToBuild=() +sToInclude+=("library/alpha_lib_reg.s") +sToInclude+=("library/alpha_driver.s") +sToInclude+=("library/std.s") +sToInclude+=("library/boundscheck.s") + +filename="" +s_name="" +backup_file="" + +# -{ FUNC }----------------------------------------------------# + +help() { + echo -e "${WHITE}-----{ ${BLUE}GenX.sh Help ${WHITE}}-----\n" + echo -e "${YELLOW} Arguments: ${WHITE}" + echo -e "${GREEN} -help ${WHITE} Displays this message\n" + echo -e "${YELLOW} Usage: ${WHITE}" + echo -e "${GREEN} ./genx.sh ${WHITE} Generates executable file from \n" + echo -e "${YELLOW} Notes: ${WHITE}" + echo -e "${ORANGE} Generates .s and links alpha driver and general library and other includes.\n" + echo -e "${WHITE}-----------------------------------------\n" +} + +printLists() { + echo -e "${GREEN}[GenX] ${WHITE}Alpha files to include: ${BLUE}${alphaToInclude[@]}${WHITE}" + echo -e "${GREEN}[GenX] ${WHITE}C files to include: ${BLUE}${cToInclude[@]}${WHITE}" + echo -e "${GREEN}[GenX] ${WHITE}C files to build: ${BLUE}${cToBuild[@]}${WHITE}" + echo -e "${GREEN}[GenX] ${WHITE}S files to include: ${BLUE}${sToInclude[@]}${WHITE}" +} + +getIncludes() { + while IFS= read -r line || [ -n "$line" ]; do + if [[ $line =~ ^#include\ \"[^\"]+\" ]]; then + between_quotes=$(echo "$line" | sed -n 's/.*"\([^"]*\)".*/\1/p') + extension="${between_quotes##*.}" + sed -i "\|$line|d" "$1" + + if [[ $between_quotes == *".alpha" ]]; then + path=$(dirname "$1") + alpha_file=${path}"/"${between_quotes} + + if [[ -f "library/$between_quotes" ]]; then + alphaToInclude+=("library/${between_quotes}") + + elif [[ -f $alpha_file ]]; then + alphaToInclude+=("$alpha_file") + + else + echo -e "${RED}[GenX] ${YELLOW}File $between_quotes not found!${WHITE}" + restoreFileFromBackup "$1" + exit 1 + fi + + elif [[ $between_quotes == *".c" ]]; then + path=$(dirname "$1") + c_file=${path}"/"${between_quotes} + if [[ -f $c_file ]]; then + cToBuild+=("$c_file") + else + echo -e "${RED}[GenX] ${YELLOW}File $between_quotes not found!${WHITE}" + restoreFileFromBackup "$1" + exit 1 + fi + + elif [[ $between_quotes == *".s" ]]; then + path=$(dirname "$1") + s_file=${path}"/"${between_quotes} + if [[ -f $s_file ]]; then + sToInclude+=("$s_file") + else + echo -e "${RED}[GenX] ${YELLOW}File $between_quotes not found!${WHITE}" + restoreFileFromBackup "$1" + exit 1 + fi + + else + echo -e "${RED}[GenX] ${YELLOW}Not able to include file type $extension!${WHITE}" + exit 1 + fi + fi + + done < "$1" +} + + +ass_c() { + for c in "${cToBuild[@]}"; do + if [ -f "$c" ]; then + c_file_ass=$(basename "$c" .c) + c_file_ass=out/$c_file_ass.s + cToInclude+=($c_file_ass) + gcc -S $c -o $c_file_ass + else + echo -e "${RED}[GenX] ${YELLOW}File $c not found!${WHITE}" + exit 1 + fi + done +} + + +appendStr() { + for alpha_file in "${alphaToInclude[@]}"; do + if [ -f "$alpha_file" ]; then + temp_file=$(mktemp) + cat "$alpha_file" > "$temp_file" + cat "$1" >> "$temp_file" + mv "$temp_file" "$1" + else + echo -e "${RED}[GenX] ${YELLOW}File $alpha_file not found!${WHITE}" + fi + done +} + +ass() { + sToInclude_string=$(printf "%s " "${sToInclude[@]}") + cToInclude_string=$(printf "%s " "${cToInclude[@]}") + gcc "$1" ${cToInclude_string} ${sToInclude_string} -no-pie -o binaries/${2} + if [ $? -eq 0 ]; then + echo -e "${GREEN}[GenX] ${WHITE}Done!" + else + echo -e "${RED}[GenX] ${YELLOW}Error generating executable file!${WHITE}" + exit 1 + fi +} + +restoreFileFromBackup() { + if [[ -f "$backup_file" ]]; then + cp "$backup_file" "$1" + rm "$backup_file" + else + echo -e "${RED}[GenX] ${YELLOW}Backup file not found!${WHITE}" + fi + +} + +# ----------------------------------------------------{ FUNC }-# + + + +# -{ INIT }----------------------------------------------------# + +if [ ! -f "./alpha" ]; then + echo -e "${RED}[GenX] ${YELLOW}File ./alpha not found! Generating with 'make'.${WHITE}" + make +fi + +if [ $# -eq 0 ]; then + help +fi + +if [ ! -d "binaries" ]; then + mkdir -p binaries +fi + +# ----------------------------------------------------{ INIT }-# + + + +# -{ RUNNER }--------------------------------------------------# + +if [ $# -eq 1 ]; then + if [ -f "$1" ]; then + filename=$(basename -- "$1") + backup_file="${1}.bak" + cp "$1" "$backup_file" + + if [[ "$1" == *.alpha ]]; then + filename="${filename:0:${#filename}-6}" + s_name="out/${filename}.s" + + getIncludes "$1" + appendStr "$1" + ./alpha -ir -tc -asc -cg -st -tok "$1" + + # include a grep here of asc to see if there are any errors + + echo -e "${GREEN}[GenX] ${WHITE}Generated .s file." + restoreFileFromBackup "$1" + ass_c + ass "$s_name" "$filename" + printLists + exit 1 + + elif [[ "$1" == *.s ]]; then + echo -e "${GREEN}[GenX] ${WHITE}File $1 is a .s file! (Skipping compiler)${WHITE}" + filename="${filename:0:${#filename}-2}" + s_name="out/${filename}.s" + ass "$s_name" "$filename" + restoreFileFromBackup "$1" + exit 1 + + else + echo -e "${RED}[GenX] ${YELLOW}File $1 is not a .alpha file!${WHITE}" + restoreFileFromBackup "$1" + exit 1 + + fi + + else + echo -e "${RED}[GenX] ${YELLOW}File $1 not found!${WHITE}" + restoreFileFromBackup "$1" + exit 1 + fi + +else + help + exit 1 +fi + +# --------------------------------------------------{ RUNNER }-# diff --git a/library/alpha_driver.s b/library/alpha_driver.s new file mode 100644 index 0000000..0092d30 --- /dev/null +++ b/library/alpha_driver.s @@ -0,0 +1,81 @@ + .file "alpha_driver.c" + .text + .globl main + .type main, @function +main: +.LFB0: + endbr64 + pushq %rbp + movq %rsp, %rbp + subq $48, %rsp + movl %edi, -36(%rbp) + movq %rsi, -48(%rbp) + movl $0, -32(%rbp) + cmpl $1, -36(%rbp) + jle .L2 + movq -48(%rbp), %rax + addq $8, %rax + movq (%rax), %rax + movq %rax, %rdi + call strlen@PLT + movl %eax, -32(%rbp) +.L2: + movl -32(%rbp), %eax + cltq + addq $4, %rax + movq %rax, %rdi + call malloc@PLT + movq %rax, -16(%rbp) + movq -16(%rbp), %rax + movq %rax, -24(%rbp) + movq -24(%rbp), %rax + movl -32(%rbp), %edx + movl %edx, (%rax) + cmpl $1, -36(%rbp) + jle .L3 + addq $4, -24(%rbp) + movq -48(%rbp), %rax + movq 8(%rax), %rax + movq %rax, -8(%rbp) + movl $0, -28(%rbp) + jmp .L4 +.L5: + movl -28(%rbp), %eax + movslq %eax, %rdx + movq -8(%rbp), %rax + addq %rdx, %rax + movzbl (%rax), %edx + movq -24(%rbp), %rax + movb %dl, (%rax) + addq $1, -24(%rbp) + addl $1, -28(%rbp) +.L4: + movl -28(%rbp), %eax + cmpl -32(%rbp), %eax + jl .L5 +.L3: + movq -16(%rbp), %rax + movq %rax, %rdi + call entry@PLT + leave + ret +.LFE0: + .size main, .-main + .ident "GCC: (Ubuntu 9.4.0-1ubuntu1~20.04.1) 9.4.0" + .section .note.GNU-stack,"",@progbits + .section .note.gnu.property,"a" + .align 8 + .long 1f - 0f + .long 4f - 1f + .long 5 +0: + .string "GNU" +1: + .align 8 + .long 0xc0000002 + .long 3f - 2f +2: + .long 0x3 +3: + .align 8 +4: diff --git a/library/alpha_lib_reg.s b/library/alpha_lib_reg.s new file mode 100644 index 0000000..c8be988 --- /dev/null +++ b/library/alpha_lib_reg.s @@ -0,0 +1,115 @@ + .file "alpha_lib.c" + .section .rodata +.LC0: + .string "%d" + + .text + .globl printInteger + .type printInteger, @function +printInteger: +.LFB2: + pushq %rbp # push old base pointer + movq %rsp, %rbp # move base pointer + + subq $16, %rsp # make room on stack + movl %edi, -4(%rbp) # spill arg to stack + movl -4(%rbp), %eax # move argument to %eax + movl %eax, %esi + movl $.LC0, %edi + movl $0, %eax + call printf + movl $0, %eax + leave + ret +.LFE2: + .size printInteger, .-printInteger + + .globl printCharacter + .type printCharacter, @function +printCharacter: +.LFB4: + pushq %rbp + movq %rsp, %rbp + + subq $16, %rsp + movb %dil, %al + movb %al, -4(%rbp) + movsbl -4(%rbp), %eax + movl %eax, %edi + call putchar + movl $0, %eax + leave + ret +.LFE4: + .size printCharacter, .-printCharacter + + .section .rodata +.LC2: + .string "false" +.LC3: + .string "true" +.LC4: + .string "%s" + + .text + .globl printBoolean + .type printBoolean, @function +printBoolean: +.LFB5: + pushq %rbp + movq %rsp, %rbp + subq $16, %rsp + movb %dil, -4(%rbp) + cmpb $0, -4(%rbp) + jne .L8 + movl $.LC2, %eax + jmp .L9 +.L8: + movl $.LC3, %eax +.L9: + movq %rax, %rsi + movl $.LC4, %edi + movl $0, %eax + call printf + movl $0, %eax + leave + ret +.LFE5: + .size printBoolean, .-printBoolean + + .globl reserve + .type reserve, @function +reserve: +.LFB8: + pushq %rbp + movq %rsp, %rbp + subq $16, %rsp + movl %edi, -4(%rbp) + movl -4(%rbp), %eax + cltq + movq %rax, %rdi + call malloc + leave + ret +.LFE8: + .size reserve, .-reserve + + .globl release + .type release, @function +release: +.LFB9: + pushq %rbp + movq %rsp, %rbp + subq $16, %rsp + movq %rdi, -8(%rbp) + movq -8(%rbp), %rax + movq %rax, %rdi + call free + movl $0, %eax + leave + ret +.LFE9: + .size release, .-release + + .ident "GCC: (GNU) 6.4.0" + .section .note.GNU-stack,"",@progbits diff --git a/library/alphastdio.c b/library/alphastdio.c new file mode 100644 index 0000000..f4da2ce --- /dev/null +++ b/library/alphastdio.c @@ -0,0 +1,61 @@ +#include +#include +#include +#include + + + +int printS(char *str) { + if (str == NULL) return -1; + printf("%s", str); + return 0; +} + +char *inS() { + char *buffer = malloc(100); + if (buffer == NULL) return NULL; + if (fgets(buffer, 100, stdin) == NULL) { + free(buffer); + return NULL; + } + buffer[strcspn(buffer, "\n")] = 0; + return buffer; +} + + + +int printI(int i) { + printf("%d", i); + return 0; +} + +int inI() { + int i; + char buffer[100]; + if (fgets(buffer, sizeof(buffer), stdin) == NULL) return 0; + if (sscanf(buffer, "%d", &i) != 1) return 0; + return i; +} + + + +int printC(char c) { + printf("%c", c); + return 0; +} + +char inC() { + char c; + if (scanf(" %c", &c) != 1) return 0; + return c; +} + + + +int printB(bool b) { + if (b) + printf("true"); + else + printf("false"); + return 0; +} \ No newline at end of file diff --git a/library/boundscheck.c b/library/boundscheck.c new file mode 100644 index 0000000..5e6081c --- /dev/null +++ b/library/boundscheck.c @@ -0,0 +1,23 @@ +#include +#include +#include + +int BoundsError(int d){ + printf("You are trying to access memory that isn't yours.\n"); + exit(1); +} + +void BoundsCheck(int argc, void * start, ...){ + va_list argptr; + va_start(argptr, start); + int index = 0; + while (argc){ + argc--; + index = va_arg(argptr, int); + if(index > *(int*)start){ + BoundsError(index); + } + start += sizeof(int); + } + va_end(argptr); +} \ No newline at end of file diff --git a/library/boundscheck.s b/library/boundscheck.s new file mode 100644 index 0000000..36fa414 --- /dev/null +++ b/library/boundscheck.s @@ -0,0 +1,112 @@ + .file "boundscheck.c" + .text + .section .rodata + .align 8 +.LC0: + .string "You are trying to access memory that isn't yours." + .text + .globl BoundsError + .type BoundsError, @function +BoundsError: +.LFB6: + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + subq $16, %rsp + movl %edi, -4(%rbp) + leaq .LC0(%rip), %rax + movq %rax, %rdi + call puts@PLT + movl $1, %edi + call exit@PLT + .cfi_endproc +.LFE6: + .size BoundsError, .-BoundsError + .globl BoundsCheck + .type BoundsCheck, @function +BoundsCheck: +.LFB7: + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + subq $240, %rsp + movl %edi, -228(%rbp) + movq %rsi, -240(%rbp) + movq %rdx, -160(%rbp) + movq %rcx, -152(%rbp) + movq %r8, -144(%rbp) + movq %r9, -136(%rbp) + testb %al, %al + je .L3 + movaps %xmm0, -128(%rbp) + movaps %xmm1, -112(%rbp) + movaps %xmm2, -96(%rbp) + movaps %xmm3, -80(%rbp) + movaps %xmm4, -64(%rbp) + movaps %xmm5, -48(%rbp) + movaps %xmm6, -32(%rbp) + movaps %xmm7, -16(%rbp) +.L3: + movq %fs:40, %rax + movq %rax, -184(%rbp) + xorl %eax, %eax + movl $16, -208(%rbp) + movl $48, -204(%rbp) + leaq 16(%rbp), %rax + movq %rax, -200(%rbp) + leaq -176(%rbp), %rax + movq %rax, -192(%rbp) + movl $0, -212(%rbp) + jmp .L4 +.L8: + subl $1, -228(%rbp) + movl -208(%rbp), %eax + cmpl $47, %eax + ja .L5 + movq -192(%rbp), %rax + movl -208(%rbp), %edx + movl %edx, %edx + addq %rdx, %rax + movl -208(%rbp), %edx + addl $8, %edx + movl %edx, -208(%rbp) + jmp .L6 +.L5: + movq -200(%rbp), %rax + leaq 8(%rax), %rdx + movq %rdx, -200(%rbp) +.L6: + movl (%rax), %eax + movl %eax, -212(%rbp) + movq -240(%rbp), %rax + movl (%rax), %eax + cmpl %eax, -212(%rbp) + jle .L7 + movl -212(%rbp), %eax + movl %eax, %edi + call BoundsError +.L7: + addq $4, -240(%rbp) +.L4: + cmpl $0, -228(%rbp) + jne .L8 + nop + movq -184(%rbp), %rax + subq %fs:40, %rax + je .L9 + call __stack_chk_fail@PLT +.L9: + leave + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE7: + .size BoundsCheck, .-BoundsCheck + .ident "GCC: (GNU) 14.2.1 20250207" + .section .note.GNU-stack,"",@progbits diff --git a/library/std.alpha b/library/std.alpha new file mode 100644 index 0000000..19b278a --- /dev/null +++ b/library/std.alpha @@ -0,0 +1,35 @@ +(* Standard Alpha Library *) + +type string: 1 -> character +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 +type integer2string: integer -> string +type integer2character: integer -> character +type integer2Boolean: integer -> Boolean + + +external function printInteger: integer2integer +external function printCharacter: character2integer +external function printBoolean: Boolean2integer + +external function printS: string2integer +external function printI: integer2integer +external function printC: character2integer +external function printB: Boolean2integer + +external function inS: integer2string +external function inI: integer2integer +external function inC: integer2character diff --git a/library/std.s b/library/std.s new file mode 100644 index 0000000..6cdcb90 --- /dev/null +++ b/library/std.s @@ -0,0 +1,273 @@ + .file "alphastdio.c" + .text + .section .rodata +.LC0: + .string "%s" + .text + .globl printS + .type printS, @function +printS: +.LFB6: + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + subq $16, %rsp + movq %rdi, -8(%rbp) + cmpq $0, -8(%rbp) + jne .L2 + movl $-1, %eax + jmp .L3 +.L2: + movq -8(%rbp), %rax + movq %rax, %rsi + leaq .LC0(%rip), %rax + movq %rax, %rdi + movl $0, %eax + call printf@PLT + movl $0, %eax +.L3: + leave + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE6: + .size printS, .-printS + .section .rodata +.LC1: + .string "\n" + .text + .globl inS + .type inS, @function +inS: +.LFB7: + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + subq $16, %rsp + movl $100, %edi + call malloc@PLT + movq %rax, -8(%rbp) + cmpq $0, -8(%rbp) + jne .L5 + movl $0, %eax + jmp .L6 +.L5: + movq stdin(%rip), %rdx + movq -8(%rbp), %rax + movl $100, %esi + movq %rax, %rdi + call fgets@PLT + testq %rax, %rax + jne .L7 + movq -8(%rbp), %rax + movq %rax, %rdi + call free@PLT + movl $0, %eax + jmp .L6 +.L7: + movq -8(%rbp), %rax + leaq .LC1(%rip), %rdx + movq %rdx, %rsi + movq %rax, %rdi + call strcspn@PLT + movq -8(%rbp), %rdx + addq %rdx, %rax + movb $0, (%rax) + movq -8(%rbp), %rax +.L6: + leave + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE7: + .size inS, .-inS + .section .rodata +.LC2: + .string "%d" + .text + .globl printI + .type printI, @function +printI: +.LFB8: + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + subq $16, %rsp + movl %edi, -4(%rbp) + movl -4(%rbp), %eax + movl %eax, %esi + leaq .LC2(%rip), %rax + movq %rax, %rdi + movl $0, %eax + call printf@PLT + movl $0, %eax + leave + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE8: + .size printI, .-printI + .globl inI + .type inI, @function +inI: +.LFB9: + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + addq $-128, %rsp + movq %fs:40, %rax + movq %rax, -8(%rbp) + xorl %eax, %eax + movq stdin(%rip), %rdx + leaq -112(%rbp), %rax + movl $100, %esi + movq %rax, %rdi + call fgets@PLT + testq %rax, %rax + jne .L11 + movl $0, %eax + jmp .L14 +.L11: + leaq -116(%rbp), %rdx + leaq -112(%rbp), %rax + leaq .LC2(%rip), %rcx + movq %rcx, %rsi + movq %rax, %rdi + movl $0, %eax + call __isoc99_sscanf@PLT + cmpl $1, %eax + je .L13 + movl $0, %eax + jmp .L14 +.L13: + movl -116(%rbp), %eax +.L14: + movq -8(%rbp), %rdx + subq %fs:40, %rdx + je .L15 + call __stack_chk_fail@PLT +.L15: + leave + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE9: + .size inI, .-inI + .globl printC + .type printC, @function +printC: +.LFB10: + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + subq $16, %rsp + movl %edi, %eax + movb %al, -4(%rbp) + movsbl -4(%rbp), %eax + movl %eax, %edi + call putchar@PLT + movl $0, %eax + leave + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE10: + .size printC, .-printC + .section .rodata +.LC3: + .string " %c" + .text + .globl inC + .type inC, @function +inC: +.LFB11: + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + subq $16, %rsp + movq %fs:40, %rax + movq %rax, -8(%rbp) + xorl %eax, %eax + leaq -9(%rbp), %rax + movq %rax, %rsi + leaq .LC3(%rip), %rax + movq %rax, %rdi + movl $0, %eax + call __isoc99_scanf@PLT + cmpl $1, %eax + je .L19 + movl $0, %eax + jmp .L21 +.L19: + movzbl -9(%rbp), %eax +.L21: + movq -8(%rbp), %rdx + subq %fs:40, %rdx + je .L22 + call __stack_chk_fail@PLT +.L22: + leave + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE11: + .size inC, .-inC + .section .rodata +.LC4: + .string "true" +.LC5: + .string "false" + .text + .globl printB + .type printB, @function +printB: +.LFB12: + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + subq $16, %rsp + movl %edi, %eax + movb %al, -4(%rbp) + cmpb $0, -4(%rbp) + je .L24 + leaq .LC4(%rip), %rax + movq %rax, %rdi + movl $0, %eax + call printf@PLT + jmp .L25 +.L24: + leaq .LC5(%rip), %rax + movq %rax, %rdi + movl $0, %eax + call printf@PLT +.L25: + movl $0, %eax + leave + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE12: + .size printB, .-printB + .ident "GCC: (GNU) 14.2.1 20250207" + .section .note.GNU-stack,"",@progbits diff --git a/src/codegen.c b/src/codegen.c index 250d2a4..9baafd4 100644 --- a/src/codegen.c +++ b/src/codegen.c @@ -2,12 +2,18 @@ /* The Translators - Spring 2025 */ #include "codegen.h" - -int generate(){ +int paramCount = 0; +int funDec = 0; +int generate() { offset = 0; + currentsp = 0; Instruction *i = begin; + funList = NULL; + // temporary + fprintf(cg_flag, ".globl entry\n"); + while (i != NULL) { - switch(getOp(i)) { + switch (getOp(i)) { case E_LABEL: generateLabel(i); break; @@ -46,7 +52,7 @@ int generate(){ break; case E_IF_X_TRUE: generateIfTrue(i); - break; + break; case E_IF_X_FALSE: generateIfFalse(i); break; @@ -74,14 +80,35 @@ int generate(){ case E_ADDRESS_OF: generateAddressOf(i); break; - default: - ; + case E_FUNC_START: + generateFunctionStart(i); + break; + case E_FUNC_DEC: + generateFunctionDec(i); + break; + default:; } i = i->next; } return -1; } +bool isAnActualFunction(TableNode *tn) { + FunDecList *fdl = funList; + while (fdl != NULL) { + printf("%s %s, %s %s\n", getName(fdl->tn), getType(fdl->tn), getName(tn), getType(tn)); + if (tn == fdl->tn) { + return true; + } + fdl = fdl ->next; + } + return false; +} + +void align(TableNode *tn) { + int size = getPrimSize(getTypeEntry(tn)); + offset += offset % size; +} CGNode *getNextCG(CGNode *cg) { if (cg == NULL) { return NULL; @@ -118,16 +145,31 @@ CGNode *findCG(TableNode *tn) { CGNode *addCG(TableNode *tn, int sp) { CGNode *cg = calloc(1, sizeof(CGNode)); cg->tn = tn; - offset += 4; // <- quick fix getPrimSize(getTypeEntry(tn)) + align(tn); + offset += getPrimSize(getTypeEntry(tn)); cg->address = offset; cg->next = cgList; cgList = cg; return cg; } - +int generateFunctionDec(Instruction *i) { + FunDecList * fd = calloc(1, sizeof(FunDecList)); + CGNode *cg = addCG(getResult(i),offset); +// printf("%d\n", getAddress(cg)+currentsp); + offset += 8; + fd->tn = getResult(i); + fd->next = funList; + funList = fd; + return 0; +} int generateLabel(Instruction *inst) { + if (inst == NULL) { + return -1; + } + fprintf(cg_flag, ".L%d:\n", getLabel(inst)); + return 0; } int generateAdd(Instruction *inst) { @@ -139,7 +181,7 @@ int generateAdd(Instruction *inst) { 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; @@ -148,10 +190,9 @@ int generateAdd(Instruction *inst) { if (cg == NULL) { cg = addCG(getResult(inst), offset); } - - + CGNode *op1CG = findCG(getTN(op1)); - CGNode *op2CG = findCG(getTN(op1)); + CGNode *op2CG = findCG(getTN(op2)); if (op1CG == NULL) { printdebug("generateAdd failed, %s is not initialized/in CG", getName(getTN(op1))); return -1; @@ -161,15 +202,14 @@ int generateAdd(Instruction *inst) { 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, "\n\tmovl\t%d(%%rbp), %%eax\t#addition start\n", getAddress(op1CG)); + fprintf(cg_flag, "\taddl\t%d(%%rbp), %%eax\n", getAddress(op2CG)); 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: @@ -177,7 +217,7 @@ int generateSub(Instruction *instruction) { 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; @@ -186,7 +226,7 @@ int generateSub(Instruction *instruction) { if (cg == NULL) { cg = addCG(getResult(instruction), offset); } - + CGNode *op1CG = findCG(getTN(op1)); CGNode *op2CG = findCG(getTN(op2)); if (op1CG == NULL) { @@ -205,8 +245,8 @@ int generateSub(Instruction *instruction) { return 0; } -int generateMult(Instruction *inst){ - /* +int generateMult(Instruction *inst) { + /* Both immediate: One immediate: Neither immediate: @@ -214,7 +254,7 @@ int generateMult(Instruction *inst){ 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; @@ -242,7 +282,7 @@ int generateMult(Instruction *inst){ } int generateDiv(Instruction *inst) { - /* + /* Both immediate: One immediate: Neither immediate: @@ -250,7 +290,7 @@ int generateDiv(Instruction *inst) { 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; @@ -259,7 +299,7 @@ int generateDiv(Instruction *inst) { if (cg == NULL) { cg = addCG(getResult(inst), offset); } - + CGNode *op1CG = findCG(getTN(op1)); CGNode *op2CG = findCG(getTN(op2)); if (op1CG == NULL) { @@ -272,10 +312,10 @@ int generateDiv(Instruction *inst) { 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 + 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; } @@ -288,7 +328,7 @@ int generateMod(Instruction *inst) { 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; @@ -303,21 +343,21 @@ int generateMod(Instruction *inst) { 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) + + 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: @@ -325,7 +365,7 @@ int generateOr(Instruction *inst) { 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; @@ -334,7 +374,7 @@ int generateOr(Instruction *inst) { if (cg == NULL) { cg = addCG(getResult(inst), offset); } - + CGNode *op1CG = findCG(getTN(op1)); CGNode *op2CG = findCG(getTN(op2)); if (op1CG == NULL) { @@ -349,22 +389,22 @@ int generateOr(Instruction *inst) { int label = label_gen(); - fprintf(cg_flag, "\tcmpl\t$0, %d(%%rbp)\t#start or\n", getAddress(op1CG)); + fprintf(cg_flag, "\tcmpb\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, "\tcmpb\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, "\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, "\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 + fprintf(cg_flag, "\tandb\t$1, %d(%%rbp)\t#or end\n", getAddress(cg)); //stores result return 0; } @@ -377,7 +417,7 @@ int generateAnd(Instruction *inst) { 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; @@ -386,7 +426,7 @@ int generateAnd(Instruction *inst) { if (cg == NULL) { cg = addCG(getResult(inst), offset); } - + CGNode *op1CG = findCG(getTN(op1)); CGNode *op2CG = findCG(getTN(op2)); if (op1CG == NULL) { @@ -398,29 +438,29 @@ int generateAnd(Instruction *inst) { printdebug("generateAnd failed, %s is not initialized/in CG", getName(getTN(op2))); return -1; } - int label = label_gen(); + int label = label_gen(); - fprintf(cg_flag, "\tcmpl\t$0, %d(%%rbp)\t#start and\n", getAddress(op1CG)); + fprintf(cg_flag, "\tcmpb\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, "\tcmpb\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, "\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, "\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 + 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; @@ -429,14 +469,14 @@ int generateNeg(Instruction *inst) { 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, "\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; @@ -444,7 +484,7 @@ int generateNeg(Instruction *inst) { int generateNot(Instruction *inst) { TNodeOrConst *op1 = getOperand1(inst); CGNode *cg = findCG(getResult(inst)); - + if (op1 == NULL) { printdebug("generateNot failed, NULL operand"); return -1; @@ -453,7 +493,7 @@ int generateNot(Instruction *inst) { 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"); @@ -474,7 +514,6 @@ int generateAssign(Instruction *inst) { TNodeOrConst *op1 = getOperand1(inst); CGNode *cg = findCG(getResult(inst)); - if (op1 == NULL) { printdebug("generateAssign failed, NULL operand"); return -1; @@ -484,44 +523,107 @@ int generateAssign(Instruction *inst) { cg = addCG(getResult(inst), offset); } + CGNode *op1CG = findCG(getTN(op1)); //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)); + char *movtype; + char *reg; + TableNode *typetn = getTypeEntry(getResult(inst)); + if (typetn == integ) { + movtype = "movl"; + reg = "%eax"; + } else if (typetn == boo) { + movtype = "movb"; + reg = "%al"; + } else if (typetn == chara) { + movtype = "movb"; + reg = "%al"; + } else { + movtype = "movq"; + reg = "%rax"; + } + fprintf(cg_flag, "\t%s\t$%d, %d(%%rbp)\t#constant assign\n",movtype, 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"); + + else if (op1CG == NULL) { + printdebug("generateAssign failed, %s is not constant but not in CGlist", getName(getTN(op1))); 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)); + if (getAdInfoType(getTN(op1)) != TYPE_FUNCTION_DECLARATION || table_lookup(getAncestor(cur), getName(getTN(op1))) == undefined){ + char *movtype; + char *reg; + TableNode *typetn = getTypeEntry(getTN(op1)); + if (typetn == integ) { + movtype = "movl"; + reg = "%eax"; + } else if (typetn == boo) { + movtype = "movb"; + reg = "%al"; + } else if (typetn == chara) { + movtype = "movb"; + reg = "%al"; + } else { + movtype = "movq"; + reg = "%rax"; + } + fprintf(cg_flag, "\t%s\t%d(%%rbp), %s\t#assign start\n",movtype, getAddress(op1CG), reg); + fprintf(cg_flag, "\t%s\t%s, %d(%%rbp)\t#assign end\n", movtype,reg,getAddress(cg)); + } else { + fprintf(cg_flag, "\tmovl\t$%s,%%eax\t#assign function\n", getName(getTN(op1))); + fprintf(cg_flag, "\tmovl\t%%eax, %d(%%rbp)\t#assign function end\n", getAddress(cg)); + } return 0; } -int generateGoto(Instruction *instruction){ +int generateGoto(Instruction *inst) { + fprintf(cg_flag, "\tjmp\t.L%d\n", getLabel(inst)); + return 0; +} + +int generateCondGoto(Instruction *inst) { return -1; } -int generateCondGoto(Instruction *instruction) { - return -1; +int generateIfTrue(Instruction *inst) { + TNodeOrConst *op1 = getOperand1(inst); + + if (op1 == NULL) { + printdebug("%sgenerateIfTrue failed, NULL operand", COLOR_RED); + return -1; + } + + CGNode *cg = findCG(getTN(op1)); + if (cg == NULL) { + printdebug("generateIfTrue failed, operand not on stack"); + return -1; + } + + fprintf(cg_flag, "\tcmpb\t$0, %d(%%rbp)\t#if true start\n", getAddress(cg)); + fprintf(cg_flag, "\tjne\t.L%d\t\t#if true end\n", getLabel(inst)); } -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 *inst) { + TNodeOrConst *op1 = getOperand1(inst); + + if (op1 == NULL) { + printdebug("%sgenerateIfFalse failed, NULL operand", COLOR_RED); + return -1; + } + + CGNode *cg = findCG(getTN(op1)); + if (cg == NULL) { + printdebug("generateIfFalse failed, operand not on stack"); + return -1; + } + + fprintf(cg_flag, "\tcmpb\t$0, %d(%%rbp)\t#if false start\n", getAddress(cg)); + fprintf(cg_flag, "\tje\t.L%d\t\t#if false end\n", getLabel(inst)); } -int generateIfFalse(Instruction *instruction){ - return -1; -} - -int generateLessThan(Instruction *inst){ - /* +int generateLessThan(Instruction *inst) { + /* Both immediate: One immediate: Neither immediate: @@ -529,7 +631,7 @@ int generateLessThan(Instruction *inst){ 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; @@ -538,7 +640,7 @@ int generateLessThan(Instruction *inst){ if (cg == NULL) { cg = addCG(getResult(inst), offset); } - + CGNode *op1CG = findCG(getTN(op1)); CGNode *op2CG = findCG(getTN(op2)); if (op1CG == NULL) { @@ -551,15 +653,15 @@ int generateLessThan(Instruction *inst){ return -1; } - fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\t#less than start\n", getAddress(op1CG)); + 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){ - /* +int generateEqualTo(Instruction *inst) { + /* Both immediate: One immediate: Neither immediate: @@ -567,7 +669,7 @@ int generateEqualTo(Instruction *inst){ 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; @@ -576,7 +678,7 @@ int generateEqualTo(Instruction *inst){ if (cg == NULL) { cg = addCG(getResult(inst), offset); } - + CGNode *op1CG = findCG(getTN(op1)); CGNode *op2CG = findCG(getTN(op2)); if (op1CG == NULL) { @@ -588,31 +690,233 @@ int generateEqualTo(Instruction *inst){ printdebug("generateLessThan failed, %s is not initialized/in CG", getName(getTN(op2))); return -1; } + char *movtype; + char *reg; + char *cmptype; + TableNode *typetn = getTypeEntry(getTN(op1)); + if (typetn == integ) { + movtype = "movl"; - 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)); + cmptype = "cmpl"; + reg = "%eax"; + } else if (typetn == boo) { + cmptype = "cmpb"; + movtype = "movb"; + reg = "%al"; + } else if (typetn == chara) { + cmptype = "cmpb"; + movtype = "movb"; + reg = "%al"; + } else { + cmptype = "cmpq"; + movtype = "movq"; + reg = "%rax"; + } + + fprintf(cg_flag, "\t%s\t%d(%%rbp), %s\t#equal to start\n", movtype, getAddress(op1CG), reg); + fprintf(cg_flag, "\t%s\t%d(%%rbp), %s\n", cmptype, getAddress(op2CG), reg); fprintf(cg_flag, "\tsete\t%%al\n"); + fprintf(cg_flag, "\tmovb\t$0, %d(%%rbp)\n", getAddress(cg)); 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 generateCall(Instruction *inst) { + paramCount = 0; + TNodeOrConst *op1 = getOperand1(inst); + TNodeOrConst *op2 = getOperand2(inst); + if (op1 == NULL) { + printdebug("%sgenerateFunctionCall failed, NULL operand", COLOR_RED); + return -1; + } + + if (op1 == NULL) { + printdebug("%sgenerateFunctionCall failed, NULL operand", COLOR_RED); + return -1; + } + + if (getTN(op1) == NULL) { + printdebug("generateFunctionCall failed, NULL tablenode1"); + return -1; + } + + if (table_lookup(getAncestor(cur),getName(getTN(op1)))!=undefined) { + fprintf(cg_flag, "\tcall %s\n", getName(getTN(op1))); + } else { + // printf("%s\n", getName(getTN(op1))); + if (findCG(getTN(op1)) == NULL) { + //printf("generateFunctionCall failed, function not in stack"); + return -1; + } + fprintf(cg_flag, "\tmovq\t%d(%%rbp), %%rax\t#call %s!\n", getAddress(findCG(getTN(op1))), getName(getTN(op1))); + fprintf(cg_flag, "\tcall *%%rax\n"); + } + //if (getTN(op2) == NULL) { + //printdebug("generateFunctionCall failed, NULL tablenode2"); + // return -1; + // } + //now for the return + CGNode *cg = findCG(getResult(inst)); + + if (cg == NULL) { + cg = addCG(getResult(inst), offset); + } + + fprintf(cg_flag, "\tmovl\t%%eax, %d(%%rbp)\t#store return from call\n", getAddress(cg)); + + return 0; } -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 generateReturn(Instruction *inst) { + TNodeOrConst *op1 = getOperand1(inst); + CGNode *cg; + + if (op1 == NULL) { + printdebug("generateReturn failed, NULL operand"); + return -1; + } + + cg = findCG(getTN(op1)); + if (cg == NULL) { + printdebug("generateReturn failed, trying to return %s not in CGList", getName(getTN(op1))); + return -1; + } + if (table_lookup(getAncestor(cur), getName(getTN(op1))) != undefined) { + fprintf(cg_flag, "\tmovl\t$%s,%%eax\t#return a function\n", getName(getTN(op1))); + } else { + fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\t#return %s\n", getAddress(cg), getName(getTN(op1))); + } + fprintf(cg_flag, "\tleave\n"); + fprintf(cg_flag, "\tret\n"); + return 0; } -int generateCopyRight(Instruction *instruction){ +int generateCopyRight(Instruction *inst) { return -1; } -int generateCopyLeft(Instruction *instruction){ +int generateCopyLeft(Instruction *inst) { return -1; } -int generateAddressOf(Instruction *instruction){ +int generateAddressOf(Instruction *inst) { 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; -} \ No newline at end of file + +int generateParam(Instruction *inst) { + TNodeOrConst *op1 = getOperand1(inst); + //fprintf(stderr, "generate param reached\n"); + if (op1 == NULL) { + printdebug("generateParam failed, NULL operand"); + return -1; + } + + CGNode *op1CG = findCG(getTN(op1)); + if (op1CG == NULL) { + printdebug("generateParam failed, %s is not in CGlist", getName(getTN(op1))); + return -1; + } + paramCount += 1; + switch(paramCount) { + case 1: + fprintf(cg_flag, "\tmovl\t%d(%%rbp), %s\t#adding param start\n", getAddress(op1CG), REG1); + break; + case 2: + fprintf(cg_flag, "\tmovl\t%d(%%rbp), %s\t#adding param start\n", getAddress(op1CG), REG2); + break; + case 3: + fprintf(cg_flag, "\tmovl\t%d(%%rbp), %s\t#adding param start\n", getAddress(op1CG), REG3); + break; + case 4: + fprintf(cg_flag, "\tmovl\t%d(%%rbp), %s\t#adding param start\n", getAddress(op1CG), REG4); + break; + case 5: + fprintf(cg_flag, "\tmovl\t%d(%%rbp), %s\t#adding param start\n", getAddress(op1CG), REG5); + break; + case 6: + fprintf(cg_flag, "\tmovl\t%d(%%rbp), %s\t#adding param start\n", getAddress(op1CG), REG6); + break; + default: + align(getTN(op1)); + offset += getPrimSize(getTypeEntry(getTN(op1))); + fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\t#adding param start\n", getAddress(op1CG)); + fprintf(cg_flag, "\tmovl\t%%eax, %d(%%rbp)\t#adding param end\n", offset - getPrimSize(getTypeEntry(getTN(op1)))); + } + return 0; +} + +int generateFunctionStart(Instruction *inst) { + currentsp = offset; + TableNode *funDecTN = getResult(inst); + + if (funDecTN == NULL) { + printdebug("generateFunctionStart failed, NULL tablenode"); + return -1; + } + + //this is independent of parameters: + fprintf(cg_flag, "%s:\n", getName(funDecTN)); + fprintf(cg_flag, "\tpushq\t%%rbp\n"); + fprintf(cg_flag, "\tmovq\t%%rsp, %%rbp\n"); + fprintf(cg_flag, "\tsubq\t$%d, %%rsp\n", getStackSize()); + + //now we need to add the CGs of nodes to the CG list by doing assign from the + // have function declararation node + //declaration ->getType: if record, go through each element and load param from stack and store to correct tn cg + // if not, go get one element of type of param + //declaration ->getType->getDefinitionScope?: go through first n entries to get table nodes for params + + TableNode *paramTN = getParameter(getTypeEntry(funDecTN)); + SymbolTable *st = getFunScope(funDecTN); + int paramOffset = 16; + TableNode *tnToAdd = getFirstEntry(st); + if (getAdInfoType(paramTN) != TYPE_RECORD_TYPE) { + CGNode *paramCG = addCG(tnToAdd, offset); + int size = getPrimSize(getTypeEntry(tnToAdd)); + paramOffset += getPrimSize(getTypeEntry(tnToAdd)); + fprintf(cg_flag, "\tmovl\t%%edi, %d(%%rbp)\t#FunctionStart1param end\n", getAddress(paramCG)); + } else { + int numParams = getRecLength(paramTN); + for (int i = numParams; i > 0; i--) { + CGNode *paramCG = addCG(tnToAdd, offset); + switch(i) { + case 1: + fprintf(cg_flag, "\tmovl\t%s, %d(%%rbp)\t#FunctionStart1param end\n", REG1, getAddress(paramCG)); + break; + case 2: + fprintf(cg_flag, "\tmovl\t%s, %d(%%rbp)\t#FunctionStart1param end\n", REG2, getAddress(paramCG)); + break; + case 3: + fprintf(cg_flag, "\tmovl\t%s, %d(%%rbp)\t#FunctionStart1param end\n", REG3, getAddress(paramCG)); + break; + case 4: + fprintf(cg_flag, "\tmovl\t%s, %d(%%rbp)\t#FunctionStart1param end\n", REG4, getAddress(paramCG)); + break; + case 5: + fprintf(cg_flag, "\tmovl\t%s, %d(%%rbp)\t#FunctionStart1param end\n", REG5, getAddress(paramCG)); + break; + case 6: + fprintf(cg_flag, "\tmovl\t%s, %d(%%rbp)\t#FunctionStart1param end\n", REG6, getAddress(paramCG)); + break; + default: + int size = getPrimSize(getTypeEntry(tnToAdd)); + paramOffset += size; + offset += getPrimSize(getTypeEntry(tnToAdd)); + fprintf(cg_flag, "\tmovl\t%d(%%rbp), %%eax\t#FunctionStart1Param start\n", paramOffset); + fprintf(cg_flag, "\tmovl\t%%eax, %d(%%rbp)\t#FunctionStart1param end\n", getAddress(paramCG)); + + } + + tnToAdd = getNextEntry(tnToAdd); + } + } + +/* if (strcmp(getName(funDecTN), "entry") == 0) { + if (funList == NULL) { + return -1; + } + TableNode *funDec; + while (funList != NULL) { + funDec = funList->tn; + CGNode *cg = findCG(getResult(inst)); + fprintf(cg_flag, "\tmovq\t$%s, %d(%%rbp)\t#storing function declaration\n", getName(funDec), getAddress(cg)); + funList = funList->next; + } + } */ + return 0; +} diff --git a/src/codegen.h b/src/codegen.h index 3203a52..828f16a 100644 --- a/src/codegen.h +++ b/src/codegen.h @@ -13,20 +13,34 @@ #include "intermediate_code.h" #include "symbol_table.h" +#define REG1 "%edi" +#define REG2 "%esi" +#define REG3 "%edx" +#define REG4 "%ecx" +#define REG5 "%r8d" +#define REG6 "%r9d" + extern FILE *cg_flag; typedef struct CGNode { TableNode *tn; int address; - CGNode *next; + struct CGNode *next; } CGNode; +typedef struct FunDecList { + TableNode *tn; + struct FunDecList *next; +} FunDecList; + +bool isAnActualFunction(TableNode *tn); 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 generateFunctionDec(Instruction *inst); int generateLabel(Instruction *inst); int generateAdd(Instruction *inst); int generateSub(Instruction *instruction); @@ -50,11 +64,14 @@ int generateCopyRight(Instruction *instruction); int generateCopyLeft(Instruction *instruction); int generateAddressOf(Instruction *instruction); int generateParam(Instruction *instruction); +int generateFunctionStart(Instruction *instruction); extern int label_count; extern Instruction *begin; extern Instruction *current; +extern SymbolTable *top; extern int offset; extern int currentsp; -extern CGNode *cgList; \ No newline at end of file +extern CGNode *cgList; +extern FunDecList *funList; diff --git a/src/grammar.h b/src/grammar.h index 2b7b03c..43272b7 100644 --- a/src/grammar.h +++ b/src/grammar.h @@ -8,8 +8,11 @@ #include "../src/symbol_table.h" extern FILE *asc_flag; extern bool tc_flag; -extern void insert_code_line(char * error_message, int line_number); - +extern bool entry_flag; +extern void insert_code_line(char *error_message, int line_number); +extern bool contains_errors; +extern int context; +//extern TableNode* comparator; typedef enum { ERROR_RUNTIME = 1, ERROR_SYNTAX = 2, @@ -29,4 +32,8 @@ Instruction *current; int offset; int currentsp; -CGNode *cgList; \ No newline at end of file +CGNode *cgList; +FunDecList *funList; +Stack *stack; +Stack *TrueList; +Stack *FalseList; diff --git a/src/grammar.y b/src/grammar.y index 7060c94..c350b72 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -1,3 +1,4 @@ + /* Syntax Analyzer with Bison (3.8.2) */ /* The Translators - Spring 2025 */ @@ -18,7 +19,6 @@ %{ #include "../src/grammar.h" %} - %union { int integ; char* words; @@ -28,7 +28,7 @@ %locations - +%token ACCESS 801 %type idlist %type assignable %type expression @@ -87,6 +87,7 @@ %token RESERVE 613 %token RELEASE 614 %token COMMENT 700 +%token INCLUDE 901 //precedence order %left ASSIGN @@ -106,7 +107,8 @@ program: prototype_or_definition_list - | error { yyerrok; } + | include_list + | include_list prototype_or_definition_list ; @@ -116,16 +118,27 @@ prototype_or_definition_list: | definition prototype_or_definition_list | prototype | definition - | error { yyerrok; } + | prototype error { yyerrok; } + | definition error { yyerrok; } ; prototype: L_PAREN EXTERNAL R_PAREN FUNCTION ID COLON ID + ; - | error { yyerrok; } - + + +include_list: + include_statement include_list + | include_statement + ; + + + +include_statement: + INCLUDE C_STRING ; @@ -133,54 +146,51 @@ prototype: definition: TYPE ID COLON { - printdebug("Currently see a record definition for %s", $2); tn = CreateEntry(getAncestor(cur),TYPE_RECORD_TYPE, recprime, $2, CreateRecordInfo(0, cur = CreateScope(cur, 0, 0))); printdebug("Created a new scope"); - //if (look_up(cur, $2) == undefined) { - // printdebug("rec not found"); - //} - } - dblock - { - //We are scanning through the dblock scope to get the length of the dblock (num of elements) from getRecSize - //and then putting it in the entry that we created above. + } dblock { setRecSize(look_up(getParent(cur), $2), getRecSize(cur)); - //putting in all the offsets setRecOffsetInfo(cur, look_up(getParent(cur),$2)); printdebug("Moving up a scope after seeing a record definition"); cur = getParent(cur); } - | TYPE ID COLON C_INTEGER ARROW id_or_types + | TYPE ID COLON C_INTEGER ARROW id_or_types { - printdebug("Currently see a array definition of name %s,storing type %s, of dimensions %d", $2, getName((TableNode*)$6), $4); + printdebug("Currently see a array definition of name %s,storing type %s, of dimensions %d", $2, getName((TableNode*)$6), $4); CreateEntry(cur,TYPE_ARRAY_TYPE, arrayprim, $2, CreateArrayInfo($4, (TableNode*)$6)); printdebug("%sID: %s, dimensions: %d, typeOfArray: %s", COLOR_GREEN, $2, $4, getName((TableNode*)$6)); } - | function_declaration - | TYPE ID COLON id_or_types ARROW id_or_types { printdebug("Currently see a function type definition of name %s,parameter type %s, of return type %s", $2, getName((TableNode*)$4), getName((TableNode*)$6)); CreateEntry(cur,TYPE_FUNCTION_TYPE,funtypeprime,$2,CreateFunctionTypeInfo((TableNode*)$4 ,(TableNode*)$6)); - } - + } + | ID { + if(strcmp($1, "entry") == 0){ + //seen entry function + entry_flag = true; + } + emit_function_start(table_lookup(cur,$1)); + //printf("ID: %s\n", $1); + //printf("Type: %s\n", getType(table_lookup(getAncestor(cur), $1))); printdebug("see function def rule 1\n"); TableNode *node = table_lookup(getAncestor(cur), $1); if (node == undefined) { printdebug("Undefined node declared."); }else if(getAdInfoType(node) != TYPE_FUNCTION_DECLARATION){ throw_error(ERROR_SYNTAX, "Not a valid function declaration."); - } + } else { printdebug("setting as keyword to true"); setStartLine(node, @1.first_line); - setAsKeyword(node, true); + setAsKeyword(node, true); } cur = CreateScope(cur, 0, 0); + setFunScope(node, cur); printdebug("Created a new scope"); } L_PAREN { TableNode * parameter = getParameter(getTypeEntry(table_lookup(getAncestor(cur), $1))); @@ -194,26 +204,33 @@ definition: || type_of_param_type == TYPE_FUNCTION_DECLARATION || type_of_param_type == TYPE_ARRAY || type_of_param_type == TYPE_PRIMITIVE - || type_of_param_type == TYPE_ALL_ELSE + || type_of_param_type == TYPE_ALL_ELSE || type_of_param_type == TYPE_SYSTEM_DEFINED || type_of_param_type == TYPE_RECORD - || type_of_param_type == TYPE_STRING){ // note that strings are actually arrays so this is unused + || type_of_param_type == TYPE_STRING){ // note that strings are actually arrays so this is unused throw_error(ERROR_TYPE, "Invalid type (%s) of parameter in function definition.", getAdInfo(parameter)); type_of_param_type = TYPE_UNDEFINED; // setting tag as undefined in these cases } if(type_of_param_type == TYPE_UNDEFINED){ CreateEntry(cur,type_of_param_type, undefined, NULL, NULL); + // throw_error(ERROR_TYPE, "Duplicate defination of parameter in function definition."); } else { if(type_of_param_type == TYPE_FUNCTION_TYPE){ CreateEntry(cur, TYPE_FUNCTION_DECLARATION, parameter,NULL, getAdInfo(parameter)); + // throw_error(ERROR_TYPE, "Duplicate defination of parameter in function definition."); + } if(type_of_param_type == TYPE_ARRAY_TYPE){ CreateEntry(cur, TYPE_ARRAY, parameter,NULL, getAdInfo(parameter)); - } - if(type_of_param_type == TYPE_PRIMITIVE_TYPE){ - CreateEntry(cur, TYPE_PRIMITIVE, parameter,NULL, getAdInfo(parameter)); - } + //throw_error(ERROR_TYPE, "Duplicate defination of parameter in function definition."); + } + if(type_of_param_type == TYPE_PRIMITIVE_TYPE){ + CreateEntry(cur, TYPE_PRIMITIVE, parameter,NULL, getAdInfo(parameter));//==undefined; + // throw_error(ERROR_TYPE, "Duplicate defination of parameter in function definition.");} + + } + } } else { printdebug("record found"); for (TableNode* entry = getFirstEntry(getRecList(parameter)); entry!= NULL; entry = getNextEntry(entry)){ @@ -222,10 +239,10 @@ definition: || type_of_param_type == TYPE_FUNCTION_TYPE || type_of_param_type == TYPE_ARRAY_TYPE || type_of_param_type == TYPE_PRIMITIVE_TYPE - || type_of_param_type == TYPE_ALL_ELSE + || type_of_param_type == TYPE_ALL_ELSE || type_of_param_type == TYPE_SYSTEM_DEFINED || type_of_param_type == TYPE_RECORD_TYPE - || type_of_param_type == TYPE_STRING){ // note that strings are actually arrays so this is unused + || type_of_param_type == TYPE_STRING){ // note that strings are actually arrays so this is unused throw_error(ERROR_TYPE, "Invalid type (%s) of parameter in function definition.", getAdInfo(entry)); type_of_param_type = TYPE_UNDEFINED; // setting tag as undefined in these cases }else{ @@ -234,60 +251,88 @@ definition: if(type_of_param_type == TYPE_UNDEFINED){ printdebug("undefined type of parameter inside record"); CreateEntry(cur,type_of_param_type, undefined, NULL, NULL); + //throw_error(ERROR_TYPE, "Duplicate defination of parameter in function definition."); + } else { if(type_of_param_type == TYPE_FUNCTION_DECLARATION){ printdebug("function declaration of parameter inside record"); CreateEntry(cur, TYPE_FUNCTION_DECLARATION, getTypeEntry(entry),NULL, getAdInfo(entry)); + //throw_error(ERROR_TYPE, "Duplicate defination of parameter in function definition."); + } if(type_of_param_type == TYPE_ARRAY){ printdebug("array type of parameter inside record"); CreateEntry(cur, TYPE_ARRAY, getTypeEntry(entry),NULL, getAdInfo(entry)); - } + //throw_error(ERROR_TYPE, "Duplicate defination of parameter in function definition."); + } if(type_of_param_type == TYPE_PRIMITIVE){ printdebug("primitive type of parameter inside record"); CreateEntry(cur, TYPE_PRIMITIVE, getTypeEntry(entry),NULL, getAdInfo(entry)); - } + + //throw_error(ERROR_TYPE, "Duplicate defination of parameter in function definition.");} + } + if(type_of_param_type == TYPE_RECORD){ + printdebug("record type of parameter inside record"); + CreateEntry(cur, TYPE_RECORD, getTypeEntry(entry),NULL, getAdInfo(entry)); + //throw_error(ERROR_TYPE, "Duplicate defination of parameter in function definition.");} + } + /*printdebug("creating entry of type %s for function", getType(entry)); CreateEntry(cur, getTypeEntry(entry), "undefined", NULL);*/ } } } //counter = 0; + printdebug("Created a new scope after seeing a function definition"); } idlist R_PAREN ASSIGN sblock { TableNode *expected = getReturn(getTypeEntry(look_up(cur, $1))); if ($8 == undefined) { throw_error(ERROR_TYPE, "Expected %s as return type but got undefined (possibly NULL). Differing return types in function.", getName(expected)); - } else if ($8 != expected) { + } else if (getAdInfoType(expected)==TYPE_ARRAY_TYPE && $8 == addr){ + printdebug("CORRECT RETURN TYPE!!!"); + } else if (getAdInfoType(expected)==TYPE_RECORD_TYPE && $8 == addr){ + printdebug("CORRECT RETURN TYPE!!!"); + }else if ($8 != expected) { throw_error(ERROR_TYPE, "Expected %s as return type but got %s. Differing return types in function.", getName(expected), getName($8)); } else { printdebug("CORRECT RETURN TYPE!!!"); } - } + //printf("Ending ID: %s\n", $1); + //printf("Ending Type: %s\n", getType(table_lookup(getAncestor(cur), $1))); +} ; function_declaration: FUNCTION ID COLON ID - { - if(getAdInfoType(look_up(cur, $4))==TYPE_FUNCTION_TYPE){ - CreateEntry(cur,TYPE_FUNCTION_DECLARATION, look_up(cur, $4), $2, CreateFunctionDeclarationInfo(-1, false)); + { + if(getAdInfoType(table_lookup(cur, $4))==TYPE_FUNCTION_TYPE){ + //printf("%s\n",$1); + //printf("%s\n",getName(table_lookup(cur, $4))); + if (CreateEntry(cur,TYPE_FUNCTION_DECLARATION, table_lookup(cur, $4), $2, CreateFunctionDeclarationInfo(-1, false,NULL)) == undefined) { + throw_error(ERROR_TYPE, "Duplicate defination of function in function declaration"); + } + } else{ throw_error(ERROR_TYPE, "Function declatation (%s) is not a valid function type", $2); - CreateEntry(cur,TYPE_FUNCTION_DECLARATION, look_up(cur, $4), $2, CreateFunctionDeclarationInfo(-1, false)); + CreateEntry(cur,TYPE_FUNCTION_DECLARATION, look_up(cur, $4), $2, CreateFunctionDeclarationInfo(-1, false,NULL)); } + emit_function_dec(table_lookup(cur, $2)); } | EXTERNAL FUNCTION ID COLON ID - { + { if(getAdInfoType(look_up(cur, $5))==TYPE_FUNCTION_TYPE){ - CreateEntry(cur,TYPE_FUNCTION_DECLARATION, look_up(cur, $5), $3, CreateFunctionDeclarationInfo(-1, false)); + if (CreateEntry(cur,TYPE_FUNCTION_DECLARATION, look_up(cur, $5), $3, CreateFunctionDeclarationInfo(-1, false,NULL)) == undefined) { + throw_error(ERROR_TYPE, "Duplicate defination of function in function declaration"); + } } else{ throw_error(ERROR_TYPE, "Function declatation (%s) is not a valid function type", $3); - CreateEntry(cur,TYPE_FUNCTION_DECLARATION, look_up(cur, $5), $3, CreateFunctionDeclarationInfo(-1, false)); + CreateEntry(cur,TYPE_FUNCTION_DECLARATION, look_up(cur, $5), $3, CreateFunctionDeclarationInfo(-1, false,NULL)); } } @@ -329,7 +374,7 @@ idlist: { $$ = $4 + 1; } - + | ID { printdebug("idlist rule 2 ID: %s", $1); TableNode *entry = getFirstEntry(cur); @@ -352,14 +397,13 @@ idlist: printdebug("tag is %d", getAdInfoType(entry)); } - | error { yyerrok; } - ; sblock: L_BRACE { + // emit_label(label_gen()); if (getLine(cur) != 0) { cur = CreateScope(cur,@1.first_line,@1.first_column); printdebug("Created a new scope"); @@ -376,7 +420,7 @@ sblock: } R_BRACE {$$ = $3;} - + | L_BRACE { if (getLine(cur) != 0) { @@ -397,85 +441,95 @@ sblock: printdebug("Moving up a scope after seeing sblock with dblock"); cur = getParent(cur); //$$ = $5; - - } + + } R_BRACE {$$ = $5;} - | error { yyerrok; } - ; dblock: - L_BRACKET + L_BRACKET { if (getLine(cur) == 0) { - setLineNumber(cur, @1.first_line); + setLineNumber(cur, @1.first_line); setColumnNumber(cur,@1.first_line); printdebug("Did not create a new scope when saw dblock, set line number to %d instead", @1.first_line); } else{ //cur = CreateScope(cur,@1.first_line,@1.first_column); // <----- What is this? printdebug("Created a new scope when seeing a dblock"); } - } + } declaration_list R_BRACKET - | error { yyerrok; } - + ; declaration_list: - declaration SEMI_COLON declaration_list - | declaration + declaration SEMI_COLON declaration_list + | declaration + | error SEMI_COLON { yyerrok; } declaration_list //only perform error recovery once we see semi-colon - | error { yyerrok; } - ; declaration: - id_or_types COLON ID + id_or_types COLON ID { printdebug("ID/TYPE: %s, ID: %s", getName((TableNode*)$1), $3) ; int d = getAdInfoType((TableNode*)$1); if(d == TYPE_UNDEFINED) { throw_error(ERROR_TYPE, "Undefined type passed in declaration list"); printdebug("Undefined type passed in declaration list"); - CreateEntry(cur,d,(TableNode*)$1,$3,getAdInfo((TableNode*)$1)); + CreateEntry(cur,d,(TableNode*)$1,$3,getAdInfo((TableNode*)$1)); } else if(d == TYPE_FUNCTION_TYPE) { printdebug("invalid (function) type passed in declaration list in dblock", @2.first_line, @2.first_column); d = TYPE_FUNCTION_DECLARATION; - CreateEntry(cur,d,(TableNode*)$1,$3,getAdInfo((TableNode*)$1)); + + if(CreateEntry(cur,d,(TableNode*)$1,$3,NULL) == undefined){ + throw_error(ERROR_TYPE, "Duplicate defination of function in declaration list"); + } + } else if(d == TYPE_ARRAY_TYPE){ printdebug("array variable at line %d and column %d", @2.first_line, @2.first_column); d = TYPE_ARRAY; - CreateEntry(cur,d,(TableNode*)$1,$3,getAdInfo((TableNode*)$1)); + + if(CreateEntry(cur,d,(TableNode*)$1,$3,getAdInfo((TableNode*)$1)) == undefined){ + throw_error(ERROR_TYPE, "Duplicate defination of array in declaration list"); + } + } else if(d == TYPE_RECORD_TYPE){ printdebug("record variable at line %d and column %d", @2.first_line, @2.first_column); d = TYPE_RECORD; - CreateEntry(cur,d,(TableNode*)$1,$3,getAdInfo((TableNode*)$1)); + + if(CreateEntry(cur,d,(TableNode*)$1,$3,getAdInfo((TableNode*)$1))== undefined){ + throw_error(ERROR_TYPE, "Duplicate defination of record in declaration list"); + } + } else if(d == TYPE_PRIMITIVE_TYPE){ printdebug("primitive variable at line %d and column %d", @2.first_line, @2.first_column); d = TYPE_PRIMITIVE; - CreateEntry(cur,d,(TableNode*)$1,$3,getAdInfo((TableNode*)$1)); + + if(CreateEntry(cur,d,(TableNode*)$1,$3,getAdInfo((TableNode*)$1)) == undefined){ + throw_error(ERROR_TYPE, "Duplicate defination of primitive in declaration list"); + } + }else { throw_error(ERROR_TYPE, "%s is being defined with an undefined type", $3); - CreateEntry(cur,d,(TableNode*)$1,$3,getAdInfo((TableNode*)$1)); + CreateEntry(cur,d,(TableNode*)$1,$3,getAdInfo((TableNode*)$1)); } } - | error { yyerrok; } - ; @@ -486,15 +540,13 @@ id_or_types: printdebug("string of id is %s in ID pattern of id_or_type rule.", $1); $$ = table_lookup(getAncestor(cur), $1); } - + | types { printdebug("string of type is %s in types pattern of id_or_type rule.",getName((TableNode*)$1)); $$ = (TableNode*)$1; } - | error { yyerrok; } - ; @@ -507,14 +559,22 @@ compound_statement statement_list { $$ = $1; } else if ($1 == $2) { $$ = $1; + }else if((getAdInfoType((TableNode*)$1) == TYPE_ARRAY_TYPE) && ((TableNode*)$2)==addr){ + $$ = $1; + }else if((getAdInfoType((TableNode*)$1) == TYPE_RECORD_TYPE) && ((TableNode*)$2)==addr){ + $$ = $1; + }else if(((TableNode*)$1)==addr && (getAdInfoType((TableNode*)$2) == TYPE_ARRAY_TYPE)){ + $$ = $2; + }else if(((TableNode*)$1)==addr && (getAdInfoType((TableNode*)$2) == TYPE_RECORD_TYPE)){ + $$ = $2; } else { - printdebug("differing return types within same function at line %d, column %d", @1.first_line, @1.first_column); + printdebug("1 differing return types within same function at line %d, column %d", @1.first_line, @1.first_column); $$ = undefined; } } | compound_statement { $$ = $1; - } + } | simple_statement SEMI_COLON statement_list{ if ($1 == undefined && $3 != undefined) { $$ = $3; @@ -522,36 +582,98 @@ compound_statement statement_list { $$ = $1; } else if ($1 == $3) { $$ = $1; + }else if((getAdInfoType((TableNode*)$1) == TYPE_ARRAY_TYPE) && ((TableNode*)$3)==addr){ + $$ = $1; + }else if((getAdInfoType((TableNode*)$1) == TYPE_RECORD_TYPE) && ((TableNode*)$3)==addr){ + $$ = $1; + }else if(((TableNode*)$1)==addr && (getAdInfoType((TableNode*)$3) == TYPE_ARRAY_TYPE)){ + $$ = $3; + }else if(((TableNode*)$1)==addr && (getAdInfoType((TableNode*)$3) == TYPE_RECORD_TYPE)){ + $$ = $3; } else { - printdebug("differing return types within same function at line %d, column %d", @1.first_line, @1.first_column); + printdebug("2 differing return types within same function at line %d, column %d", @1.first_line, @1.first_column); $$ = undefined; } } | simple_statement SEMI_COLON { $$ = $1; } + | error SEMI_COLON { yyerrok; } statement_list { $$ = $4; } ; compound_statement: -WHILE L_PAREN expression R_PAREN sblock { - $$ = $5; -} - | IF L_PAREN expression R_PAREN THEN sblock ELSE sblock { - if ($6 == undefined && $8 != undefined) { + WHILE L_PAREN { + S_Push(TrueList, S_Init(), 0); + S_Push(FalseList, S_Init(), 0); + int *l = calloc(1, sizeof(int)); + *l = label_gen(); + emit_label(*l); + S_Push(stack, l, 2); + } expression R_PAREN { + emit_conditional_jump(E_IF_X_FALSE, 0, tn_or_const(NODE, $4)); + Stack * t = S_Peek(FalseList); + S_Push(t, current, 1); + emit_label(label_gen()); + emit_backpatch(S_Pop(TrueList), getLabel(current)); + } sblock { + $$ = $7; + int l = label_gen(); + emit_backpatch(S_Pop(FalseList), l); + emit_goto(*(int*)(S_Pop(stack))); + emit_label(l); + } + // IF L_PAREN expression R_PAREN THEN sblock ELSE sblock + | IF L_PAREN { + S_Push(TrueList, S_Init(), 0); + S_Push(FalseList, S_Init(), 0); + }expression R_PAREN THEN { + int l = label_gen(); + emit_conditional_jump(E_IF_X_TRUE, l, tn_or_const(NODE, $4)); + Stack * t = S_Peek(TrueList); + S_Push(t, current, 1); + + emit_goto(0); + t = S_Peek(FalseList); + S_Push(t, current, 1); + emit_label(l); + emit_backpatch(S_Pop(TrueList), getLabel(current)); + } sblock ELSE { + // NOTE we are not going back to + int l = label_gen(); + emit_backpatch(S_Pop(FalseList), l); + S_Push(stack, S_Init(), 0); + emit_goto(0); + S_Push(S_Peek(stack), current, 1); + emit_label(l); + } sblock { + int l = label_gen(); + emit_backpatch(S_Pop(stack), l); + emit_label(l); + if ($8 == undefined && $11 != undefined) { + $$ = $11; + } else if ($8 != undefined && $11 == undefined) { $$ = $8; - } else if ($6 != undefined && $8 == undefined) { - $$ = $6; - } else if ($6 == $8) { - $$ = $6; + } else if ($8 == $11) { + $$ = $8; + }else if((getAdInfoType((TableNode*)$8) == TYPE_ARRAY_TYPE) && ((TableNode*)$11)==addr){ + $$ = $8; + }else if((getAdInfoType((TableNode*)$8) == TYPE_RECORD_TYPE) && ((TableNode*)$11)==addr){ + $$ = $8; + }else if(((TableNode*)$8)==addr && (getAdInfoType((TableNode*)$11) == TYPE_ARRAY_TYPE)){ + $$ = $11; + }else if(((TableNode*)$8)==addr && (getAdInfoType((TableNode*)$11) == TYPE_RECORD_TYPE)){ + $$ = $11; } else { - printdebug("differing return types within same function at line %d, column %d", @1.first_line, @1.first_column); + printdebug("3 differing return types within same function at line %d, column %d", @1.first_line, @1.first_column); + //printf("%s\n", getName((TableNode*)$6)); + //printf("%s\n", getName((TableNode*)$8)); $$ = undefined; } } - + | sblock { $$ = $1; } @@ -561,36 +683,73 @@ WHILE L_PAREN expression R_PAREN sblock { simple_statement: - assignable ASSIGN expression - { printdebug("simple statement"); - TableNode* node; - if((getAdInfoType((TableNode*)$1) == TYPE_FUNCTION_DECLARATION)|| - (getAdInfoType((TableNode*)$1) == TYPE_ARRAY)|| - (getAdInfoType((TableNode*)$1) == TYPE_RECORD)|| - (getAdInfoType((TableNode*)$1) == TYPE_PRIMITIVE)){ - - node = ((TableNode*)$1); - } else{ - printdebug("Invalid type passed to assignable."); - node = undefined; + assignable{ + //updating context for reserve/release + if(getAdInfoType((TableNode*)$1) == TYPE_ARRAY || getAdInfoType((TableNode*)$1) == TYPE_FUNCTION_DECLARATION){ + PushContext(getTypeEntry((TableNode*)$1)); + + //printf("pushed %s to context stack in simple statement assignable rule\n",getName(getContextTypeEntry(context_head))); } - - - if(getAdInfoType(node) == getAdInfoType((TableNode*)$3)){ - emit_assignment($1, tn_or_const(NODE, $3)); - printdebug("%s[☺] Passed type check; %s = %s", COLOR_GREEN, getName(node), getName((TableNode*)$3)); + S_Push(TrueList, S_Init(), 0); + S_Push(FalseList, S_Init(), 0); + } ASSIGN expression + { +// ---------------------------------------------------------------------------- + if ( getTypeEntry((TableNode*)$4) == boo ) { + emit_label(label_gen()); + } + emit_backpatch(S_Pop(TrueList), getLabel(current)); + emit_backpatch(S_Pop(FalseList), getLabel(current)); +// ---------------------------------------------------------------------------- + printdebug("simple statement"); + TableNode* node; + if((getAdInfoType((getTypeEntry((TableNode*)$1))) == TYPE_FUNCTION_TYPE)|| + (getAdInfoType((getTypeEntry((TableNode*)$1))) == TYPE_ARRAY_TYPE)|| + (getAdInfoType((getTypeEntry((TableNode*)$1))) == TYPE_RECORD_TYPE)|| + (getAdInfoType((getTypeEntry((TableNode*)$1))) == TYPE_PRIMITIVE_TYPE)){ + node = ((TableNode*)$1); } else { - throw_error(ERROR_TYPE, "%s != %s", getName(node), getName((TableNode*)$3)); + //printf("%d\n",getAdInfoType((getTypeEntry((TableNode*)$1)))); + throw_error(ERROR_TYPE, "Invalid type passed to assignable."); + //printf("%d, %d\n", @1.first_line, @1.first_column); + //printf("%s\n", getType(getTypeEntry((TableNode*)$1))); + //printf("%s\n\n", getType(getTypeEntry((TableNode*)$3))); + node = undefined; + } + if(getAdInfoType(node) == getAdInfoType((TableNode*)$4)){ + emit_assignment($1, tn_or_const(NODE, $4)); + printdebug("%s[☺] Passed type check; %s = %s", COLOR_GREEN, getType(node), getType((TableNode*)$4)); + } else if (getTypeEntry(getTypeEntry(node)) == arrayprim && getTypeEntry((TableNode*)$4) == addr) { + emit_assignment($1, tn_or_const(NODE, $4)); + printdebug("%s[☺] Passed type check; %s = %s", COLOR_GREEN, getType(node), getType((TableNode*)$4)); + } else if (getTypeEntry(getTypeEntry(node)) == recprime && getTypeEntry((TableNode*)$4) == addr) { + emit_assignment($1, tn_or_const(NODE, $4)); + printdebug("%s[☺] Passed type check; %s = %s", COLOR_GREEN, getType(node), getType((TableNode*)$4)); + } else { + //printf("%d\n",getAdInfoType((TableNode*)$1)); + //printf("%d\n",getAdInfoType((TableNode*)$3)); + //printf("%d\n",getAdInfoType((TableNode*)$1)); + //printf("%d\n",getAdInfoType((TableNode*)$3)); + throw_error(ERROR_TYPE, "Assignable Assign Expression - Object %s of type %s != Object %s of type %s", getName(node), getType(node), getName((TableNode*)$4), getType((TableNode*)$4)); } - $$ = undefined; + //resetting context + if(getAdInfoType((TableNode*)$1) == TYPE_ARRAY || getAdInfoType((TableNode*)$1) == TYPE_FUNCTION_DECLARATION){ + PopContext(); + printdebug("popped a context off in simplestatement assignable rule\n"); + } } - | RETURN expression {$$ = getTypeEntry((TableNode*)$2);} + | RETURN expression { + $$ = getTypeEntry((TableNode*)$2); + emit_return(tn_or_const(NODE,(TableNode*)$2));} + + // | assignable ASSIGN RESERVE assignable{ } + |simple_statement error {yyerrok; yyclearin; printdebug("error in simple statement");} + + - | error { yyerrok; } - ; @@ -598,41 +757,81 @@ simple_statement: rec_op: DOT - | error { yyerrok; } - + ; ablock: - L_PAREN argument_list R_PAREN + L_PAREN{ + if (stack == NULL){ + stack = S_Init(); + } + Stack * t = S_Init(); + S_Push(stack, t, 0); + } + argument_list { + } R_PAREN { - $$ = $2; +// here + $$ = $3; printdebug("ablock is %d", $$); } - | error { yyerrok; } - + ; - argument_list: - //NEED TO EMIT PARAMETERS HERE. MAYBE USE STACK STRUCTURE - expression COMMA argument_list + + expression{ + PopContext(); + printdebug("popped a context off in argument list\n"); + incrementArgumentNumber(function_head); + TableNode* typeOfArg = getFunctionNumberType(getFunctionType(function_head), getArgumentNumber(function_head)); + PushContext(typeOfArg); + printdebug("pushed %s to context stack\n",getName(typeOfArg)); + TableNode * arg = CreateEntry(cur, getAdInfoType((TableNode*)$1), getTypeEntry((TableNode*)$1), arg_var_gen(), NULL); + //inside a scope of an array call if line number is -2 + if(getLine(cur)==-2){ + if(getTypeEntry(arg) != integ){ + throw_error(ERROR_TYPE, "Argument %s of type %s is not of type integer for an array argument", getName(arg), getType(arg)); + } + } +// ---------------------------------------------------------------------------- + // this is emitting the param withthe wrong TableNode + // We need to fiture out how to get the right one. + Stack * t = S_Peek(stack); + if(t==NULL){ + t = S_Init(); + S_Push(stack, t, 1); + } + emit_parameter(tn_or_const(NODE,$1)); + S_Push(t, current, 1); + emit_detach(); +// ---------------------------------------------------------------------------- + } + COMMA argument_list + {$$ = $4 + 1;} + + | expression + { - CreateEntry(cur,getAdInfoType((TableNode*)$1), (TableNode*)$1, getName((TableNode*)$1), NULL); - $$ = $3 + 1; + PopContext(); + printdebug("popped a context off in argument list (single arg rule)\n"); + TableNode* arg = CreateEntry(cur, getAdInfoType((TableNode*)$1), getTypeEntry((TableNode*)$1), arg_var_gen(), NULL); + //inside a scope of an array call if line number is -2 + if(getLine(cur)==-2){ + if(getTypeEntry(arg) != integ){ + throw_error(ERROR_TYPE, "Argument %s of type %s is not of type integer for an array argument", getName(arg), getType(arg)); + } + } + emit_parameter(tn_or_const(NODE,$1)); + $$ = 1; printdebug("[ARGUMENT_LIST] argument list is %d", $$); } - | expression - { - CreateEntry(cur,getAdInfoType((TableNode*)$1),(TableNode*)$1, getName((TableNode*)$1), NULL); - $$ = 1; printdebug("[ARGUMENT_LIST] argument list is %d", $$); - } - | error { yyerrok; } - + ; @@ -656,7 +855,7 @@ expression: $$ = node; } else { $$=undefined; - throw_error(ERROR_TYPE, "%s != %s", getName(getTypeEntry((TableNode*)$2)), getName(integ)); + throw_error(ERROR_TYPE, "Object %s of type %s is not of type integer and can't be negated", getName((TableNode*)$2), getType((TableNode*)$2)); } } @@ -666,13 +865,15 @@ expression: if(getTypeEntry((TableNode*)$2) == boo) { char* temp = temp_var_gen(); TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, boo, temp, NULL); - emit_unary_op(E_NOT,node,tn_or_const(NODE,$2)); - //NOTE ADD ASSIGNMENT EMIT HERE (MIGHT NEED TO PUSH TO STACK) + Stack * t = S_Pop(TrueList); + Stack * f = S_Pop(FalseList); + S_Push(TrueList, f, 0); + S_Push(FalseList, t, 0); //result of unary operation $$ = node; } else { $$=undefined; - throw_error(ERROR_TYPE, "%s != %s", getName((TableNode*)$2), getName(boo)); + throw_error(ERROR_TYPE, "Object %s of type %s is not of type Boolean and can't be negated", getName((TableNode*)$2), getType((TableNode*)$2)); } } @@ -687,6 +888,7 @@ expression: } else { $$=undefined; throw_error(ERROR_TYPE, "%s != %s", getName((TableNode*)$1), getName((TableNode*)$3)); + throw_error(ERROR_TYPE, "Object %s of type %s and Object %s of type %s must both be integers", getName((TableNode*)$1), getType((TableNode*)$1), getName((TableNode*)$3), getType((TableNode*)$3)); } } @@ -701,7 +903,7 @@ expression: $$ = node; } else { $$=undefined; - throw_error(ERROR_TYPE, "%s != %s", getName((TableNode*)$1), getName((TableNode*)$3)); + throw_error(ERROR_TYPE, "Object %s of type %s and Object %s of type %s must both be integers", getName((TableNode*)$1), getType((TableNode*)$1), getName((TableNode*)$3), getType((TableNode*)$3)); } } @@ -715,7 +917,7 @@ expression: $$ = node; } else { $$=undefined; - throw_error(ERROR_TYPE, "%s != %s", getName((TableNode*)$1), getName((TableNode*)$3)); + throw_error(ERROR_TYPE, "Object %s of type %s and Object %s of type %s must both be integers", getName((TableNode*)$1), getType((TableNode*)$1), getName((TableNode*)$3), getType((TableNode*)$3)); } } @@ -729,7 +931,7 @@ expression: $$ = node; } else { $$=undefined; - throw_error(ERROR_TYPE, "%s != %s", getName((TableNode*)$1), getName((TableNode*)$3)); + throw_error(ERROR_TYPE, "Object %s of type %s and Object %s of type %s must both be integers", getName((TableNode*)$1), getType((TableNode*)$1), getName((TableNode*)$3), getType((TableNode*)$3)); } } @@ -743,64 +945,184 @@ expression: $$ = node; } else { $$=undefined; - throw_error(ERROR_TYPE, "%s != %s", getName((TableNode*)$1), getName((TableNode*)$3)); + throw_error(ERROR_TYPE, "Object %s of type %s and Object %s of type %s must both be integers", getName((TableNode*)$1), getType((TableNode*)$1), getName((TableNode*)$3), getType((TableNode*)$3)); } } | expression AND expression { + char* temp = temp_var_gen(); + TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, boo, temp, NULL); +// ---------------------------------------------------------------------------- + uint_least8_t b = 0; + emit_assignment(node, tn_or_const(BOOLEAN,&b)); + // emit_label(label_gen()); + // emit_backpatch(S_Pop(TrueList), getLabel(current)); + emit_conditional_jump(E_IF_X_FALSE, 0, tn_or_const(NODE, $1)); + Stack * t1 = S_Peek(FalseList); + if(t1==NULL){ + t1 = S_Init(); + S_Push(FalseList, t1, 1); + } + S_Push(t1, current, 1); + emit_goto(0); + t1 = S_Peek(TrueList); + if(t1==NULL){ + t1 = S_Init(); + S_Push(TrueList, t1, 1); + } + S_Push(t1, current, 1); + emit_label(label_gen()); + emit_backpatch(S_Pop(TrueList), getLabel(current)); + emit_conditional_jump(E_IF_X_FALSE, 0, tn_or_const(NODE, $3)); + Stack * t = S_Peek(FalseList); + if(t==NULL){ + t = S_Init(); + S_Push(FalseList, t, 1); + } + S_Push(t, current, 1); + b = 1; + emit_assignment(node, tn_or_const(BOOLEAN,&b)); + emit_goto(0); + t = S_Peek(TrueList); + if(t==NULL){ + t = S_Init(); + S_Push(TrueList, t, 1); + } + S_Push(t, current, 1); + S_Merge(FalseList); +// ---------------------------------------------------------------------------- printdebug("AND"); if((getTypeEntry((TableNode*)$1)==getTypeEntry((TableNode*)$3)) && getTypeEntry((TableNode*)$1) == boo) { - char* temp = temp_var_gen(); - TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, boo, temp, NULL); - emit_binary_op(E_AND,node,tn_or_const(NODE,$1),tn_or_const(NODE,$3)); + //emit_binary_op(E_AND,node,tn_or_const(NODE,$1),tn_or_const(NODE,$3)); $$ = node; } else { $$=undefined; - throw_error(ERROR_TYPE, "%s != %s", getName((TableNode*)$1), getName((TableNode*)$3)); + throw_error(ERROR_TYPE, "Object %s of type %s and Object %s of type %s must both be Boolean", getName((TableNode*)$1), getType((TableNode*)$1), getName((TableNode*)$3), getType((TableNode*)$3)); } } | expression OR expression { + char* temp = temp_var_gen(); + TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, boo, temp, NULL); +// ---------------------------------------------------------------------------- + uint_least8_t b = 1; + emit_assignment(node, tn_or_const(BOOLEAN,&b)); + // emit_label(label_gen()); + // emit_backpatch(S_Pop(TrueList), getLabel(current)); + emit_conditional_jump(E_IF_X_TRUE, 0, tn_or_const(NODE, $1)); + Stack * t1 = S_Peek(TrueList); + if(t1==NULL){ + t1 = S_Init(); + S_Push(TrueList, t1, 1); + } + S_Push(t1, current, 1); + emit_goto(0); + t1 = S_Peek(FalseList); + if(t1==NULL){ + t1 = S_Init(); + S_Push(FalseList, t1, 1); + } + S_Push(t1, current, 1); + emit_label(label_gen()); + emit_backpatch(S_Pop(FalseList), getLabel(current)); + emit_conditional_jump(E_IF_X_TRUE, 0, tn_or_const(NODE, $3)); + Stack * t = S_Peek(TrueList); + if(t==NULL){ + t = S_Init(); + S_Push(TrueList, t, 1); + } + S_Push(t, current, 1); + b = 0; + emit_assignment(node, tn_or_const(BOOLEAN,&b)); + emit_goto(0); + t = S_Peek(FalseList); + if(t==NULL){ + t = S_Init(); + S_Push(FalseList, t, 1); + } + S_Push(t, current, 1); + S_Merge(TrueList); +// ---------------------------------------------------------------------------- printdebug("OR"); if((getTypeEntry((TableNode*)$1)==getTypeEntry((TableNode*)$3)) && getTypeEntry((TableNode*)$1) == boo) { - char* temp = temp_var_gen(); - TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, boo, temp, NULL); - emit_binary_op(E_OR,node,tn_or_const(NODE,$1),tn_or_const(NODE,$3)); $$ = node; } else { $$=undefined; - throw_error(ERROR_TYPE, "%s != %s", getName((TableNode*)$1), getName((TableNode*)$3)); + throw_error(ERROR_TYPE, "Object %s of type %s and Object %s of type %s must both be Boolean", getName((TableNode*)$1), getType((TableNode*)$1), getName((TableNode*)$3), getType((TableNode*)$3)); } } - - | expression LESS_THAN expression + + | expression LESS_THAN expression { - printdebug("less than expression"); - if(getTypeEntry((TableNode*)$1) == getTypeEntry((TableNode*)$3) && getTypeEntry((TableNode*)$1)==integ) { char* temp = temp_var_gen(); TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, boo, temp, NULL); - emit_binary_op(E_LESS_THAN,node,tn_or_const(NODE,$1),tn_or_const(NODE,$3)); +// ---------------------------------------------------------------------------- + // emit_label(label_gen()); + // emit_backpatch(S_Pop(TrueList), getLabel(current)); + emit_binary_op(E_LESS_THAN, node, tn_or_const(NODE,$1), tn_or_const(NODE,$3)); + emit_conditional_jump(E_IF_X_TRUE, 0, tn_or_const(NODE, node)); + Stack * t = S_Peek(TrueList); + if(t==NULL){ + t = S_Init(); + S_Push(TrueList, t, 1); + } + S_Push(t, current, 1); + emit_goto(0); + t = S_Peek(FalseList); + if(t==NULL){ + t = S_Init(); + S_Push(FalseList, t, 1); + } + S_Push(t, current, 1); + /* + */ +// ---------------------------------------------------------------------------- + printdebug("less than expression"); + if(getTypeEntry((TableNode*)$1) == getTypeEntry((TableNode*)$3) && getTypeEntry((TableNode*)$1)==integ) { $$ = node; - } else { + } else if(getTypeEntry((TableNode*)$1) == getTypeEntry((TableNode*)$3) && getTypeEntry((TableNode*)$1)==boo){ + $$ = node; + }else { $$=undefined; - throw_error(ERROR_TYPE, "%s != %s", getName((TableNode*)$1), getName((TableNode*)$3)); + throw_error(ERROR_TYPE, "Object %s of type %s and Object %s of type %s must both be integers", getName((TableNode*)$1), getType((TableNode*)$1), getName((TableNode*)$3), getType((TableNode*)$3)); } } | expression EQUAL_TO expression { - printdebug("equals check expression"); - if(getTypeEntry((TableNode*)$1) == getTypeEntry((TableNode*)$3) && getTypeEntry((TableNode*)$1) != undefined) { char* temp = temp_var_gen(); TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, boo, temp, NULL); - emit_binary_op(E_EQUAL_TO,node,tn_or_const(NODE,$1),tn_or_const(NODE,$3)); +// ---------------------------------------------------------------------------- + emit_binary_op(E_EQUAL_TO, node, tn_or_const(NODE,$1), tn_or_const(NODE,$3)); + emit_conditional_jump(E_IF_X_TRUE, 0, tn_or_const(NODE, node)); + Stack * t = S_Peek(TrueList); + if(t==NULL){ + t = S_Init(); + S_Push(TrueList, t, 1); + } + S_Push(t, current, 1); + emit_goto(0); + t = S_Peek(FalseList); + if(t==NULL){ + t = S_Init(); + S_Push(FalseList, t, 1); + } + S_Push(t, current, 1); + /* + */ + // emit_label(label_gen()); + // emit_backpatch(S_Pop(TrueList), getLabel(current)); +// ---------------------------------------------------------------------------- + printdebug("equals check expression"); + if(getTypeEntry((TableNode*)$1) == getTypeEntry((TableNode*)$3) && getTypeEntry((TableNode*)$1) != undefined) { + // emit_binary_op(E_EQUAL_TO, node, tn_or_const(NODE,$1), tn_or_const(NODE,$3)); $$ = node; - + } else { $$ = undefined; - throw_error(ERROR_TYPE, "%s != %s", getName((TableNode*)$1), getName((TableNode*)$3)); + throw_error(ERROR_TYPE, "Object %s of type %s and Object %s of type %s must both be the same type", getName((TableNode*)$1), getType((TableNode*)$1), getName((TableNode*)$3), getType((TableNode*)$3)); } } @@ -808,29 +1130,162 @@ expression: { $$ = $1; } - + | L_PAREN expression R_PAREN + // TODO: We need to check if we need to backpatch here. { printdebug("paren expression. current type is %s",getType((TableNode*)$2)); $$=$2; } - | memOp assignable + // TODO: We need to type check this. + /*| RESERVE ID { + char* temp = temp_var_gen(); + TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, addr, temp, NULL); + TableNode * n = look_up(cur, $2); + if(getAdInfoType(n) != TYPE_RECORD){ + throw_error(ERROR_TYPE, "Invalid Reserve expression with object %s of type %s.", + getName((TableNode*)n), getType((TableNode*)n)); + $$=undefined; + } + int v = getRecTotal(getTypeEntry(n)); + emit_reserve(node, tn_or_const(INTEGER, &v)); + $$ = node; + } + | RELEASE ID { + TableNode * n = look_up(cur, $2); + if(getAdInfoType(n) != TYPE_RECORD){ + throw_error(ERROR_TYPE, "Invalid Release expression with object %s of type %s.", + getName((TableNode*)n), getType((TableNode*)n)); + $$=undefined; + } + char* temp = temp_var_gen(); + TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, integ, temp, NULL); + //emit release needed here + $$ = node; + } + | RESERVE ID { + cur = CreateScope(cur, -2,-1); + } ablock { + char* temp = temp_var_gen(); + TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, addr, temp, NULL); + int a = S_Size(S_Peek(stack)) + 1; + emit_push_all(S_Peek(stack)); + S_Pop(stack); + emit_function_call(node, a, tn_or_const(NODE, $2)); + $$ = node; + TableNode * n = look_up(cur, $2); + if(getAdInfoType(n) != TYPE_ARRAY){ + throw_error(ERROR_TYPE, "Invalid Reserve expression with object %s of type %s.", + getName(n), getType(n)); + $$=undefined; + } + //doing more complicated type checking in a block + if(getNumArrDim(getTypeEntry(n)) != $4){ + throw_error(ERROR_SYNTAX, "expected %d dimensions for this array but got %d", getNumArrDim(getTypeEntry(n)), $4); + $$=undefined; + } + cur = getParent(cur); + }*/ + | RESERVE assignable{ + + if(getTypeEntry((TableNode*)$2) == getContextTypeEntry(context_head) + && (/*getAdInfoType((TableNode*)$2)==TYPE_ARRAY ||*/ getAdInfoType(getTypeEntry((TableNode*)$2)) == TYPE_RECORD)){ + char* temp = temp_var_gen(); + //does this have integer? + TableNode* node = CreateEntry(cur,TYPE_RECORD, getContextTypeEntry(context_head), temp, NULL); + emit_reserve(node, tn_or_const(NODE,$2)); + $$ = node; + } + else if(((getTypeEntry((TableNode*)$2)) == getArrType(getContextTypeEntry(context_head))) + && (getAdInfoType(getContextTypeEntry(context_head)) == TYPE_ARRAY_TYPE)){ + char* temp = temp_var_gen(); + //does this have integer? + TableNode* node = CreateEntry(cur,TYPE_ARRAY, getContextTypeEntry(context_head), temp, NULL); + emit_reserve(node, tn_or_const(NODE,$2)); + $$ = node; + }else{ + //printf("%s on right %s on left\n",getType((TableNode*)$2),getName(getArrType(getContextTypeEntry(context_head)))); + //printf("%s is the name of the left\n",getName(getContextTypeEntry(context_head))); + $$ = undefined; + } + } + + | RELEASE assignable{ + + if(getTypeEntry((TableNode*)$2) == getContextTypeEntry(context_head) + && (/*getAdInfoType((TableNode*)$2)==TYPE_ARRAY ||*/ getAdInfoType(getTypeEntry((TableNode*)$2)) == TYPE_RECORD)){ + char* temp = temp_var_gen(); + //does this have integer? + TableNode* node = CreateEntry(cur,TYPE_RECORD, getContextTypeEntry(context_head), temp, NULL); + emit_release((TableNode*)$2); + $$ = node; + } + else if(((getTypeEntry((TableNode*)$2)) == getArrType(getContextTypeEntry(context_head))) + && (getAdInfoType(getContextTypeEntry(context_head)) == TYPE_ARRAY_TYPE)){ + char* temp = temp_var_gen(); + //does this have integer? + TableNode* node = CreateEntry(cur,TYPE_ARRAY, getContextTypeEntry(context_head), temp, NULL); + emit_release((TableNode*)$2); + $$ = node; + }else{ + $$=undefined; + } + } + +/* + TableNode* node = CreateEntry(cur,getAdInfoType((TableNode*)$2), getTypeEntry(), temp, NULL); + int a = S_Size(S_Peek(stack)) + 1; + emit_push_all(S_Peek(stack)); + S_Pop(stack); + emit_function_call(node, a, tn_or_const(NODE, $2)); + $$ = node; + TableNode * n = look_up(cur, $2); + if(getAdInfoType(n) != TYPE_ARRAY){ + throw_error(ERROR_TYPE, "Invalid Reserve expression with object %s of type %s.", + getName(n), getType(n)); + $$=undefined; + } + */ +/* + | RELEASE assignable{ + char* temp = temp_var_gen(); + TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, integ, temp, NULL); + int a = S_Size(S_Peek(stack)) + 1; + emit_push_all(S_Peek(stack)); + S_Pop(stack); + emit_function_call(node, a, tn_or_const(NODE, $2)); + $$ = node; + TableNode * n = look_up(cur, $2); + if(getAdInfoType(n) != TYPE_ARRAY){ + throw_error(ERROR_TYPE, "Invalid Release expression with object %s of type %s.", + getName(n), getType(n)); + $$=undefined; + } + //doing more complicated type checking in a block + //if(getNumArrDim(getTypeEntry(n)) != $4){ + // throw_error(ERROR_SYNTAX, "expected %d dimensions for this array but got %d", getNumArrDim(getTypeEntry(n)), $4); + // $$=undefined; + //} + + } +/* + | RELEASE assignable { int d = getAdInfoType((TableNode*)$2); - if(d == TYPE_ARRAY ||d == TYPE_RECORD) { + //commenting out type checks for now since assignable is being resolved to something before reserve is being applied which is tricky + //if(d == TYPE_ARRAY ||d == TYPE_RECORD) { char* temp = temp_var_gen(); TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, addr, temp, NULL); //NOTE ADD ASSIGNMENT EMIT HERE (MIGHT NEED TO PUSH TO STACK) $$ = node; - } else { - throw_error(ERROR_TYPE, "Invalid memOp expression (%s).", getName((TableNode*)$2)); - $$=undefined; - } + // } else { + // throw_error(ERROR_TYPE, "Invalid memOp expression with object %s of type %s.", getName((TableNode*)$2), getType((TableNode*)$2)); + // $$=undefined; + // } } +*/ - | error { yyerrok; } - ; //UPDATED $$ for tablenodes to this point @@ -839,92 +1294,107 @@ expression: // add array case // include type check for ablock in arrays - ablock is always the int of the elements in array/rec assignable: - ID + ID { TableNode* pass = look_up(cur,$1); if(pass == undefined){ throw_error(ERROR_TYPE, "Undefined variable %s", $1); } - $$ = pass; + $$ = pass; printdebug("[ASSIGNABLE - RULE 1] assignable = type: %s | ID = %s", getType(pass), getName(pass)); } - - | assignable + | assignable { + //TableNode* pass = look_up(cur,$1); + //if(pass == undefined){ + // throw_error(ERROR_TYPE, "Undefined variable %s", $1); + if(getAdInfoType((TableNode*)$1) == TYPE_ARRAY|| getAdInfoType((TableNode*)$1) == TYPE_FUNCTION_DECLARATION){ + PushFunction(1,(TableNode*)$1); + PushContext(getFunctionNumberType(getFunctionType(function_head), getArgumentNumber(function_head))); + printdebug("pushed %s to function stack\n",getName((TableNode*)$1)); + } printdebug("%sBeginning rule 2 of assignable.", COLOR_CYAN); + //Creating a dummy scope where we create entries for all the arguments of a function call + //Must also consider that we might be in an array access + if(getAdInfoType((TableNode*)$1) == TYPE_ARRAY){ + //PushContext(3); + printdebug("%sCreating scope for array access", COLOR_CYAN); + //special scope for numbers for array access scope + cur = CreateScope(cur, -2,-1); + }else{ cur = CreateScope(cur, -1,-1); + } + + if(getAdInfoType((TableNode*)$1) == TYPE_FUNCTION_DECLARATION){ + //the function context is created. Pushing the type of the function since that has the information needed + } + } //we have to consider emmissions in ablocks - ablock + ablock { + if(getAdInfoType((TableNode*)$1) == TYPE_ARRAY|| getAdInfoType((TableNode*)$1) == TYPE_FUNCTION_DECLARATION){ + PopFunction(); + } + //PopContext(); //int type = getAdInfoType(look_up(getParent(cur), getName((TableNode*)$1))); int type = getAdInfoType(getTypeEntry((TableNode*)$1)); printdebug("%stype is %d", COLOR_PURPLE, type); printdebug("%s", getName((TableNode*)$1)); - + if (type == TYPE_FUNCTION_TYPE) { printdebug("%sEntering function call", COLOR_LIGHTGREEN); - if (look_up(getParent(cur), getType((TableNode*)$1))->additionalinfo->FunDecAdInfo->regularoras) { - printdebug("as function"); - //char *funtype = getType(look_up(cur, $1)); - //printdebug("%s", getType(look_up(cur, getName((TableNode*)$1)))); - - - - TableNode * typeNode = getTypeEntry((TableNode*)$1); - TableNode *param = getParameter(typeNode); - printTableNode(param); - - if (getAdInfoType(param) == TYPE_RECORD_TYPE) { - SymbolTable *recList = getRecList(param); - TableNode *lastCheckedRef = getFirstEntry(recList); - TableNode *lastCheckedAct = getFirstEntry(cur); - while (getNextEntry(lastCheckedRef) != NULL) { - lastCheckedRef = getNextEntry(lastCheckedRef); + //getting the parameter. The type of assignable is a function type so we need to access the paramater of the type + TableNode *expected = getParameter(getTypeEntry((TableNode*)$1)); + //Jump into case where the parameter is a record type + if(getAdInfoType(expected) == TYPE_RECORD_TYPE){ + //int argument_size = getRecSize(cur); + int parameter_size = getRecSize(getRecList(expected)); + printdebug("argument size is %d\n", $3); + printdebug("parameter size is %d\n", parameter_size); + if ($3 != parameter_size) { + throw_error(ERROR_SYNTAX, "expected %d arguments for this function but got %d", parameter_size, $3); + }else{ + TableNode* param_arg_type = getFirstEntry(getRecList(expected)); + TableNode* arg_given = getFirstEntry(cur); + while(arg_given != NULL && arg_given != undefined && getName(arg_given)[0]!='&'){ + arg_given = getNextEntry(arg_given); } - - if ($3 != getRecLength(param)) { - printdebug("expected %d arguments but got %d", getRecLength(param), $3); + if(getTypeEntry(arg_given) != getTypeEntry(param_arg_type)){ + throw_error(ERROR_TYPE, "expected %s expression as first argument of a record in function call but got %s", getType(param_arg_type), getType(arg_given)); } - //this isn't very efficient, but will hopefully work - while (lastCheckedAct != NULL && lastCheckedRef != NULL) { - if (getTypeEntry(lastCheckedRef) != getTypeEntry(lastCheckedAct)) { - printdebug("expected %s. expression in function call got %s. at line %d and column %d",getType(lastCheckedRef), getName(lastCheckedAct), @3.first_line, @3.first_column); - + param_arg_type = getNextEntry(param_arg_type); + arg_given = getNextEntry(arg_given); + while(arg_given != NULL && arg_given != undefined && param_arg_type != NULL){ + while(arg_given != NULL && getName(arg_given)[0]!='&'){ + arg_given = getNextEntry(arg_given); } - lastCheckedAct = getNextEntry(lastCheckedAct); - TableNode *tn = getFirstEntry(recList); - - if (tn != lastCheckedRef) { - while (getNextEntry(tn) != lastCheckedRef) { - tn = getNextEntry(tn); - } - lastCheckedRef = tn; - } else {break;} - } - } else { - if (strcmp(getName(param), getName(getFirstEntry(cur))) != 0) { - printdebug("expected %s expression in function call but got %s", getName(param), getName(getFirstEntry(cur))); - } - - if (getNextEntry(getFirstEntry(cur)) != NULL) { - printdebug("expected 1 parameter, but got multiple in function call"); + if(getTypeEntry(arg_given) != getTypeEntry(param_arg_type)){ + throw_error(ERROR_TYPE, "expected type %s expression as argument of a record in function call but got type %s", getType(param_arg_type), getType(arg_given)); + } + arg_given = getNextEntry(arg_given); + param_arg_type = getNextEntry(param_arg_type); } } - } else { - char *expected = getName(getParameter(look_up(getParent(cur), getType((TableNode*)$1)))); - char *actual = getType(getFirstEntry(cur)); - if (strcmp(expected, actual) != 0) { - printdebug("expected %s expression in function call but got %s at line %d and column %d",expected, actual, @3.first_line, @3.first_column); - } - if ($3 != 1) { - printdebug("expected 1 argument but got %d", $3); + }else{ + TableNode*actual_instance = getFirstEntry(cur); + while(actual_instance != NULL && actual_instance != undefined && getName(actual_instance)[0] !='&'){ + actual_instance = getNextEntry(actual_instance); } + if(actual_instance == NULL){ + throw_error(ERROR_TYPE, "Invalid function call. No arguments passed"); + break; } + TableNode *actual = getTypeEntry(actual_instance); + if (expected != actual) { + throw_error(ERROR_TYPE, "expected %s expression in single argument function call but got %s", getType(expected), getName(actual)); + } + if ($3 != 1) { + throw_error(ERROR_SYNTAX, "expected 1 argument but got %d", $3); } printTableNode(getReturn(getTypeEntry((TableNode*)$1))); - // + } char* temp = temp_var_gen(); - TableNode* typeNode2 = getReturn(getTypeEntry($1)); + TableNode* typeNode2 = getReturn(getTypeEntry((TableNode*)$1)); int t = -1; if(getAdInfoType(typeNode2) == TYPE_PRIMITIVE_TYPE){ t = TYPE_PRIMITIVE; @@ -935,21 +1405,29 @@ assignable: else if(getAdInfoType(typeNode2) == TYPE_RECORD_TYPE){ t = TYPE_RECORD; } + //this may need to be updated to provide the correct name of things else if(getAdInfoType(typeNode2) == TYPE_FUNCTION_TYPE){ t = TYPE_FUNCTION_DECLARATION; }else{ t= TYPE_UNDEFINED; - printdebug("CHANGE ME [TYPE CHECK] Undefined type stored in record. improper."); + throw_error(ERROR_TYPE, "Undefined type returned by function."); } TableNode* node = CreateEntry(cur,t, typeNode2, temp, NULL); +//----------------------------------------------------------------------------- + // Please don't touch + // the + 1 is here because I don't detach the last param + int a = S_Size(S_Peek(stack)) + 1; + emit_push_all(S_Peek(stack)); + S_Pop(stack); + emit_function_call(node, a, tn_or_const(NODE, $1)); +//----------------------------------------------------------------------------- $$ = node; //NOTE ADD ASSIGNMENT EMIT HERE (MIGHT NEED TO PUSH TO STACK for function call) printdebug("[ASSIGNABLE - RULE 2] assignable = type: %s | name_func = %s", getName(typeNode2), getName((TableNode*)$1)); - } else if (type == TYPE_ARRAY_TYPE) { printdebug("%sEntering array call", COLOR_LIGHTGREEN); - if (getNumArrDim(look_up(getParent(cur), getType((TableNode*)$1))) != $2) { - printdebug("expected %d arguments but had %d at line %d and column %d\n", getNumArrDim(look_up(cur, getName((TableNode*)$1))), $2, @2.first_line, @2.first_column); + if (getNumArrDim(getTypeEntry((TableNode*)$1)) != $3) { + throw_error(ERROR_SYNTAX, "expected %d arguments for this array but got %d", getNumArrDim(getTypeEntry((TableNode*)$1)), $3); } char* temp = temp_var_gen(); @@ -968,25 +1446,43 @@ assignable: t = TYPE_FUNCTION_DECLARATION; }else{ t= TYPE_UNDEFINED; - printdebug("CHANGE ME [TYPE CHECK] Undefined type stored in record. improper."); + throw_error(ERROR_TYPE, "Undefined type stored in array."); } TableNode* node = CreateEntry(cur,t, typeNode2, temp, NULL); - //emit assign here - //emit_array_access(char* node, char* array, ...) + //TODO: emit assign here + //TODO: emit_array_access(char* node, char* array, ...) $$ = node; printdebug("[ASSIGNABLE - RULE 2] assignable = type: %s | name_func = %s", getType((TableNode*)$1), getName((TableNode*)$1)); } cur = getParent(cur); } - - | assignable rec_op ID - { - if(getAdInfoType((TableNode*)$1) != TYPE_RECORD_TYPE){ - printdebug("CHANGE ME [TYPE CHECK]Invalid type passed to record access"); + | assignable rec_op ACCESS + { + if(getAdInfoType((TableNode*)$1) != TYPE_ARRAY){ + throw_error(ERROR_TYPE, "Invalid type passed to array access"); + $$ = undefined; + }else if($3>getNumArrDim(getTypeEntry((TableNode*)$1))){ + throw_error(ERROR_TYPE, "Invalid trying to access the size of dimension %d but this array only has %d dimensions", $3, getNumArrDim(getTypeEntry((TableNode*)$1))); + $$ = undefined; + } else{ + char* temp = temp_var_gen(); + int t = 6; + //emission + // arr._1 .... + $$ = CreateEntry(cur,t, integ, temp, NULL); } - else if(undefined != table_lookup(getRecList(table_lookup(getAncestor(cur), getName(getTypeEntry((TableNode*)$1)))), $3)) { + } - TableNode* type = table_lookup(getRecList(table_lookup(getAncestor(cur), getName(getTypeEntry((TableNode*)$1)))), $3); + | assignable rec_op ID + { + + if(getAdInfoType((TableNode*)$1) != TYPE_RECORD){ + throw_error(ERROR_TYPE, "Invalid type passed to record access"); + $$ = undefined; + } + else if(undefined != table_lookup(getRecList(getTypeEntry((TableNode*)$1)), $3)) { + + TableNode* type = getTypeEntry(table_lookup(getRecList(getTypeEntry((TableNode*)$1)), $3)); char* temp = temp_var_gen(); int t = -1; if(getAdInfoType(type) == TYPE_PRIMITIVE_TYPE){ @@ -1002,39 +1498,22 @@ assignable: t = TYPE_FUNCTION_DECLARATION; }else{ t= TYPE_UNDEFINED; - printdebug("CHANGE ME [TYPE CHECK] Undefined type stored in record. improper."); + throw_error(ERROR_TYPE, "Undefined type stored in record."); } TableNode* node = CreateEntry(cur,t, type, temp, NULL); - //NOTE ADD ASSIGNMENT EMIT HERE (MIGHT NEED TO PUSH TO STACK) - //emit_field_access(char* node, char* record, $3) + // getElementOffset(rec, ID) + // NOTE ADD ASSIGNMENT EMIT HERE (MIGHT NEED TO PUSH TO STACK) + // emit_field_access(char* node, char* record, $3) + int n = getElementOffset(getTypeEntry((TableNode*)$1), $3); + emit_field_access(node, tn_or_const(NODE, $1), n); $$=node; }else{ - printdebug("CHANGE ME [TYPE CHECK] undefined type (Field Access Lookup failed)"); + throw_error(ERROR_TYPE, "Invalid field access %s", $3); $$=undefined; - } + } printdebug("[ASSIGNABLE - RULE 3] record = name: %s | field = %s", getName((TableNode*)($1)), getName((TableNode*)$3)); } - - | error { yyerrok; } - - ; - - - -memOp: - RESERVE - { - printdebug("reserve expression"); - } - - | RELEASE - { - printdebug("release expression"); - } - - | error { yyerrok; } - ; @@ -1042,7 +1521,7 @@ constant: C_STRING { char* temp = temp_var_gen(); - TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, stri, temp, NULL); + TableNode* node = CreateEntry(cur,TYPE_ARRAY, stri, temp, NULL); emit_assignment(node, tn_or_const(STRING,$1)); printdebug("string of C_STRING in constant is %s", $1); $$ = node; @@ -1056,7 +1535,7 @@ constant: printdebug("number of C_INTEGER in constant is %d", $1); $$ = node; } - + | C_NULL { char* temp = temp_var_gen(); @@ -1065,16 +1544,16 @@ constant: printdebug("string of C_NULL in constant is NULL"); $$ = node; } - + | C_CHARACTER { char* temp = temp_var_gen(); TableNode* node = CreateEntry(cur,TYPE_PRIMITIVE, chara, temp, NULL); emit_assignment(node, tn_or_const(CHARACTER,&$1)); - printdebug("string of C_CHARACTER in constant is %s",$1); + //printdebug("string of C_CHARACTER in constant is %s",$1); $$ = node; } - + | C_TRUE { char* temp = temp_var_gen(); @@ -1084,7 +1563,7 @@ constant: printdebug("string of C_TRUE in constant is true"); $$ = node; } - + | C_FALSE { char* temp = temp_var_gen(); @@ -1099,25 +1578,25 @@ constant: -types: +types: T_INTEGER { $$ = $1; printdebug("string of T_INTEGER in types is %s",getName((TableNode*)$1)); } - + | T_ADDRESS { $$ = $1; printdebug("string of T_ADDRESS in types is %s",getName((TableNode*)$1)); } - + | T_CHARACTER { $$ = $1; printdebug("string of T_CHARACTER in types is %s",getName((TableNode*)$1)); } - + | T_BOOLEAN { $$ = $1; @@ -1155,7 +1634,7 @@ void throw_error(ErrorType error_type, const char *format, ...) { } if (asc_flag) { - /* yyerror(""); */ + yyerror(""); int needed = snprintf(NULL, 0, " LINE (%d:%d) ** %s ERROR: ", line, column, error_name); char *error_message = malloc(needed + 1); snprintf(error_message, needed + 1, " LINE (%d:%d) ** %s ERROR: ", line, column, error_name); @@ -1186,7 +1665,7 @@ void throw_error(ErrorType error_type, const char *format, ...) { return; } - snprintf(total_error_message, total_needed, "%s%s\n\n", error_message, error_message2); + snprintf(total_error_message, total_needed, "%s%s\n", error_message, error_message2); if (tc_flag) { insert_code_line(total_error_message, line); } else { @@ -1204,13 +1683,14 @@ void throw_error(ErrorType error_type, const char *format, ...) { void yyerror(const char *err) { int line = yylloc.first_line; int column = yylloc.first_column; - + contains_errors = true; + // Grammar Fallback Case if (strcmp(err, "syntax error") == 0) { if (asc_flag != NULL) { - int needed = snprintf(NULL, 0, " LINE (%d:%d) ** SYNTAX ERROR: Incorrect syntax at token '%s'\n\n", line, column, yytext); + int needed = snprintf(NULL, 0, " LINE (%d:%d) ** SYNTAX ERROR: Incorrect syntax at token '%s'\n", line, column, yytext); char *error_message = malloc(needed + 1); - snprintf(error_message, needed + 1, " LINE (%d:%d) ** SYNTAX ERROR: Incorrect syntax at token '%s'\n\n", line, column, yytext); + snprintf(error_message, needed + 1, " LINE (%d:%d) ** SYNTAX ERROR: Incorrect syntax at token '%s'\n", line, column, yytext); insert_code_line(error_message, line); } else { @@ -1218,3 +1698,4 @@ void yyerror(const char *err) { } } } + diff --git a/src/intermediate_code.c b/src/intermediate_code.c index 9948115..813b51a 100644 --- a/src/intermediate_code.c +++ b/src/intermediate_code.c @@ -3,43 +3,145 @@ #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) { +Stack *S_Init() { + Stack *s = calloc(1, sizeof(*s)); + return s; +} + +void S_Free(Stack *s) { + // since we are not responsible for the values we can just pop until + // NULL + for (void *p = S_Pop(s); p != NULL; p = S_Pop(s)); + free(s); +} + +void S_Push(Stack *s, void *v, int i) { + __Node *n = calloc(1, sizeof(*n)); + n->v = v; + n->next = s->n; + s->n = n; + s->w = i; + s->size = s->size + 1; +} + +void *S_Pop(Stack *s) { + if (s == NULL || S_IsEmpty(s)) { + return NULL; + } + __Node *node = s->n; + s->n = node->next; + s->size = s->size - 1; + void *r = node->v; + free(node); + return r; +} + +void *S_Peek(Stack *s) { + if (s == NULL || S_IsEmpty(s)) { + return NULL; + } + return s->n->v; +} + +bool S_IsEmpty(Stack *s) { + if (s == NULL || s->size == 0) { + return true; + } + return false; +} + +int S_Size(Stack *s) { + if (s == NULL || S_IsEmpty(s)) { + return 0; + } + return s->size; +} + +void S_Merge(Stack *list) { + Stack *s1 = S_Pop(list); + Stack *s2 = S_Peek(list); + if (s1 == NULL) { + return; + } + if (s2 == NULL) { + S_Push(list, s1, 0); + return; + } + for (Instruction *i = S_Pop(s1); i; i = S_Pop(s1)) { + S_Push(s2, i, 1); + } +} +void emit_backpatch(Stack *s, int l) { + for (Instruction *i = S_Pop(s); i; i = S_Pop(s)) { + i->label = l; + } +} +//_______________________________________________________________________ + +char *temp = NULL; + +/* + 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. + */ + +void emit_push_all(Stack *s) { + for (Instruction *i = S_Pop(s); i; i = S_Pop(s)) { + current->next = i; + i->prev = current; + i->index = current->index + 1; + current = i; + current->next = NULL; + } +} + +void emit_detach() { + current = current->prev; + current->next = NULL; +} + +void backpatch(Stack *s, int l) { + while (!S_IsEmpty(s)) { + Instruction *i = S_Pop(s); + set_label(i, l); + } +} + +TNodeOrConst *getOperand1(Instruction *i) { return i->operand1; } -TNodeOrConst* getOperand2(Instruction* i) { +TNodeOrConst *getOperand2(Instruction *i) { return i->operand2; } -TableNode* getResult(Instruction* i) { +TableNode *getResult(Instruction *i) { return i->result; } -Op getOp(Instruction* i) { +Op getOp(Instruction *i) { return i->opcode; } -int getLabel(Instruction* i) { +int getLabel(Instruction *i) { return i->label; } -int get_index(Instruction* i) { +int get_index(Instruction *i) { return i->index; } -void set_label(Instruction* i, int label) { +void set_label(Instruction *i, int label) { i->label = label; } -bool isConst(TNodeOrConst* tnc) { +bool isConst(TNodeOrConst *tnc) { return tnc->d != NODE; } -TNodeOrConst* tn_or_const(Discriminant d, void* tnc) { - TNodeOrConst* count = calloc(1, sizeof(*count)); +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) { @@ -53,20 +155,21 @@ TNodeOrConst* tn_or_const(Discriminant d, void* tnc) { count->tnc_union->string = tnc; break; case INTEGER: - count->tnc_union->integer = *(int*)tnc; + count->tnc_union->integer = *(int *)tnc; break; case CHARACTER: - count->tnc_union->character = *(char*)tnc; + count->tnc_union->character = *(char *)tnc; break; case BOOLEAN: - count->tnc_union->Boolean = *(uint_least8_t*)tnc; + count->tnc_union->Boolean = *(uint_least8_t *)tnc; break; } return count; } + static void emit_helper(void) { - Instruction* inst = calloc(1, sizeof(*inst)); + Instruction *inst = calloc(1, sizeof(*inst)); if (begin == NULL) { begin = current = inst; current->index = 1; @@ -77,8 +180,18 @@ static void emit_helper(void) { current = inst; } } +void emit_function_dec(TableNode * name){ + emit_helper(); + current->opcode = E_FUNC_DEC; + current->result = name; +} -void emit_binary_op(Op op, TableNode* result, TNodeOrConst* arg1, TNodeOrConst* arg2) { +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 @@ -87,22 +200,28 @@ void emit_binary_op(Op op, TableNode* result, TNodeOrConst* arg1, TNodeOrConst* current->operand2 = arg2; } -void emit_unary_op(Op op, TableNode* result, TNodeOrConst* arg) { +void emit_goto(int i) { + emit_helper(); + current->opcode = E_GOTO; + current->label = i; +} + +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) { +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; +char *get_string(TNodeOrConst *tc) { + char *s; switch (tc->d) { case NODE: return getName(tc->tnc_union->node); @@ -126,119 +245,6 @@ char* get_string(TNodeOrConst* tc) { } } -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; @@ -259,18 +265,18 @@ void emit_conditional_jump(Op condition, int label, ...) { va_start(argptr, label); current->opcode = condition; current->label = label; - TNodeOrConst* n1; - TNodeOrConst* n2; + TNodeOrConst *n1; + TNodeOrConst *n2; switch (condition) { case E_IF_X_TRUE: case E_IF_X_FALSE: - n1 = va_arg(argptr, TNodeOrConst*); + 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*); + n1 = va_arg(argptr, TNodeOrConst *); + n2 = va_arg(argptr, TNodeOrConst *); current->operand1 = n1; current->operand2 = n2; break; @@ -278,123 +284,354 @@ void emit_conditional_jump(Op condition, int label, ...) { va_end(argptr); } -void emit_function_start(TNodeOrConst * name) { +void emit_function_start(TableNode *name) { emit_helper(); - current->opcode = E_LABEL; // I think this is right TODO: ask - current->operand1 = name; - // this is probabaly a func declaration + current->opcode = E_FUNC_START; + current->result = name; } -void emit_parameter(TNodeOrConst* param) { +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) { +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->operand1 = name; + current->operand2 = tn_or_const(INTEGER, ¶m_count); current->result = result; } -void emit_return(TNodeOrConst* value) { +void emit_return(TNodeOrConst *value) { emit_helper(); current->opcode = E_RETURN; current->operand1 = value; } -void emit_reserve(TableNode* result, TNodeOrConst* size) { +void emit_reserve(TableNode *result, TNodeOrConst *size) { + // this needs to change + // we need to take a int + /* + emit_binary_op(E_MUL, result, + */ emit_parameter(size); emit_function_call(result, 1, tn_or_const(NODE, look_up(cur, "reserve"))); } -void emit_release(TableNode* pointer) { +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) { +void emit_deref_right(TableNode *x, TNodeOrConst *y) { emit_helper(); + current->opcode = E_DEREF_RIGHT; + current->result = x; + current->operand1 = y; } -void emit_array_access(Op op, TableNode* result, TNodeOrConst* array, TNodeOrConst* index) { +void emit_deref_left(TableNode *x, TNodeOrConst *y) { emit_helper(); - current->opcode; + current->opcode = E_DEREF_LEFT; + current->result = x; + current->operand1 = y; +} + +void emit_address_of(TableNode *x, TNodeOrConst *y) { + emit_helper(); + current->opcode = E_ADDRESS_OF; + current->result = x; + current->operand1 = y; +} + +void emit_field_access(TableNode *result, TNodeOrConst *record, int offset){ + emit_helper(); + current->opcode = E_DEREF_RIGHT; + current->result = result; + current->operand1 = record; + current->operand2 = tn_or_const(INTEGER, &offset); +} + +void emit_array_access(Op op, TableNode *result, TNodeOrConst *array, TNodeOrConst *index) { + emit_helper(); + current->opcode = op; 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) { +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(); + {[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 + */ /* We need a label ERROR to jump to - */ + emit_conditional_jump(E_LESS_THAN, ); + emit_conditional_jump(E_LESS_THAN, ); + emit_jump(); + */ } -/*// * 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(){ +// * Implement temp variable generator function that produces unique names (t1, t2, etc.) + +int label_gen() { label_count++; return label_count; } -TableNode* getTN(TNodeOrConst* tnc) { +void emit_as_file(FILE *out_file, Instruction *i) { + if (out_file == NULL) { + fprintf(stderr, "Error: output file is NULL\n"); + return; + } + + if (i == NULL) { + return; + } + switch (i->opcode) { + case E_FUNC_DEC: + fprintf(out_file, + "%4.d: func_dec : %s\n", + i->index, + getName(i->result)); + + break; + case E_FUNC_START: + fprintf(out_file, + "%4.d: func : %s\n", + i->index, + getName(i->result)); + break; + case E_LABEL: + fprintf(out_file, + "%4.d: Label : %d\n", + i->index, + i->label); + break; + 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: + fprintf(out_file, + "%4.d: GOTO : %d\n", + i->index, + i->label); + break; + case E_IF_X_TRUE: + fprintf(out_file, + "%4.d: if %s True 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: + // this feels wrong I need to TODO: this + 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_EQUAL_TO: + // this feels wrong I need to TODO: this + 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_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: + fprintf(out_file, + "%4.d: return : %s\n", + i->index, + get_string(i->operand1)); + break; + case E_INDEX_COPY_RIGHT: + 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_INDEX_COPY_LEFT: + fprintf(out_file, + "%4.d: %s[ %s ] = %s\n", + i->index, + getName(i->result), + get_string(i->operand2), + get_string(i->operand1)); + break; + case E_ADDRESS_OF: + fprintf(out_file, + "%4.d: %s = &%s\n", + i->index, + getName(i->result), + get_string(i->operand1)); + break; + case E_DEREF_RIGHT: + fprintf(out_file, + "%4.d: %s = *((char * )%s + %s)\n", + i->index, + getName(i->result), + get_string(i->operand1), + get_string(i->operand2) + ); + break; + case E_DEREF_LEFT: + fprintf(out_file, + "%4.d: *%s = %s\n", + i->index, + getName(i->result), + get_string(i->operand1)); + break; + } + + emit_as_file(out_file, i->next); +} + +TableNode *getTN(TNodeOrConst *tnc) { if (tnc->d == NODE) { return tnc->tnc_union->node; } return NULL; } -int getConst(TNodeOrConst* tnc) { +int getConst(TNodeOrConst *tnc) { if (tnc->d == INTEGER) { return tnc->tnc_union->integer; + } else if (tnc->d == CHARACTER) { + return tnc->tnc_union->character; + } else if (tnc->d == BOOLEAN) { + return tnc->tnc_union->Boolean; + } else if (tnc->d == ADDRESS) { + return 0; } return -1; } \ No newline at end of file diff --git a/src/intermediate_code.h b/src/intermediate_code.h index c1efb76..67c6346 100644 --- a/src/intermediate_code.h +++ b/src/intermediate_code.h @@ -12,9 +12,39 @@ #include "symbol_table.h" +typedef struct Stack Stack; +typedef struct __Node __Node; + +typedef struct __Node { + void *v; + __Node *next; +} __Node; + +typedef struct Stack { + __Node *n; + int w; + int size; +} Stack; +Stack *S_Init(); +void S_Free(Stack *s); +void S_Push(Stack *s, void *v, int i); +void *S_Pop(Stack *s); +void *S_Peek(Stack *s); +bool S_IsEmpty(Stack *s); +int S_Size(Stack *s); +void S_Merge(Stack *list); +//______________________________________________________________________________________________ + +typedef union TNConstUnion TNConstUnion; +typedef struct Instruction Instruction; +typedef struct TNodeOrConst TNodeOrConst; + // these are from page 364 -typedef enum { - E_LABEL = 10000, // this is not in the book + +typedef enum { // these are from page 364 + E_LABEL = 10000, // this is not in the book + E_FUNC_START, + E_FUNC_DEC, E_ADD, // 1 from the list E_SUB, // 1 E_MUL, // 1 @@ -50,75 +80,91 @@ typedef enum { BOOLEAN // bool } Discriminant; -typedef union { - TableNode* node; +typedef union TNConstUnion { + TableNode *node; int integer; - char* string; + char *string; char character; - void* address; + void *address; bool Boolean; } TNConstUnion; -typedef struct { +typedef struct TNodeOrConst { Discriminant d; - TNConstUnion* tnc_union; + TNConstUnion *tnc_union; } TNodeOrConst; -typedef struct Instruction Instruction; typedef struct Instruction { Op opcode; - TableNode* result; - TNodeOrConst* operand1; - TNodeOrConst* operand2; + TableNode *result; + TNodeOrConst *operand1; + TNodeOrConst *operand2; int label; int index; - Instruction* prev; - Instruction* next; + Instruction *prev; + Instruction *next; } Instruction; +// NOTE We are not using this We are using the Stack api typedef struct TFList { - Instruction* i; - TFList* next; + 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); +// TFList * make_list(Instruction * i); +// - makelist(i) function to create instruction lists +// void merge(TFList * l1, TFList * l2); +// - merge(p1,p2) function to concatenate lists +// void backpatch(TFList * l, int label); +// - backpatch(p,i) function to fill in jump targets +// void bp_temp(int n); + +extern Instruction *begin; +extern Instruction *current; +extern int label_count; +extern bool code_gen; +extern FILE *ir_flag; + +TNodeOrConst *tn_or_const(Discriminant, 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); +void emit_as_file(FILE *out_file, Instruction *instr_arr); 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); + +void emit_function_start(TableNode *name); +void emit_parameter(TNodeOrConst *param); +void emit_function_call(TableNode *result, int param_count, TNodeOrConst *name); +void emit_function_dec(TableNode * name); +void emit_return(TNodeOrConst *value); +void emit_reserve(TableNode *result, TNodeOrConst *size); +void emit_release(TableNode *pointer); +void emit_field_access(TableNode *result, TNodeOrConst *record, int offset); +void emit_array_access(Op op, TableNode *result, TNodeOrConst *array, TNodeOrConst *index); +void emit_bounds_check(TNodeOrConst *index, TNodeOrConst *arr); +void emit_goto(int i); +void emit_detach(); +void emit_push_all(Stack *s); + +int getLabel(Instruction *i); +TableNode *getTN(TNodeOrConst *tnc); +int getConst(TNodeOrConst *tnc); + +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); int label_gen(); -TableNode* getTN(TNodeOrConst* tnc); -int getConst(TNodeOrConst* tnc); - -extern int label_count; -extern Instruction* begin; -extern Instruction* current; - +void backpatch(Stack *s, int l); +void emit_backpatch(Stack *s, int l); extern int offset; extern int currentsp; -extern CGNode* cgList; \ No newline at end of file +extern CGNode *cgList; diff --git a/src/lexicalStructure.h b/src/lexicalStructure.h index bdd0db7..d9f23d8 100644 --- a/src/lexicalStructure.h +++ b/src/lexicalStructure.h @@ -25,10 +25,11 @@ int line_number = 1; int column_number = 1; int yycolumn = 1; -#define YY_USER_ACTION { \ +#define YY_USER_ACTION \ + { \ yylloc.first_line = yylineno; \ yylloc.last_line = yylineno; \ yylloc.first_column = yycolumn; \ yylloc.last_column = yycolumn + yyleng - 1; \ yycolumn += yyleng; \ -} + } diff --git a/src/lexicalStructure.lex b/src/lexicalStructure.lex index cd1b56e..a8f4474 100644 --- a/src/lexicalStructure.lex +++ b/src/lexicalStructure.lex @@ -19,6 +19,8 @@ SCHAR \\n|\\t|\\\"|[^\"\n\\] %% +"#include" { if(tok_flag != NULL) {print_tok(INCLUDE);} incr(line_number,column_number,INCLUDE); return INCLUDE; } + "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; } @@ -56,10 +58,27 @@ SCHAR \\n|\\t|\\\"|[^\"\n\\] "->" { if(tok_flag != NULL) {print_tok(ARROW);} incr(line_number,column_number,ARROW); return ARROW; } {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;} + + +'{CHAR}' { + if (tok_flag) print_tok(C_CHARACTER); + incr(line_number, column_number, C_CHARACTER); + + int value; + if (strcmp(yytext, "'\\n'") == 0) value = 0x0A; + else if (strcmp(yytext, "'\\t'") == 0) value = 0x09; + else if (strcmp(yytext, "'\\''") == 0) value = 0x27; + else if (strcmp(yytext, "'\\\\'") == 0) value = 0x5C; + else value = yytext[1]; + + yylval.letter = value; + 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;*/} - +_{DIGIT}+ {if(tok_flag != NULL){print_tok(ACCESS);}incr(line_number,column_number,ACCESS);yylval.integ = atoi(&yytext[1])/*words = strdup("integer")*/;return ACCESS;} "(" { 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; } @@ -78,4 +97,4 @@ SCHAR \\n|\\t|\\\"|[^\"\n\\] " " { incr(line_number,column_number,0); } . { incr(line_number,column_number,0); } -%% +%% \ No newline at end of file diff --git a/src/runner.c b/src/runner.c index a74c424..4aa6a84 100644 --- a/src/runner.c +++ b/src/runner.c @@ -126,6 +126,9 @@ int run(FILE *alpha) { fseek(alpha, 0, SEEK_SET); yyin = alpha; + stack = S_Init(); + TrueList = S_Init(); + FalseList = S_Init(); yyparse(); if (tok_flag != NULL) { @@ -153,13 +156,22 @@ int run(FILE *alpha) { if (ir_flag != NULL) { printdebug("[-ir] Intermediate code is enabled."); - emit_as_file(ir_flag, begin); + if (!contains_errors) { + emit_as_file(ir_flag, begin); + } else { + remove(ir_name); + } fclose(ir_flag); } if (cg_flag != NULL) { printdebug("[-cg] Code generation is enabled."); - generate(); + + if (!contains_errors) { + generate(); + } else { + remove(cg_name); + } fclose(cg_flag); } @@ -191,7 +203,7 @@ int new_file(char *arg, char *alpha) { mkdir("./out", 0777); - char *new_basename = calloc(strlen(basename) + 5, sizeof(char)); + char *new_basename = calloc(strlen(basename) + 7, sizeof(char)); strcpy(new_basename, "./out/"); strcat(new_basename, basename); basename = new_basename; @@ -232,8 +244,12 @@ int new_file(char *arg, char *alpha) { } else if (strcmp(arg, "-asc") == 0) { asc_flag = fopen(file_name, "w"); } else if (strcmp(arg, "-ir") == 0) { + ir_name = malloc(strlen(file_name) + 1); + strcpy(ir_name, file_name); ir_flag = fopen(file_name, "w"); } else if (strcmp(arg, "-cg") == 0) { + cg_name = malloc(strlen(file_name) + 1); + strcpy(cg_name, file_name); cg_flag = fopen(file_name, "w"); } return 0; @@ -247,7 +263,7 @@ int is_alpha_file(char *alpha, int file_len) { return 0; // is alpha file } -void insert_code_line(char * error_message, int line_number) { +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); @@ -259,11 +275,14 @@ void insert_code_line(char * error_message, int line_number) { 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; + if (current->is_error == false) { + CodeLine *next_code_line = current->next; + current->next = error_line; + error_line->next = next_code_line; + } } current = current->next; } @@ -331,4 +350,4 @@ char *file_read_line(FILE *fp) { str[len] = '\0'; return str; -} \ No newline at end of file +} diff --git a/src/runner.h b/src/runner.h index 9971eed..09a836a 100644 --- a/src/runner.h +++ b/src/runner.h @@ -56,8 +56,14 @@ FILE *ir_flag = NULL; FILE *cg_flag = NULL; bool tc_flag = false; bool DEBUG = false; +bool entry_flag = false; +//1 is for default, 2 is in array context, 3 is in record context +int context = 1; int no_flag = 0; int arg; +bool contains_errors = false; +char *cg_name; +char *ir_name; TableNode *funprime; TableNode *arrayprim; @@ -70,6 +76,9 @@ TableNode *recprime; TableNode *funtypeprime; TableNode *undefined; extern Instruction *begin; +extern Stack *stack; +extern Stack *TrueList; +extern Stack *FalseList; int main(int argc, char *argv[]); int check_flag(char *arg, char *alpha); @@ -106,6 +115,6 @@ typedef struct CodeLine { CodeLine *code_head; char *file_read_line(FILE *fp); -void insert_code_line(char * error_message, int line_number); +void insert_code_line(char *error_message, int line_number); void append_code_line(CodeLine *code_line); -void print_code_lines(); \ No newline at end of file +void print_code_lines(); diff --git a/src/symbol_table.c b/src/symbol_table.c index 2fc926c..a1f457f 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -4,7 +4,12 @@ #include "symbol_table.h" Constant_Stack *head = NULL; +Context_stack *context_head = NULL; +//TableNode* comparator = NULL; +Function_Stack *function_head = NULL; + int temp2_count = 0; +int temp3_count = 0; void printdebug_impl(char *file, int line, const char *format, ...) { if (DEBUG) { @@ -24,6 +29,12 @@ char *temp_var_gen() { temp2_count++; return ret; } +char *arg_var_gen() { + char *ret = calloc(9, sizeof(*ret)); + sprintf(ret, "&%d", temp3_count); + temp3_count++; + return ret; +} Constant_Stack *Push(TableNode *type, void *value, bool isConst) { if (type == NULL || type == undefined) { @@ -46,6 +57,234 @@ Constant_Stack *Push(TableNode *type, void *value, bool isConst) { return cs; } +Context_stack *PushContext(/*int context, */TableNode *typeToCompare) { + /*if (context != 1 && context != 2 && context != 3 && context != 0) { + printdebug( + "invalid context passed in"); + return NULL; + }*/ + if(typeToCompare == NULL) { + printdebug( + "passed a NULL reference to PushContext. Invalid."); + return NULL; + } + Context_stack *cs = (Context_stack *)calloc(1,sizeof(Context_stack)); + //cs->con = context; + cs->typeToCompare = typeToCompare; + if (context_head == NULL) { + context_head = cs; + cs->next = NULL; + } else { + cs->next = context_head; + context_head = cs; + } + return cs; +} + +Function_Stack *PushFunction(int arg, TableNode* FunctionType) { + if (FunctionType == NULL) { + printdebug( + "passed a NULL reference to PushFunction. Invalid."); + return NULL; + } + if(FunctionType == undefined) { + printdebug( + "passed an undefined reference to PushFunction. Invalid."); + return NULL; + } + Function_Stack *fs = (Function_Stack *)calloc(1,sizeof(Function_Stack)); + fs->arg = arg; + fs->FunctionType = FunctionType; + if (function_head == NULL) { + function_head = fs; + fs->next = NULL; + } else { + fs->next = function_head; + function_head = fs; + } + return fs; +} + +Function_Stack *PopFunction() { + if (function_head == NULL) { + printf("cannot pop from an empty stack from popfunction. Invalid.\n"); + return NULL; + } + Function_Stack *fs = function_head; + function_head = function_head->next; + return fs; +} + +int getArgumentNumber(Function_Stack *fs) { + if (fs == NULL) { + printdebug( + "passed a NULL reference to getArgumentNumber. Invalid."); + return -1; + } + return fs->arg; +} + +int getTotalNumberArguments(TableNode* function) { + if (function == NULL) { + printdebug( + "passed a NULL reference to getTotalNumberArguments. Invalid."); + return -1; + } + if (getAdInfoType(function) != TYPE_FUNCTION_DECLARATION) { + printdebug( + "passed an invalid reference to getTotalNumberArguments. Invalid."); + return -1; + } + TableNode* functionType = getParameter(getTypeEntry(function)); + if(functionType != undefined){ + return -1; + } + if(getAdInfoType(functionType) != TYPE_RECORD_TYPE){ + return 1; + }else{ + return getRecLength(functionType); + } +} + +Function_Stack* setArgumentNumber(Function_Stack *fs, int arg) { + if (fs == NULL) { + printdebug( + "passed a NULL reference to setArgumentNumber. Invalid."); + return NULL; + } + + if(argFunctionType)){ + //case where invalid argument number is being passed + return NULL; + } + fs->arg = arg; + return fs; +} +Function_Stack* setFunctionType(Function_Stack *fs, TableNode* functionType) { + if (fs == NULL) { + printdebug( + "passed a NULL reference to setFunctionType. Invalid."); + return NULL; + } + if (functionType == NULL) { + printdebug( + "passed a NULL reference to setFunctionType. Invalid."); + return NULL; + } + fs->FunctionType = functionType; + return fs; +} +TableNode* getFunctionType(Function_Stack *fs) { + if (fs == NULL) { + printdebug( + "passed a NULL reference to getFunctionType. Invalid."); + return undefined; + } + TableNode* tn = fs->FunctionType; + return tn; +} + +Function_Stack* incrementArgumentNumber(Function_Stack *fs) { + if (fs == NULL) { + printdebug( + "passed a NULL reference to incrementArgumentNumber. Invalid."); + return NULL; + } + int cur=getArgumentNumber(fs); + setArgumentNumber(fs, cur+1); + //setFunctionType(fs, getFunctionNumberType(getFunctionType(fs), cur+1)); + return fs; +} + +TableNode* getRecordNumberType(TableNode* record, int arg){ + if(record == NULL){ + //case where NULL is being passed in + return undefined; + } + if(getAdInfoType(record) != TYPE_RECORD_TYPE){ + //case where invalid argument number is being passed + return undefined; + } + if(argFunctionType; + return tn; +} + +Context_stack *PopContext() { + if (context_head == NULL) { + printf("cannot pop from an empty stack from popcontext. Invalid.\n"); + return NULL; + } + Context_stack *cs = context_head; + context_head = context_head->next; + //printf("Popped context off stack: number %d\n", cs->con); + return cs; +} +/* +int getContextType(Context_stack *cs) { + if (cs == NULL) { + printdebug( + "passed a NULL reference to getContextType. Invalid."); + return -1; + } + return cs->con; +} +*/ +TableNode *getContextTypeEntry(Context_stack *cs) { + if (cs == NULL) { + printdebug( + "passed a NULL reference to getContextTypeEntry. Invalid."); + return undefined; + } + TableNode* tn = cs->typeToCompare; + return tn; +} Constant_Stack *Pop() { if (head == NULL) { printf("cannot pop from an empty stack. Invalid.\n"); @@ -68,10 +307,10 @@ Constant_Stack *Print_Stack() { printf("Type: %s, Value: NULL", getName(cs->theType)); } if (cs->theType == stri) { - printf("Type: %s, Value: %s\n", getName(cs->theType), *(char *)(cs->theValue)); + printf("Type: %s, Value: %c\n", getName(cs->theType), *(char *)(cs->theValue)); } if (cs->theType == integ) { - printf("Type: %s, Value: %d\n", getName(cs->theType), (int *)(cs->theValue)); + printf("Type: %s, Value: %d\n", getName(cs->theType), *(int *)(cs->theValue)); } if (cs->theType == chara) { printf("Type: %s, Value: %c\n", getName(cs->theType), *(char *)cs->theValue); @@ -109,6 +348,18 @@ int getPrimSize(TableNode *definition) { "Invalid."); return -1; } + if (getAdInfoType(definition) == TYPE_ARRAY_TYPE) { + //special case to return size for reference to an array + return 8; + } + if (getAdInfoType(definition) == TYPE_FUNCTION_TYPE) { + //special case to return size for reference to a function + return 8; + } + if (getAdInfoType(definition) == TYPE_RECORD_TYPE) { + //special case to return size for reference to a record + return getRecTotal(definition); + } if (definition->additionalinfo == NULL) { printdebug("node has NULL additionalinfo. Invalid."); return -1; @@ -389,7 +640,7 @@ int getRecLength(TableNode *definition) { } return definition->additionalinfo->RecAdInfo->numofelements; } -// This gets the array. Needs to up be updated to get the scope instead + SymbolTable *getRecList(TableNode *definition) { if (definition == NULL) { printdebug( @@ -443,18 +694,89 @@ int getRecSize(SymbolTable *tn) { } return -1; } +int getRecPosition(TableNode *rec, char *id) { + if (rec == NULL) { + printdebug( + "passed a NULL entry to getRecPosition. Invalid."); + return -1; + } + if (rec == undefined) { + printdebug( + "passed an undefined entry to getRecPosition. Invalid."); + return -1; + } + if (getAdInfoType(rec) != TYPE_RECORD_TYPE) { + printdebug( + "not checking the position of a record -- invalid op"); + return -1; + } + TableNode *cur = getFirstEntry(getRecList(rec)); + int i = 1; + while (cur != NULL) { + if (strcmp(getName(cur), id) == 0) { + return i; + } + cur = getNextEntry(cur); + i++; + } + if (cur == NULL) { + printdebug( + "passed an invalid entry to getRecPosition. Invalid."); + return -1; + } else { + return i; + } +} + +int getElementOffset(TableNode *rec, char *id) { + if (rec == NULL) { + printdebug( + "passed a NULL entry to getElementOffset. Invalid."); + return -1; + } + if (rec == undefined) { + printdebug( + "passed an undefined entry to getElementOffset. Invalid."); + return -1; + } + if (getAdInfoType(rec) != TYPE_RECORD_TYPE) { + printdebug( + "not checking the offset of a record -- invalid op"); + return -1; + } + int *offsets = getRecOffsets(rec); + int position = getRecPosition(rec, id); + if (position == -1) { + printdebug( + "passed an invalid entry to getElementOffset. Invalid."); + return -1; + } + position = position - 1; + int total_offset = 0; + int current_position = 1; + while (current_position < position + 1) { + //adding current element in struct + total_offset += offsets[2 * current_position]; + //adding padding between elements + total_offset += offsets[2 * current_position + 1]; + current_position++; + } + //returning the offset of the start of the element + return total_offset; +} // below function takes a bool to see if parameter should be decomposed or not ; // note that functions only take one input and have one output // using "as" the input record can be decomposed to give the illusion of // multiple inputs Below function also has the line number where the function is // first defined -AdInfo *CreateFunctionDeclarationInfo(int line, bool asorregular) { - AdInfo *info = (AdInfo *)malloc(sizeof(AdInfo)); +AdInfo *CreateFunctionDeclarationInfo(int line, bool asorregular, SymbolTable *scope) { + AdInfo *info = (AdInfo *)calloc(1, sizeof(AdInfo)); info->FunDecAdInfo = (function_declaration_info *)malloc( sizeof(function_declaration_info)); info->FunDecAdInfo->startlinenumber = line; info->FunDecAdInfo->regularoras = asorregular; + info->FunDecAdInfo->scope = scope; return info; } // gets the line at which the function was first defined. (Can be used to print @@ -523,6 +845,68 @@ bool getAsKeyword(TableNode *definition) { return definition->additionalinfo->FunDecAdInfo->regularoras; } +SymbolTable *getFunScope(TableNode *definition) { + if (definition == NULL) { + printdebug( + "passed a NULL entry to getScope " + "function. Invalid."); + return NULL; + } + if (getAdInfoType(definition) != TYPE_FUNCTION_DECLARATION) { + printdebug( + "passed in invalid entry type to getScope " + "function. Invalid."); + return NULL; + } + if (definition->additionalinfo == NULL) { + printdebug( + "node has NULL additionalinfo. Invalid."); + return NULL; + } + if (definition->additionalinfo->FunDecAdInfo == NULL) { + printdebug( + "node has NULL additionalinfo. Invalid."); + return NULL; + } + if (definition->additionalinfo->FunDecAdInfo->scope == NULL) { + printdebug( + "node has no scope initialized."); + return NULL; + } + + return definition->additionalinfo->FunDecAdInfo->scope; +} +TableNode *setFunScope(TableNode *tn, SymbolTable *scope) { + if (tn == NULL) { + printdebug( + "passing in a NULL entry to setFunScope. " + "invalid"); + return undefined; + } + if (getAdInfoType(tn) != TYPE_FUNCTION_DECLARATION) { + printdebug( + "passing in an invalid entry to setFunScope. " + "invalid"); + return undefined; + } + if (tn->additionalinfo == NULL) { + printdebug( + "node has NULL additionalinfo. Invalid."); + return undefined; + } + if (tn->additionalinfo->FunDecAdInfo == NULL) { + printdebug( + "node has NULL additionalinfo. Invalid."); + return undefined; + } + if (scope == NULL) { + printdebug( + "passed in an empty scope."); + return undefined; + } + tn->additionalinfo->FunDecAdInfo->scope = scope; + return tn; +} TableNode *setAsKeyword(TableNode *tn, bool as) { if (tn == NULL) { printdebug( @@ -623,6 +1007,7 @@ TableNode *getReturn(TableNode *definition) { "node has NULL additionalinfo. Invalid."); return undefined; } + printdebug("function:%s with return type %s\n", getName(definition), getName(definition->additionalinfo->FunTypeAdInfo->returntype)); return definition->additionalinfo->FunTypeAdInfo->returntype; } @@ -671,31 +1056,31 @@ SymbolTable *init(SymbolTable *start) { chara = (TableNode *)calloc(1, sizeof(TableNode)); stri = (TableNode *)calloc(1, sizeof(TableNode)); boo = (TableNode *)calloc(1, sizeof(TableNode)); - TableNode *reservetype = (TableNode *)calloc(1, sizeof(TableNode)); - TableNode *reserve = (TableNode *)calloc(1, sizeof(TableNode)); - TableNode *releasetype = (TableNode *)calloc(1, sizeof(TableNode)); - TableNode *release = (TableNode *)calloc(1, sizeof(TableNode)); + //TableNode *reservetype = (TableNode *)calloc(1, sizeof(TableNode)); + //TableNode *reserve = (TableNode *)calloc(1, sizeof(TableNode)); + //TableNode *releasetype = (TableNode *)calloc(1, sizeof(TableNode)); + //TableNode *release = (TableNode *)calloc(1, sizeof(TableNode)); // TableNode* arr = (TableNode*)malloc(sizeof(SymbolTable)); start->entries = integ; integ->next = addr; addr->next = chara; chara->next = stri; stri->next = boo; - boo->next = reservetype; - reservetype->next = reserve; - reserve->next = releasetype; - releasetype->next = release; - release->next = NULL; + boo->next = NULL;//reservetype; + //reservetype->next = reserve; + //reserve->next = releasetype; + //releasetype->next = release; + //release->next = NULL; integ->theName = "integer"; addr->theName = "address"; chara->theName = "character"; boo->theName = "Boolean"; stri->theName = "string"; - reserve->theName = "reserve"; - reservetype->theName = "reserve type"; - releasetype->theName = "release type"; - release->theName = "release"; + //reserve->theName = "reserve"; + //reservetype->theName = "reserve type"; + //releasetype->theName = "release type"; + //release->theName = "release"; // arr->theName= "array" // root TableNode that all are pointing to but not in table @@ -762,10 +1147,10 @@ SymbolTable *init(SymbolTable *start) { chara->theType = prime; stri->theType = arrayprim; boo->theType = prime; - reserve->theType = reservetype; - reservetype->theType = funtypeprime; - releasetype->theType = funtypeprime; - release->theType = releasetype; + //reserve->theType = reservetype; + //reservetype->theType = funtypeprime; + //releasetype->theType = funtypeprime; + //release->theType = releasetype; // arr->theType=arrayprim; @@ -779,20 +1164,20 @@ SymbolTable *init(SymbolTable *start) { chara->additionalinfo = CreatePrimitiveInfo(SIZE_CHAR); stri->additionalinfo = CreateArrayInfo(1, chara); boo->additionalinfo = CreatePrimitiveInfo(SIZE_BOOL); - reserve->additionalinfo = CreateFunctionDeclarationInfo(0, false); - reservetype->additionalinfo = CreateFunctionTypeInfo(integ, addr); - releasetype->additionalinfo = CreateFunctionTypeInfo(addr, integ); - release->additionalinfo = CreateFunctionDeclarationInfo(0, false); + //reserve->additionalinfo = CreateFunctionDeclarationInfo(0, false, NULL); + //reservetype->additionalinfo = CreateFunctionTypeInfo(integ, addr); + //releasetype->additionalinfo = CreateFunctionTypeInfo(addr, integ); + //release->additionalinfo = CreateFunctionDeclarationInfo(0, false, NULL); integ->tag = TYPE_PRIMITIVE_TYPE; // explicitly set the type for integ addr->tag = TYPE_PRIMITIVE_TYPE; // explicitly set the type for addr chara->tag = TYPE_PRIMITIVE_TYPE; // explicitly set the type for chara stri->tag = TYPE_ARRAY_TYPE; // explicitly set the type for stri boo->tag = TYPE_PRIMITIVE_TYPE; // explicitly set the type for boo - reserve->tag = TYPE_FUNCTION_DECLARATION; - reservetype->tag = TYPE_FUNCTION_TYPE; - releasetype->tag = TYPE_FUNCTION_TYPE; - release->tag = TYPE_FUNCTION_DECLARATION; + //reserve->tag = TYPE_FUNCTION_DECLARATION; + //reservetype->tag = TYPE_FUNCTION_TYPE; + //releasetype->tag = TYPE_FUNCTION_TYPE; + //release->tag = TYPE_FUNCTION_DECLARATION; // addr->additionalinfo = CreatePrimitiveInfo(8); start->Line_Number = 1; @@ -948,6 +1333,11 @@ TableNode *CreateEntry(SymbolTable *table, int tag, TableNode *typeOf, char *id, return NULL; } */ + if ((id != NULL) && table_lookup(cur, id) != undefined) { + printdebug("This name is already defined in the current scope"); + //throw_error(ERROR_TYPE, "Already defined."); + return undefined; + } if (typeOf == NULL) { printdebug("Passing an NULL Type Node to Create Entry"); return undefined; @@ -975,8 +1365,13 @@ TableNode *CreateEntry(SymbolTable *table, int tag, TableNode *typeOf, char *id, return newEntry; } else { TableNode *oldEntry = table->entries; - table->entries = newEntry; - newEntry->next = oldEntry; + while (oldEntry->next != NULL) { + oldEntry = oldEntry->next; + } + oldEntry->next = newEntry; + newEntry->next = NULL; + //table->entries = newEntry; + //newEntry->next = oldEntry; printdebug("[CreateEntry] Adding %s to the symbol table", id); return newEntry; } @@ -1119,6 +1514,14 @@ TableNode *table_lookup(SymbolTable *table, char *x) { } TableNode *entrie = table->entries; for (; entrie != NULL; entrie = entrie->next) { + if (entrie->theName == NULL) { + printdebug("name of entry is currently NULL, undefined"); + return undefined; + } + if (entrie->theName == undefined->theName) { + printdebug("name of entry is currently undefined"); + return undefined; + } if (!strcmp(entrie->theName, x)) { return entrie; } @@ -1208,6 +1611,9 @@ void print_symbol_table(SymbolTable *table, FILE *file_ptr) { } for (; entry != NULL; entry = getNextEntry(entry)) { + if ((getName(entry)[0] == '$' || getName(entry)[0] == '&') && ir_flag == NULL) { + continue; + } if (getAdInfoType(entry) == TYPE_ARRAY_TYPE) { char *arrayType = (char *)malloc(100); sprintf(arrayType, " %d -> %s", getNumArrDim(entry), @@ -1286,11 +1692,17 @@ void print_symbol_table(SymbolTable *table, FILE *file_ptr) { if (getAdInfoType(entry) == TYPE_FUNCTION_DECLARATION) { char *functiontype = (char *)malloc(100); - sprintf(functiontype, " %s", getName(getReturn(entry))); - if (parentScopeNum == 0) { - st_fprint(file_ptr, getName(entry), currentScopeNum, -100, functiontype, " Function Definition"); + sprintf(functiontype, " %s", getName(getTypeEntry(entry))); + char *functionScope = (char *)malloc(100); + if (getLine(getFunScope(entry)) < 1) { + sprintf(functionScope, " Function not defined before runtime"); } else { - st_fprint(file_ptr, getName(entry), currentScopeNum, parentScopeNum, functiontype, " Function Definition"); + sprintf(functionScope, " Function Definition that starts at line %d", getLine(getFunScope(entry))); + } + if (parentScopeNum == 0) { + st_fprint(file_ptr, getName(entry), currentScopeNum, -100, functiontype, functionScope); + } else { + st_fprint(file_ptr, getName(entry), currentScopeNum, parentScopeNum, functiontype, functionScope); } } @@ -1309,7 +1721,7 @@ void print_symbol_table(SymbolTable *table, FILE *file_ptr) { if ((getFirstChild(node)) == NULL) { print_symbol_table(getFirstChild(node), file_ptr); } else { - if (getLine(getFirstChild(node)) == -1) { + if (getLine(getFirstChild(node)) < -3) { continue; } else { print_symbol_table(getFirstChild(node), file_ptr); @@ -1435,7 +1847,13 @@ SymbolTable *getParent(SymbolTable *st) { ListOfTable *getChildren(SymbolTable *st) { return st->Children_Scope; } SymbolTable *getFirstChild(ListOfTable *lt) { return lt->table; } ListOfTable *getRestOfChildren(ListOfTable *lt) { return lt->next; } -TableNode *getFirstEntry(SymbolTable *st) { return st->entries; } +TableNode *getFirstEntry(SymbolTable *st) { + if (st == NULL || st->entries == NULL) { + printdebug("passed a NULL symbol table to getFirstEntry"); + return undefined; + } + return st->entries; +} // Segfaults when passed an invalid table node! TableNode *getNextEntry(TableNode *tn) { @@ -1553,3 +1971,28 @@ TableNode *printTableNode(TableNode *tn) { return tn; } + +int getStackSize() { + int i = 0; + TableNode *tn = getFirstEntry(top); + while (tn != NULL) { + i++; + tn = getNextEntry(tn); + } + + ListOfTable *lt = getChildren(top); + while (lt != NULL) { + TableNode *first = lt->table->entries; + while (first != NULL) { + i++; + first = getNextEntry(first); + } + + lt = lt->next; + } + + i= i * 8; + if (i % 16 != 0) i += 8; + + return i; +} diff --git a/src/symbol_table.h b/src/symbol_table.h index 391f05a..35d6b81 100644 --- a/src/symbol_table.h +++ b/src/symbol_table.h @@ -15,9 +15,14 @@ #define SIZE_CHAR 1 #define SIZE_BOOL 1 -struct TableNode; +extern FILE *ir_flag; + +typedef struct TableNode TableNode; typedef struct TFList TFList; typedef struct CGNode CGNode; +typedef struct SymbolTable SymbolTable; +typedef struct Function_Stack Function_Stack; +typedef struct Context_stack Context_stack; typedef struct Constant_Stack { struct TableNode *theType; @@ -25,6 +30,32 @@ typedef struct Constant_Stack { struct Constant_Stack *next; bool isConst; } Constant_Stack; +//explanation about context stack +//If we have an array context, it means that we are expecting an array, either on the left side of assignable or as the (one of the) arguments that needs to be passed in for a function +//with the array context, either we are initializing the array OR we are reserving space for an element of the array. Can only reserve a record or an array so that element must be a record or an array. +//if we have a record context, that means we are expecting a record on the left side of the assignable assignment or we are expecting a record passed as an argument for a function call. +//we push and pop these contexts as needed. +//we can also push the table node of the thing that we are trying to look at. If it is supposed to be an array, for example, we can push that array onto the stack +//if it is a record, we can push that record onto the stack so that we can approperiately type check +//0 - no expecting array or record +//1 - expecting an array +//2 - expecting a record +//we also have a function call stack to look at what function call we are inside (what parameters it is expecting) +//This is distinct from the context stack. We don't necessarily add to the function call stack. After every valid argument, we simply add one to what argument we are seeing +//This lets us update the context stack as needed with the next tablenode type that we are comparing against +//we can also simply add to the function call stack if we have functions inside functions and then update as needed + +typedef struct Context_stack { + //int con; + TableNode *typeToCompare; + struct Context_stack *next; +} Context_stack; + +typedef struct Function_Stack{ + int arg; + TableNode *FunctionType; + struct Function_Stack *next; +} Function_Stack; typedef struct { int size; @@ -45,6 +76,7 @@ typedef struct { typedef struct { int startlinenumber; bool regularoras; + SymbolTable *scope; } function_declaration_info; typedef struct { @@ -101,14 +133,29 @@ void printdebug_impl(char *file, int line, const char *format, ...); printdebug_impl(__FILE__, __LINE__, format, ##__VA_ARGS__) char *temp_var_gen(); +char *arg_var_gen(); +int getTotalNumberArguments(TableNode* function); +Function_Stack* incrementArgumentNumber(Function_Stack *fs); +Function_Stack* setArgumentNumber(Function_Stack *fs, int arg); Constant_Stack *Push(TableNode *type, void *value, bool isConst); +Context_stack *PushContext(/*int context,*/TableNode *typeToCompare); +Function_Stack *PushFunction(int arg, TableNode* FunctionType); Constant_Stack *Pop(); +Context_stack *PopContext(); +Function_Stack* setFunctionType(Function_Stack *fs, TableNode* functionType); +Function_Stack *PopFunction(); +TableNode* getFunctionTypeContext(Function_Stack *fs); +TableNode* getFunctionType(Function_Stack *fs); +//int getContextType(Context_stack *cs); Constant_Stack *Print_Stack(); +int getArgumentNumber(Function_Stack *fs); AdInfo *CreatePrimitiveInfo(int size); int getPrimSize(TableNode *definition); AdInfo *CreateArrayInfo(int dim, TableNode *type); int getNumArrDim(TableNode *definition); TableNode *getArrType(TableNode *definition); +TableNode* getRecordNumberType(TableNode* record, int arg); +TableNode* getFunctionNumberType(TableNode* function, int arg); AdInfo *CreateRecordInfo(int length, SymbolTable *recordScope); int getRecTotal(TableNode *node); TableNode *setRecOffsetInfo(SymbolTable *scope, TableNode *node); @@ -117,7 +164,9 @@ int getRecLength(TableNode *definition); SymbolTable *getRecList(TableNode *definition); TableNode *setRecSize(TableNode *tn, int n); int getRecSize(SymbolTable *tn); -AdInfo *CreateFunctionDeclarationInfo(int line, bool asorregular); +AdInfo *CreateFunctionDeclarationInfo(int line, bool asorregular, SymbolTable *scope); +TableNode *setFunScope(TableNode *tn, SymbolTable *scope); +SymbolTable *getFunScope(TableNode *definition); int getStartLine(TableNode *definition); TableNode *setStartLine(TableNode *tn, int start); bool getAsKeyword(TableNode *definition); @@ -155,16 +204,25 @@ TableNode *getFirstEntry(SymbolTable *st); TableNode *getNextEntry(TableNode *tn); TableNode *printTableNode(TableNode *tn); +TableNode *getContextTypeEntry(Context_stack *cs); + +int getElementOffset(TableNode *rec, char* id); +int getRecPosition(TableNode* rec, char* id); +int getStackSize(); + + extern int yylex(void); extern char *yytext; extern int yyleng; extern int yychar; extern SymbolTable *cur; +extern SymbolTable *top; extern int line_number; extern int column_number; extern FILE *yyin; extern bool DEBUG; extern int temp2_count; +extern int temp3_count; extern TableNode *funprime; extern TableNode *arrayprim; extern TableNode *integ; @@ -176,6 +234,8 @@ extern TableNode *recprime; extern TableNode *funtypeprime; extern TableNode *undefined; extern Constant_Stack *head; +extern Context_stack *context_head; +extern Function_Stack *function_head; extern char *COLOR_RED; extern char *COLOR_GREEN; @@ -191,4 +251,4 @@ extern char *COLOR_YELLOW; extern char *COLOR_LIGHTBLUE; extern char *COLOR_LIGHTPURPLE; extern char *COLOR_LIGHTCYAN; -extern char *COLOR_WHITE; \ No newline at end of file +extern char *COLOR_WHITE; diff --git a/src/typedefs.h b/src/typedefs.h index 5c476bf..15fe996 100644 --- a/src/typedefs.h +++ b/src/typedefs.h @@ -55,3 +55,6 @@ #define RELEASE 614 // comments #define COMMENT 700 +//Additional tokens +#define ACCESS 801 +#define INCLUDE 901 \ No newline at end of file diff --git a/test.sh b/test.sh index 3f6f5a9..ce2d31d 100755 --- a/test.sh +++ b/test.sh @@ -20,147 +20,140 @@ LIGHTCYAN='\033[1;36m' WHITE='\033[1;37m' if [ ! -f "./alpha" ]; then - echo -e "${RED}[ERROR] ${YELLOW}File ./alpha not found!${WHITE}" - exit 1 + echo -e "${RED}[ALERT] ${YELLOW}File ./alpha not found! Generating with 'make'.${WHITE}" + make fi if [ ! -d "./out" ]; then mkdir -p out fi -SWITCH=${YELLOW} -count=0 +if [ $# -eq 0 ]; then + help +fi -switchfunc() { - if [ $count -eq 0 ]; then - count=1 - SWITCH=${YELLOW} - else - count=0 - SWITCH='\033[0;35m' - fi +help() { + echo -e "${WHITE}-----{ ${BLUE}Test.sh Help ${WHITE}}-----\n" + echo -e "${YELLOW} Arguments: ${WHITE}" + echo -e "${GREEN} -exp ${WHITE} Generate expected output files" + echo -e "${GREEN} -diff ${WHITE} Compare output files with expected output files" + echo -e "${GREEN} -help ${WHITE} Show this help message\n" + echo -e "${YELLOW} Usage: ${WHITE}" + echo -e "${GREEN} ./test.sh [flags] ${WHITE} Run the test on a single file" + echo -e "${GREEN} ./test.sh [flags] ${WHITE} Run the test on all files in a directory\n" + echo -e "${YELLOW} Examples: ${WHITE}" + echo -e "${GREEN} ./test.sh test.alpha ${WHITE} Runs test flags in header on test.alpha" + echo -e "${GREEN} ./test.sh test/ ${WHITE} Runs test flags in header on all .alpha files in test/" + echo -e "${GREEN} ./test.sh test/ -exp ${WHITE} Runs test flags in header on all .alpha files in test/ and generates expected output files" + echo -e "${GREEN} ./test.sh test/ -diff ${WHITE} Runs test flags in header on all .alpha files in test/ and compares output files with expected output files" + echo -e "${GREEN} ./test.sh test/ -exp -diff ${WHITE} Runs test flags in header on all .alpha files in test/ and generates expected output files and compares output files with expected output files\n" + echo -e "${YELLOW} Notes: ${WHITE}" + echo -e "${ORANGE} To create a test file, on the first line of the .alpha file, add:" + echo -e "${LIGHTBLUE} (* TEST: [ ] *)" + echo -e "${ORANGE} where are the alpha flags to be used. Ex:" + echo -e "${LIGHTBLUE} (* TEST: [ -debug -asc -tc ] *)\n" + echo -e "${WHITE}-----------------------------------------\n" + exit 1 } -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 "" +run() { + filename=$(basename -- "$1") + first_line=$(head -n 1 "$1") + if [[ "$first_line" == "(* TEST: ["*"] *)"* ]]; then + bracket_content=$(echo "$first_line" | sed -n 's/.*\[\(.*\)\].*/\1/p') + sed -i '1d' "$1" + ./alpha ${bracket_content} "$1" + sed -i "1s/^/$first_line\n/" "$1" - 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 "" + if [ $# -ge 2 ]; then + path=$(dirname "$1") + filename_noext=${filename:0:${#filename}-6} + if [[ "$2" == "-exp" || "$3" == "-exp" ]]; then + for file in out/${filename_noext}.*; do + if [[ "$file" == *".asc" || "$file" == *".s" || "$file" == *".st" || "$file" == *".tok" || "$file" == *".ir" ]]; then + for_filename=$(basename -- "$file") + for_filename="${for_filename}.exp" + if [ -f "${path}/../expected/${for_filename}" ]; then + echo -e "${RED}[ALERT] ${YELLOW}File ${path}/../expected/${for_filename} already exists! Overwriting...${WHITE}" + fi + cp "$file" "${path}/../expected/${for_filename}" + else + echo -e "${RED}[ALERT] ${YELLOW}Unexpected file found: $file ${WHITE}" + fi + done + fi - 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 "" + if [[ "$2" == "-diff" || "$3" == "-diff" ]]; then + for file in out/${filename_noext}.*; do + if [[ "$file" == *".asc" || "$file" == *".s" || "$file" == *".st" || "$file" == *".tok" || "$file" == *".ir" ]]; then + for_filename=$(basename -- "$file") + for_filename="${for_filename}.exp" + if [ -f "${path}/../expected/${for_filename}" ]; then + exp_basename=$(basename -- "$for_filename") + diff -q "${path}/../expected/${for_filename}" "$file" + if [ $? -eq 0 ]; then + echo -e "${GREEN}[SUCCESS] ${YELLOW}Test ${WHITE}$file ${YELLOW}passed ${WHITE}$exp_basename${WHITE}" + else + echo -e "${RED}[ERROR] ${YELLOW}Test ${WHITE}$file ${YELLOW}failed ${WHITE}$exp_basename${WHITE}" + fi + else + echo -e "${RED}[ALERT] ${YELLOW}File ${path}/../expected/${for_filename} not found!${WHITE}" + fi + else + echo -e "${RED}[ALERT] ${YELLOW}Unexpected file found: $file ${WHITE}" + fi + done + fi + fi + else + echo -e "${RED}[ERROR] ${YELLOW}File $1 is not a valid .alpha test file!${WHITE}" + fi +} - 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 : 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 +if [[ "$1" == *"/" ]]; then + if [ $# -ge 2 ]; then + for file in "$1"*; do + if [[ "$file" == *.alpha ]]; then + if [[ "$2" == "-exp" || "$3" == "-exp" || "$2" == "-diff" || "$3" == "-diff" ]]; then + run "$file" "$2" "$3" + else + echo -e "${RED}[ERROR] ${YELLOW}Invalid argument $2!${WHITE}" + help + fi + fi + done + else + for file in "$1"*; do + if [[ "$file" == *.alpha ]]; then + run "$file" + else + echo -e "${RED}[ERROR] ${YELLOW}File $file is not a .alpha file!${WHITE}" + fi + done + fi + + exit 0 +fi + +if [ -f "$1" ]; then + if [[ "$1" == *.alpha ]]; then + if [ $# -ge 2 ]; then + if [[ "$2" == "-exp" || "$3" == "-exp" || "$2" == "-diff" || "$3" == "-diff" ]]; then + run "$1" "$2" "$3" + else + echo -e "${RED}[ERROR] ${YELLOW}Invalid argument $2!${WHITE}" + help + fi + else + run "$1" + + fi + else + echo -e "${RED}[ERROR] ${YELLOW}File $1 is not a .alpha file!${WHITE}" + help + fi +else + help fi diff --git a/tests/carl/NoErrors/type.array.alpha b/tests/carl/NoErrors/type.array.alpha deleted file mode 100644 index 2b04ba0..0000000 --- a/tests/carl/NoErrors/type.array.alpha +++ /dev/null @@ -1 +0,0 @@ -type A : 1 -> integer diff --git a/tests/given/README.MD b/tests/given/README.MD new file mode 100644 index 0000000..ad2dae4 --- /dev/null +++ b/tests/given/README.MD @@ -0,0 +1 @@ +NOTE: slightly modified from originals, please execute with care. :) \ No newline at end of file diff --git a/tests/carl/NoErrors/entry.definition.alpha.asc b/tests/given/expected/entry.definition.alpha.asc similarity index 100% rename from tests/carl/NoErrors/entry.definition.alpha.asc rename to tests/given/expected/entry.definition.alpha.asc diff --git a/tests/carl/NoErrors/entry.duplicateDifferent.alpha.asc b/tests/given/expected/entry.duplicateDifferent.alpha.asc similarity index 100% rename from tests/carl/NoErrors/entry.duplicateDifferent.alpha.asc rename to tests/given/expected/entry.duplicateDifferent.alpha.asc diff --git a/tests/carl/NoErrors/entry.duplicateSame.alpha.asc b/tests/given/expected/entry.duplicateSame.alpha.asc similarity index 100% rename from tests/carl/NoErrors/entry.duplicateSame.alpha.asc rename to tests/given/expected/entry.duplicateSame.alpha.asc diff --git a/tests/carl/NoErrors/entry.local.alpha.asc b/tests/given/expected/entry.local.alpha.asc similarity index 100% rename from tests/carl/NoErrors/entry.local.alpha.asc rename to tests/given/expected/entry.local.alpha.asc diff --git a/tests/carl/Errors/entry.undeclaredType.alpha.asc b/tests/given/expected/error.entry.undeclaredType.alpha.asc similarity index 100% rename from tests/carl/Errors/entry.undeclaredType.alpha.asc rename to tests/given/expected/error.entry.undeclaredType.alpha.asc diff --git a/tests/carl/Errors/entry.undeclaredVar.alpha.asc b/tests/given/expected/error.entry.undeclaredVar.alpha.asc similarity index 100% rename from tests/carl/Errors/entry.undeclaredVar.alpha.asc rename to tests/given/expected/error.entry.undeclaredVar.alpha.asc diff --git a/tests/carl/NoErrors/error.none.alpha.asc b/tests/given/expected/error.none.alpha.asc similarity index 100% rename from tests/carl/NoErrors/error.none.alpha.asc rename to tests/given/expected/error.none.alpha.asc diff --git a/tests/carl/Errors/error.operator.alpha.asc b/tests/given/expected/error.operator.alpha.asc similarity index 100% rename from tests/carl/Errors/error.operator.alpha.asc rename to tests/given/expected/error.operator.alpha.asc diff --git a/tests/carl/NoErrors/function.declaration.alpha.asc b/tests/given/expected/function.declaration.alpha.asc similarity index 100% rename from tests/carl/NoErrors/function.declaration.alpha.asc rename to tests/given/expected/function.declaration.alpha.asc diff --git a/tests/carl/NoErrors/function.definition.alpha.asc b/tests/given/expected/function.definition.alpha.asc similarity index 100% rename from tests/carl/NoErrors/function.definition.alpha.asc rename to tests/given/expected/function.definition.alpha.asc diff --git a/tests/carl/NoErrors/functionValue.alpha.asc b/tests/given/expected/functionValue.alpha.asc similarity index 100% rename from tests/carl/NoErrors/functionValue.alpha.asc rename to tests/given/expected/functionValue.alpha.asc diff --git a/tests/carl/NoErrors/sample.good.alpha.asc b/tests/given/expected/sample.good.alpha.asc similarity index 100% rename from tests/carl/NoErrors/sample.good.alpha.asc rename to tests/given/expected/sample.good.alpha.asc diff --git a/tests/carl/NoErrors/selectionSort.alpha.asc b/tests/given/expected/selectionSort.alpha.asc similarity index 100% rename from tests/carl/NoErrors/selectionSort.alpha.asc rename to tests/given/expected/selectionSort.alpha.asc diff --git a/tests/carl/NoErrors/type.array.alpha.asc b/tests/given/expected/type.array.alpha.asc similarity index 100% rename from tests/carl/NoErrors/type.array.alpha.asc rename to tests/given/expected/type.array.alpha.asc diff --git a/tests/carl/NoErrors/type.mapping.alpha.asc b/tests/given/expected/type.mapping.alpha.asc similarity index 100% rename from tests/carl/NoErrors/type.mapping.alpha.asc rename to tests/given/expected/type.mapping.alpha.asc diff --git a/tests/carl/NoErrors/type.record.alpha.asc b/tests/given/expected/type.record.alpha.asc similarity index 100% rename from tests/carl/NoErrors/type.record.alpha.asc rename to tests/given/expected/type.record.alpha.asc diff --git a/tests/carl/NoErrors/types.alpha.asc b/tests/given/expected/types.alpha.asc similarity index 100% rename from tests/carl/NoErrors/types.alpha.asc rename to tests/given/expected/types.alpha.asc diff --git a/tests/carl/NoErrors/entry.definition.alpha b/tests/given/test/entry.definition.alpha similarity index 83% rename from tests/carl/NoErrors/entry.definition.alpha rename to tests/given/test/entry.definition.alpha index 0003cd5..75f6a38 100644 --- a/tests/carl/NoErrors/entry.definition.alpha +++ b/tests/given/test/entry.definition.alpha @@ -1,3 +1,4 @@ +(* TEST: [-asc -tc] *) (* type string : 1 -> character *) type M : string -> integer diff --git a/tests/carl/NoErrors/entry.duplicateDifferent.alpha b/tests/given/test/entry.duplicateDifferent.alpha similarity index 85% rename from tests/carl/NoErrors/entry.duplicateDifferent.alpha rename to tests/given/test/entry.duplicateDifferent.alpha index 5cbd668..6a75b69 100644 --- a/tests/carl/NoErrors/entry.duplicateDifferent.alpha +++ b/tests/given/test/entry.duplicateDifferent.alpha @@ -1,3 +1,4 @@ +(* TEST: [-asc -tc] *) type M : string -> integer function entry : M diff --git a/tests/carl/NoErrors/entry.duplicateSame.alpha b/tests/given/test/entry.duplicateSame.alpha similarity index 83% rename from tests/carl/NoErrors/entry.duplicateSame.alpha rename to tests/given/test/entry.duplicateSame.alpha index 554b9d8..435e170 100644 --- a/tests/carl/NoErrors/entry.duplicateSame.alpha +++ b/tests/given/test/entry.duplicateSame.alpha @@ -1,3 +1,4 @@ +(* TEST: [-asc -tc] *) type M : string -> integer function entry : M diff --git a/tests/carl/NoErrors/entry.local.alpha b/tests/given/test/entry.local.alpha similarity index 84% rename from tests/carl/NoErrors/entry.local.alpha rename to tests/given/test/entry.local.alpha index cff2062..f2efa3a 100644 --- a/tests/carl/NoErrors/entry.local.alpha +++ b/tests/given/test/entry.local.alpha @@ -1,3 +1,4 @@ +(* TEST: [-asc -tc] *) type M : string -> integer function entry : M diff --git a/tests/carl/Errors/entry.undeclaredType.alpha b/tests/given/test/error.entry.undeclaredType.alpha similarity index 81% rename from tests/carl/Errors/entry.undeclaredType.alpha rename to tests/given/test/error.entry.undeclaredType.alpha index 6b9531f..9de0d02 100644 --- a/tests/carl/Errors/entry.undeclaredType.alpha +++ b/tests/given/test/error.entry.undeclaredType.alpha @@ -1,3 +1,4 @@ +(* TEST: [-asc -tc] *) type M : string -> integer function foo : M diff --git a/tests/carl/Errors/entry.undeclaredVar.alpha b/tests/given/test/error.entry.undeclaredVar.alpha similarity index 77% rename from tests/carl/Errors/entry.undeclaredVar.alpha rename to tests/given/test/error.entry.undeclaredVar.alpha index 6cd5fa7..29a502c 100644 --- a/tests/carl/Errors/entry.undeclaredVar.alpha +++ b/tests/given/test/error.entry.undeclaredVar.alpha @@ -1,3 +1,4 @@ +(* TEST: [-asc -tc] *) type M : string -> integer function entry : M diff --git a/tests/carl/NoErrors/error.none.alpha b/tests/given/test/error.none.alpha similarity index 90% rename from tests/carl/NoErrors/error.none.alpha rename to tests/given/test/error.none.alpha index 85aa4f2..bd54c16 100644 --- a/tests/carl/NoErrors/error.none.alpha +++ b/tests/given/test/error.none.alpha @@ -1,3 +1,4 @@ +(* TEST: [-asc -tc] *) type string2int: string -> integer function entry : string2int diff --git a/tests/carl/Errors/error.operator.alpha b/tests/given/test/error.operator.alpha similarity index 90% rename from tests/carl/Errors/error.operator.alpha rename to tests/given/test/error.operator.alpha index a7b0691..bb2e79c 100644 --- a/tests/carl/Errors/error.operator.alpha +++ b/tests/given/test/error.operator.alpha @@ -1,3 +1,4 @@ +(* TEST: [-asc -tc] *) type string2int: string -> integer function entry : string2int diff --git a/tests/carl/NoErrors/function.declaration.alpha b/tests/given/test/function.declaration.alpha similarity index 65% rename from tests/carl/NoErrors/function.declaration.alpha rename to tests/given/test/function.declaration.alpha index 69f210f..2396d45 100644 --- a/tests/carl/NoErrors/function.declaration.alpha +++ b/tests/given/test/function.declaration.alpha @@ -1,3 +1,4 @@ +(* TEST: [-asc -tc] *) type M : integer -> integer function f : M diff --git a/tests/carl/NoErrors/function.definition.alpha b/tests/given/test/function.definition.alpha similarity index 75% rename from tests/carl/NoErrors/function.definition.alpha rename to tests/given/test/function.definition.alpha index b729610..ffafb72 100644 --- a/tests/carl/NoErrors/function.definition.alpha +++ b/tests/given/test/function.definition.alpha @@ -1,3 +1,4 @@ +(* TEST: [-asc -tc] *) type M : integer -> integer function f : M diff --git a/tests/carl/NoErrors/functionValue.alpha b/tests/given/test/functionValue.alpha similarity index 70% rename from tests/carl/NoErrors/functionValue.alpha rename to tests/given/test/functionValue.alpha index f521a42..24fce40 100644 --- a/tests/carl/NoErrors/functionValue.alpha +++ b/tests/given/test/functionValue.alpha @@ -1,5 +1,6 @@ +(* TEST: [-asc -tc] *) (* Type definitions *) - +#include "std.alpha" (* mapping type *) type string2int: string -> integer @@ -8,9 +9,9 @@ type funArray: 1 -> string2int (* record of functions *) type funRec: [ string2int: f; string2int: g ] - +type int2int: integer -> integer (* function returning function *) -type integer_2_string2int: integer -> string2int +type integer_2_int2int: integer -> int2int (* function returning function *) type string2int_2_integer: string2int -> integer @@ -21,21 +22,23 @@ 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 a: int2int +function b: integer_2_int2int function c: string2int_2_integer function d: iic2b d(x,y,z) := { - return (x < y & z < 'm'); + [string: s] + return true; } function entry: string2int a(x) := { [string : s] - s := x; + x:= printInteger(x); + return 0; } @@ -44,30 +47,31 @@ b(x) := { i := x; return a; } - + c(x) := { [string: s] s := "Hi!"; - return x(s); + return 3; } - + (* Function definition entry is the first function called *) entry(arg) := { - [integer: result; string2int: f; integer: temp] - temp := a("Hello"); + [integer: result; int2int: f; integer: temp] + temp := 7; f := b(temp); - result := c(f); + result := f(temp); + (*result := c(f);*) if (d(1,2,'c')) then { result := 0; } else { - [ Boolean : b] + [ Boolean : b] result := entry("hello"); } - result := c(f); + (*result := c(f);*) return result; } diff --git a/tests/carl/NoErrors/sample.good.alpha b/tests/given/test/sample.good.alpha similarity index 96% rename from tests/carl/NoErrors/sample.good.alpha rename to tests/given/test/sample.good.alpha index 8a8b727..8153085 100644 --- a/tests/carl/NoErrors/sample.good.alpha +++ b/tests/given/test/sample.good.alpha @@ -1,3 +1,4 @@ +(* TEST: [-asc -tc] *) (* Type definitions *) type int2int: integer -> integer diff --git a/tests/carl/NoErrors/selectionSort.alpha b/tests/given/test/selectionSort.alpha similarity index 98% rename from tests/carl/NoErrors/selectionSort.alpha rename to tests/given/test/selectionSort.alpha index edd2076..489f355 100644 --- a/tests/carl/NoErrors/selectionSort.alpha +++ b/tests/given/test/selectionSort.alpha @@ -1,3 +1,4 @@ +(* TEST: [-asc -tc] *) (* Type definitions *) type string2int: string -> integer diff --git a/tests/given/test/type.array.alpha b/tests/given/test/type.array.alpha new file mode 100644 index 0000000..3aec34c --- /dev/null +++ b/tests/given/test/type.array.alpha @@ -0,0 +1,2 @@ +(* TEST: [-asc -tc] *) +type A : 1 -> integer diff --git a/tests/carl/NoErrors/type.mapping.alpha b/tests/given/test/type.mapping.alpha similarity index 57% rename from tests/carl/NoErrors/type.mapping.alpha rename to tests/given/test/type.mapping.alpha index 8b6bc50..dc4f63d 100644 --- a/tests/carl/NoErrors/type.mapping.alpha +++ b/tests/given/test/type.mapping.alpha @@ -1,2 +1,3 @@ +(* TEST: [-asc -tc] *) type M : integer -> character diff --git a/tests/carl/NoErrors/type.record.alpha b/tests/given/test/type.record.alpha similarity index 64% rename from tests/carl/NoErrors/type.record.alpha rename to tests/given/test/type.record.alpha index 2c5e9c9..9c2b1c6 100644 --- a/tests/carl/NoErrors/type.record.alpha +++ b/tests/given/test/type.record.alpha @@ -1 +1,2 @@ +(* TEST: [-asc -tc] *) type R : [ integer : i ; character : c ] diff --git a/tests/carl/NoErrors/types.alpha b/tests/given/test/types.alpha similarity index 98% rename from tests/carl/NoErrors/types.alpha rename to tests/given/test/types.alpha index 0402f95..47e92f5 100644 --- a/tests/carl/NoErrors/types.alpha +++ b/tests/given/test/types.alpha @@ -1,3 +1,4 @@ +(* TEST: [-asc -tc] *) (* At compiler start-up your program should diff --git a/tests/programs/array.alpha b/tests/programs/array.alpha new file mode 100644 index 0000000..55841e9 --- /dev/null +++ b/tests/programs/array.alpha @@ -0,0 +1,19 @@ +#include "../../library/std.alpha" +type main: string -> integer +function entry: main + +(* maybe some other type definitions *) + +entry(arg) := { + [ string: one_name; string: another_name ] + + one_name := "a string literal"; + + another_name := reserve another_name(4); + another_name(0) := 'C'; + another_name(1) := 'a'; + another_name(2) := 'r'; + another_name(3) := 'l'; + + return 0; +} \ No newline at end of file diff --git a/tests/programs/factorial.alpha b/tests/programs/factorial.alpha new file mode 100644 index 0000000..4f02932 --- /dev/null +++ b/tests/programs/factorial.alpha @@ -0,0 +1,42 @@ +#include "std.alpha" + +function entry: string2integer +function calc: integerXinteger2integer + +calc(counter, result) := { + + if ( counter = 0 ) then { + return result; + } else { + result := result * counter; + counter := counter - 1; + return calc(counter, result); + } +} + + + +entry (arg) := { + [integer: result; integer: userInput] + + result := printC('E'); + result := printC('n'); + result := printC('t'); + result := printC('e'); + result := printC('r'); + result := printC(' '); + result := printC('N'); + result := printC('u'); + result := printC('m'); + result := printC('b'); + result := printC('e'); + result := printC('r'); + result := printC(':'); + result := printC(' '); + + userInput := inI(1); + userInput := calc(userInput, 1); + result := printI(userInput); + + return 0; +} \ No newline at end of file diff --git a/tests/programs/fib.alpha b/tests/programs/fib.alpha new file mode 100644 index 0000000..1a9d185 --- /dev/null +++ b/tests/programs/fib.alpha @@ -0,0 +1,47 @@ +#include "std.alpha" + +function entry : string2integer +function fib : integer2integer + +fib(i) := { + + if (i < 1) then { + return 0; + } else { + i := i; + } + + if (i < 2) then { + return i; + } else { + i := i; + } + + return fib(i-1) + fib(i-2); +} + +entry (arg) := { + [ integer: result; integer: input; integer: fibValue] + + result := printC('E'); + result := printC('n'); + result := printC('t'); + result := printC('e'); + result := printC('r'); + result := printC(' '); + result := printC('N'); + result := printC('u'); + result := printC('m'); + result := printC('b'); + result := printC('e'); + result := printC('r'); + result := printC(':'); + result := printC(' '); + + input := inI(1); + fibValue := fib(input); + + result := printI(fibValue); + + return 0; +} diff --git a/tests/programs/helloworld.alpha b/tests/programs/helloworld.alpha new file mode 100644 index 0000000..abc43a3 --- /dev/null +++ b/tests/programs/helloworld.alpha @@ -0,0 +1,23 @@ +#include "std.alpha" + +function entry: string2integer + +entry (arg) := { + [integer: result] + + result := printCharacter('H'); + result := printCharacter('e'); + result := printCharacter('l'); + result := printCharacter('l'); + result := printCharacter('o'); + result := printCharacter(' '); + result := printCharacter('W'); + result := printCharacter('o'); + result := printCharacter('r'); + result := printCharacter('l'); + result := printCharacter('d'); + result := printCharacter('!'); + result := printCharacter('\n'); + + return 0; +} diff --git a/tests/programs/sp3_if_else_sse.alpha b/tests/programs/sp3_if_else_sse.alpha new file mode 100644 index 0000000..b55f061 --- /dev/null +++ b/tests/programs/sp3_if_else_sse.alpha @@ -0,0 +1,36 @@ +#include "std.alpha" +type rec: [character: x; integer: y] + +type T2: rec -> integer + +type main: string -> integer +function entry: main + (* +function bar: T2 + +bar (r,s) := { + return 0; +} + + *) +entry (arg) := { + [ Boolean:x ; Boolean:y ; Boolean:z ; Boolean:t; integer: c] + x := false; + y := false; + if ( (x | y) | !( y = x ) ) then { + + (* + if ( x" +1 22 201 "integer" +2 1 406 "function" +2 10 101 "entry" +2 15 508 ":" +2 17 101 "main" +4 1 101 "entry" +4 6 501 "(" +4 7 101 "arg" +4 10 502 ")" +4 12 608 ":=" +4 15 505 "{" +5 5 407 "return" +5 12 301 "0" +5 13 507 ";" +6 1 506 "}" diff --git a/tests/sprint1/expected/sp1_simple_int.expected b/tests/sprint1/expected/sp1_simple_int.tok.exp similarity index 100% rename from tests/sprint1/expected/sp1_simple_int.expected rename to tests/sprint1/expected/sp1_simple_int.tok.exp diff --git a/tests/sprint1/expected/sp1_simple_literals.expected b/tests/sprint1/expected/sp1_simple_literals.tok.exp similarity index 100% rename from tests/sprint1/expected/sp1_simple_literals.expected rename to tests/sprint1/expected/sp1_simple_literals.tok.exp diff --git a/tests/sprint1/expected/sp1_variables.expected b/tests/sprint1/expected/sp1_variables.tok.exp similarity index 100% rename from tests/sprint1/expected/sp1_variables.expected rename to tests/sprint1/expected/sp1_variables.tok.exp diff --git a/tests/sprint1/test/sp1_comment_fix1.alpha b/tests/sprint1/test/sp1_comment_fix1.alpha index 910a538..25e4ba9 100644 --- a/tests/sprint1/test/sp1_comment_fix1.alpha +++ b/tests/sprint1/test/sp1_comment_fix1.alpha @@ -1 +1,2 @@ +(* TEST: [-tok] *) (***) \ No newline at end of file diff --git a/tests/sprint1/test/sp1_comment_fix2.alpha b/tests/sprint1/test/sp1_comment_fix2.alpha index bd710e9..0ba95b5 100644 --- a/tests/sprint1/test/sp1_comment_fix2.alpha +++ b/tests/sprint1/test/sp1_comment_fix2.alpha @@ -1 +1,2 @@ +(* TEST: [-tok] *) (*(**)*) \ No newline at end of file diff --git a/tests/sprint1/test/sp1_comment_issues.alpha b/tests/sprint1/test/sp1_comment_issues.alpha index e968d93..05d3636 100644 --- a/tests/sprint1/test/sp1_comment_issues.alpha +++ b/tests/sprint1/test/sp1_comment_issues.alpha @@ -1,3 +1,4 @@ +(* TEST: [-tok] *) (*(**)*) (***) (******)(*\kpp*********) diff --git a/tests/sprint1/test/sp1_comments.alpha b/tests/sprint1/test/sp1_comments.alpha index 1111428..f30501b 100644 --- a/tests/sprint1/test/sp1_comments.alpha +++ b/tests/sprint1/test/sp1_comments.alpha @@ -1,3 +1,4 @@ +(* TEST: [-tok] *) (* hello *) (* hello *) (* I'd think this is a legal "string" that contains several \n \t diff --git a/tests/sprint1/test/sp1_general_token.alpha b/tests/sprint1/test/sp1_general_token.alpha index defc56b..9e1389d 100644 --- a/tests/sprint1/test/sp1_general_token.alpha +++ b/tests/sprint1/test/sp1_general_token.alpha @@ -1,3 +1,4 @@ +(* TEST: [-tok] *) This is a test 9combined 7okens 12345 diff --git a/tests/sprint1/test/sp1_include.alpha b/tests/sprint1/test/sp1_include.alpha new file mode 100644 index 0000000..27a2500 --- /dev/null +++ b/tests/sprint1/test/sp1_include.alpha @@ -0,0 +1,4 @@ +(* TEST: [-tok -asc -tc] *) +#include "alpha.h" +#include "alpha.h" +#include "alpha.h" \ No newline at end of file diff --git a/tests/sprint1/test/sp1_keywords.alpha b/tests/sprint1/test/sp1_keywords.alpha index ff18168..e60a891 100644 --- a/tests/sprint1/test/sp1_keywords.alpha +++ b/tests/sprint1/test/sp1_keywords.alpha @@ -1,3 +1,4 @@ +(* TEST: [-tok] *) while While whiLe diff --git a/tests/sprint1/test/sp1_operators.alpha b/tests/sprint1/test/sp1_operators.alpha index b985387..515ce69 100644 --- a/tests/sprint1/test/sp1_operators.alpha +++ b/tests/sprint1/test/sp1_operators.alpha @@ -1,3 +1,4 @@ +(* TEST: [-tok] *) + - * diff --git a/tests/sprint1/test/sp1_other_punc.alpha b/tests/sprint1/test/sp1_other_punc.alpha index bd1f2de..a9981db 100644 --- a/tests/sprint1/test/sp1_other_punc.alpha +++ b/tests/sprint1/test/sp1_other_punc.alpha @@ -1,3 +1,4 @@ +(* TEST: [-tok] *) ; : , diff --git a/tests/sprint1/test/sp1_punc_grouping.alpha b/tests/sprint1/test/sp1_punc_grouping.alpha index 45dfb99..c512933 100644 --- a/tests/sprint1/test/sp1_punc_grouping.alpha +++ b/tests/sprint1/test/sp1_punc_grouping.alpha @@ -1,3 +1,4 @@ +(* TEST: [-tok] *) ) a) )a diff --git a/tests/sprint1/test/sp1_real_alpha_file1.alpha b/tests/sprint1/test/sp1_real_alpha_file1.alpha index 51d5d08..f729f0b 100644 --- a/tests/sprint1/test/sp1_real_alpha_file1.alpha +++ b/tests/sprint1/test/sp1_real_alpha_file1.alpha @@ -1,3 +1,4 @@ +(* TEST: [-tok] *) type rec: [integer: x; integer: y] type T1: integer -> integer type T2: rec -> integer diff --git a/tests/sprint1/test/sp1_real_alpha_file2.alpha b/tests/sprint1/test/sp1_real_alpha_file2.alpha index 0beb2af..409d6d3 100644 --- a/tests/sprint1/test/sp1_real_alpha_file2.alpha +++ b/tests/sprint1/test/sp1_real_alpha_file2.alpha @@ -1,3 +1,4 @@ +(* TEST: [-tok] *) (* Type definitions *) type string: 1 -> character type int2int: integer -> integer diff --git a/tests/sprint1/test/sp1_simple_alpha.alpha b/tests/sprint1/test/sp1_simple_alpha.alpha new file mode 100644 index 0000000..3f59493 --- /dev/null +++ b/tests/sprint1/test/sp1_simple_alpha.alpha @@ -0,0 +1,7 @@ +(* TEST: [-tok] *) +type main: string -> integer +function entry: main + +entry(arg) := { + return 0; +} \ No newline at end of file diff --git a/tests/sprint1/test/sp1_simple_int.alpha b/tests/sprint1/test/sp1_simple_int.alpha index 127f0a6..32c572d 100644 --- a/tests/sprint1/test/sp1_simple_int.alpha +++ b/tests/sprint1/test/sp1_simple_int.alpha @@ -1,3 +1,4 @@ +(* TEST: [-tok] *) 45 123 8392 diff --git a/tests/sprint1/test/sp1_simple_literals.alpha b/tests/sprint1/test/sp1_simple_literals.alpha index 4c5b0b2..ba4aa9d 100644 --- a/tests/sprint1/test/sp1_simple_literals.alpha +++ b/tests/sprint1/test/sp1_simple_literals.alpha @@ -1,3 +1,4 @@ +(* TEST: [-tok] *) "this is a string" 721398 'g' '/n' (* should print 3 tokens before this *) ' ' diff --git a/tests/sprint1/test/sp1_variables.alpha b/tests/sprint1/test/sp1_variables.alpha index 26db6c0..7e69840 100644 --- a/tests/sprint1/test/sp1_variables.alpha +++ b/tests/sprint1/test/sp1_variables.alpha @@ -1,3 +1,4 @@ +(* TEST: [-tok] *) valid1 Valid2 _valid3 diff --git a/tests/sprint2/expected/sp2_carls_mistake.expected b/tests/sprint2/expected/sp2_carls_mistake.st.exp similarity index 74% rename from tests/sprint2/expected/sp2_carls_mistake.expected rename to tests/sprint2/expected/sp2_carls_mistake.st.exp index cee5d6f..edcf5c5 100644 --- a/tests/sprint2/expected/sp2_carls_mistake.expected +++ b/tests/sprint2/expected/sp2_carls_mistake.st.exp @@ -1,27 +1,30 @@ 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 +Boolean : 001001 : : Primitive Type : size-1 bytes reserve type : 001001 : : integer -> address : Type of Function -reserve : 001001 : : undefined : Function Definition +reserve : 001001 : : reserve type : Function not defined before runtime release type : 001001 : : address -> integer : Type of Function -release : 001001 : : undefined : Function Definition +release : 001001 : : release type : Function not defined before runtime +rec : 001001 : : Record Type : elements-2 size-8 bytes +T1 : 001001 : : integer -> integer : Type of Function +T2 : 001001 : : rec -> integer : Type of Function +arr : 001001 : : 1 -> integer : Type of Array +main : 001001 : : string -> integer : Type of Function +entry : 001001 : : main : Function Definition that starts at line 25 +foo : 001001 : : T1 : Function Definition that starts at line 13 +bar1 : 001001 : : T2 : Function Definition that starts at line 17 +bar2 : 001001 : : T2 : Function Definition that starts at line 21 ------------------------------:--------:--------:-----------------------------------:-----------------------------------: -w : 025000 : 001001 : rec : Record Instance -result : 025000 : 001001 : integer : Primitive Instance arg : 025000 : 001001 : string : Array Instance +result : 025000 : 001001 : integer : Primitive Instance +w : 025000 : 001001 : rec : Record Instance +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +------------------------------:--------:--------:-----------------------------------:-----------------------------------: ------------------------------:--------:--------:-----------------------------------:-----------------------------------: r : 021000 : 001001 : integer : Primitive Instance s : 021000 : 001001 : integer : Primitive Instance @@ -31,5 +34,5 @@ y : 017000 : 001001 : integer ------------------------------:--------:--------:-----------------------------------:-----------------------------------: x : 013000 : 001001 : integer : Primitive Instance ------------------------------:--------:--------:-----------------------------------:-----------------------------------: -y : 001000 : 001001 : integer : Primitive Instance x : 001000 : 001001 : integer : Primitive Instance +y : 001000 : 001001 : integer : Primitive Instance diff --git a/tests/sprint2/expected/sp2_function_types.expected b/tests/sprint2/expected/sp2_function_types.st.exp similarity index 67% rename from tests/sprint2/expected/sp2_function_types.expected rename to tests/sprint2/expected/sp2_function_types.st.exp index 391690b..707ff66 100644 --- a/tests/sprint2/expected/sp2_function_types.expected +++ b/tests/sprint2/expected/sp2_function_types.st.exp @@ -1,29 +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 +Boolean : 001001 : : Primitive Type : size-1 bytes reserve type : 001001 : : integer -> address : Type of Function -reserve : 001001 : : undefined : Function Definition +reserve : 001001 : : reserve type : Function not defined before runtime release type : 001001 : : address -> integer : Type of Function -release : 001001 : : undefined : Function Definition +release : 001001 : : release type : Function not defined before runtime +Boolean2Boolean : 001001 : : Boolean -> Boolean : Type of Function +integer2integer : 001001 : : integer -> integer : Type of Function +character2integer : 001001 : : character -> integer : Type of Function +Boolean2integer : 001001 : : Boolean -> integer : Type of Function +string2integer : 001001 : : string -> integer : Type of Function +integer2integer2Boolean : 001001 : : integer2integer -> Boolean : Type of Function +character2character2Boolean : 001001 : : undefined -> undefined : Type of Function +Boolean2Boolean2Boolean : 001001 : : Boolean2Boolean -> Boolean : Type of Function +integer2address : 001001 : : integer -> address : Type of Function +address2integer : 001001 : : address -> integer : Type of Function +integer2integer2integer : 001001 : : integer2integer -> integer : Type of Function +printInteger : 001001 : : integer2integer : Function not defined before runtime +printCharacter : 001001 : : character2integer : Function not defined before runtime +printBoolean : 001001 : : Boolean2integer : Function not defined before runtime +reserved : 001001 : : integer2address : Function not defined before runtime +released : 001001 : : address2integer : Function not defined before runtime +integer2integer2integerFunc : 001001 : : integer2integer2integer : Function not defined before runtime +entry : 001001 : : string2integer : Function not defined before runtime diff --git a/tests/sprint2/expected/sp2_integer_binary_op.expected b/tests/sprint2/expected/sp2_integer_binary_op.st.exp similarity index 83% rename from tests/sprint2/expected/sp2_integer_binary_op.expected rename to tests/sprint2/expected/sp2_integer_binary_op.st.exp index d24c170..b418814 100644 --- a/tests/sprint2/expected/sp2_integer_binary_op.expected +++ b/tests/sprint2/expected/sp2_integer_binary_op.st.exp @@ -1,21 +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 +Boolean : 001001 : : Primitive Type : size-1 bytes reserve type : 001001 : : integer -> address : Type of Function -reserve : 001001 : : undefined : Function Definition +reserve : 001001 : : reserve type : Function not defined before runtime release type : 001001 : : address -> integer : Type of Function -release : 001001 : : undefined : Function Definition +release : 001001 : : release type : Function not defined before runtime +main : 001001 : : string -> integer : Type of Function +entry : 001001 : : main : Function Definition that starts at line 5 +testarr : 001001 : : 1 -> integer : Type of Array ------------------------------:--------:--------:-----------------------------------:-----------------------------------: -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 +x : 005000 : 001001 : integer : Primitive Instance +arr : 005000 : 001001 : testarr : Array Instance +arr2 : 005000 : 001001 : testarr : Array Instance +b2 : 005000 : 001001 : Boolean : Primitive Instance +b1 : 005000 : 001001 : Boolean : Primitive Instance diff --git a/tests/sprint2/expected/sp2_invalid_multiple_params_no_as.expected b/tests/sprint2/expected/sp2_invalid_multiple_params_no_as.st.exp similarity index 82% rename from tests/sprint2/expected/sp2_invalid_multiple_params_no_as.expected rename to tests/sprint2/expected/sp2_invalid_multiple_params_no_as.st.exp index 509c6eb..df23356 100644 --- a/tests/sprint2/expected/sp2_invalid_multiple_params_no_as.expected +++ b/tests/sprint2/expected/sp2_invalid_multiple_params_no_as.st.exp @@ -1,20 +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 +Boolean : 001001 : : Primitive Type : size-1 bytes reserve type : 001001 : : integer -> address : Type of Function -reserve : 001001 : : undefined : Function Definition +reserve : 001001 : : reserve type : Function not defined before runtime release type : 001001 : : address -> integer : Type of Function -release : 001001 : : undefined : Function Definition +release : 001001 : : release type : Function not defined before runtime +rec : 001001 : : Record Type : elements-2 size-8 bytes +main : 001001 : : rec -> integer : Type of Function +test : 001001 : : main : Function Definition that starts at line 5 ------------------------------:--------:--------:-----------------------------------:-----------------------------------: arg : 005000 : 001001 : integer : Primitive Instance arg2 : 005000 : 001001 : integer : Primitive Instance ------------------------------:--------:--------:-----------------------------------:-----------------------------------: -y : 001000 : 001001 : integer : Primitive Instance x : 001000 : 001001 : integer : Primitive Instance +y : 001000 : 001001 : integer : Primitive Instance diff --git a/tests/sprint2/expected/sp2_invalid_recop.expected b/tests/sprint2/expected/sp2_invalid_recop.st.exp similarity index 82% rename from tests/sprint2/expected/sp2_invalid_recop.expected rename to tests/sprint2/expected/sp2_invalid_recop.st.exp index 642ad85..b6a78e2 100644 --- a/tests/sprint2/expected/sp2_invalid_recop.expected +++ b/tests/sprint2/expected/sp2_invalid_recop.st.exp @@ -1,20 +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 +Boolean : 001001 : : Primitive Type : size-1 bytes reserve type : 001001 : : integer -> address : Type of Function -reserve : 001001 : : undefined : Function Definition +reserve : 001001 : : reserve type : Function not defined before runtime release type : 001001 : : address -> integer : Type of Function -release : 001001 : : undefined : Function Definition +release : 001001 : : release type : Function not defined before runtime +main : 001001 : : string -> integer : Type of Function +entry : 001001 : : main : Function Definition that starts at line 6 +rec : 001001 : : Record Type : elements-2 size-8 bytes ------------------------------:--------:--------:-----------------------------------:-----------------------------------: -w : 006000 : 001001 : rec : Record Instance arg : 006000 : 001001 : string : Array Instance +w : 006000 : 001001 : rec : Record Instance ------------------------------:--------:--------:-----------------------------------:-----------------------------------: -y : 004000 : 001001 : integer : Primitive Instance x : 004000 : 001001 : integer : Primitive Instance +y : 004000 : 001001 : integer : Primitive Instance diff --git a/tests/sprint2/expected/sp2_invalid_release.expected b/tests/sprint2/expected/sp2_invalid_release.st.exp similarity index 85% rename from tests/sprint2/expected/sp2_invalid_release.expected rename to tests/sprint2/expected/sp2_invalid_release.st.exp index 1ac0274..823a68c 100644 --- a/tests/sprint2/expected/sp2_invalid_release.expected +++ b/tests/sprint2/expected/sp2_invalid_release.st.exp @@ -1,17 +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 +Boolean : 001001 : : Primitive Type : size-1 bytes reserve type : 001001 : : integer -> address : Type of Function -reserve : 001001 : : undefined : Function Definition +reserve : 001001 : : reserve type : Function not defined before runtime release type : 001001 : : address -> integer : Type of Function -release : 001001 : : undefined : Function Definition +release : 001001 : : release type : Function not defined before runtime +rec : 001001 : : Record Type : elements-2 size-8 bytes ------------------------------:--------:--------:-----------------------------------:-----------------------------------: w : 003000 : 001001 : rec : Record Instance ------------------------------:--------:--------:-----------------------------------:-----------------------------------: -y : 001000 : 001001 : integer : Primitive Instance x : 001000 : 001001 : integer : Primitive Instance +y : 001000 : 001001 : integer : Primitive Instance diff --git a/tests/sprint2/expected/sp2_library.expected b/tests/sprint2/expected/sp2_library.st.exp similarity index 79% rename from tests/sprint2/expected/sp2_library.expected rename to tests/sprint2/expected/sp2_library.st.exp index 80a9611..a625233 100644 --- a/tests/sprint2/expected/sp2_library.expected +++ b/tests/sprint2/expected/sp2_library.st.exp @@ -1,39 +1,38 @@ 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 +Boolean : 001001 : : Primitive Type : size-1 bytes reserve type : 001001 : : integer -> address : Type of Function -reserve : 001001 : : undefined : Function Definition +reserve : 001001 : : reserve type : Function not defined before runtime release type : 001001 : : address -> integer : Type of Function -release : 001001 : : undefined : Function Definition +release : 001001 : : release type : Function not defined before runtime +BooleanXBoolean : 001001 : : Record Type : elements-2 size-2 bytes +characterXcharacter : 001001 : : Record Type : elements-2 size-2 bytes +integerXinteger : 001001 : : Record Type : elements-2 size-8 bytes +Boolean2Boolean : 001001 : : Boolean -> Boolean : Type of Function +integer2integer : 001001 : : integer -> integer : Type of Function +character2integer : 001001 : : character -> integer : Type of Function +Boolean2integer : 001001 : : Boolean -> integer : Type of Function +string2integer : 001001 : : string -> integer : Type of Function +integerXinteger2integer : 001001 : : integerXinteger -> integer : Type of Function +integerXinteger2Boolean : 001001 : : integerXinteger -> Boolean : Type of Function +characterXcharacter2Boolean : 001001 : : characterXcharacter -> Boolean : Type of Function +BooleanXBoolean2Boolean : 001001 : : BooleanXBoolean -> Boolean : Type of Function +integer2address : 001001 : : integer -> address : Type of Function +address2integer : 001001 : : address -> integer : Type of Function +printInteger : 001001 : : integer2integer : Function not defined before runtime +printCharacter : 001001 : : character2integer : Function not defined before runtime +printBoolean : 001001 : : Boolean2integer : Function not defined before runtime +entry : 001001 : : string2integer : Function not defined before runtime ------------------------------:--------:--------:-----------------------------------:-----------------------------------: -y : 015000 : 001001 : integer : Primitive Instance x : 015000 : 001001 : integer : Primitive Instance +y : 015000 : 001001 : integer : Primitive Instance ------------------------------:--------:--------:-----------------------------------:-----------------------------------: -y : 014000 : 001001 : character : Primitive Instance x : 014000 : 001001 : character : Primitive Instance +y : 014000 : 001001 : character : Primitive Instance ------------------------------:--------:--------:-----------------------------------:-----------------------------------: -y : 013000 : 001001 : Boolean : Primitive Instance x : 013000 : 001001 : Boolean : Primitive Instance +y : 013000 : 001001 : Boolean : Primitive Instance diff --git a/tests/sprint2/expected/sp2_llnode.st.exp b/tests/sprint2/expected/sp2_llnode.st.exp new file mode 100644 index 0000000..abbd641 --- /dev/null +++ b/tests/sprint2/expected/sp2_llnode.st.exp @@ -0,0 +1,61 @@ +NAME : SCOPE : PARENT : TYPE : EXTRA ANNOTATION : +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +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-1 bytes +reserve type : 001001 : : integer -> address : Type of Function +reserve : 001001 : : reserve type : Function not defined before runtime +release type : 001001 : : address -> integer : Type of Function +release : 001001 : : release type : Function not defined before runtime +main : 001001 : : string -> integer : Type of Function +entry : 001001 : : main : Function Definition that starts at line 68 +rec : 001001 : : Record Type : elements-2 size-8 bytes +T1 : 001001 : : integer -> integer : Type of Function +T2 : 001001 : : rec -> integer : Type of Function +llnode : 001001 : : Record Type : elements-3 size-24 bytes +list : 001001 : : integer -> llnode : Type of Function +foo : 001001 : : T1 : Function Definition that starts at line 45 +bar1 : 001001 : : T2 : Function Definition that starts at line 49 +bar2 : 001001 : : T2 : Function Definition that starts at line 53 +make_list : 001001 : : list : Function Definition that starts at line 16 +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +arg : 068000 : 001001 : string : Array Instance +result : 068000 : 001001 : integer : Primitive Instance +w : 068000 : 001001 : rec : Record Instance +li : 068000 : 001001 : llnode : Record Instance +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +r : 053000 : 001001 : integer : Primitive Instance +s : 053000 : 001001 : integer : Primitive Instance +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +x : 058012 : 053000 : integer : Primitive Instance +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +a : 049000 : 001001 : integer : Primitive Instance +b : 049000 : 001001 : integer : Primitive Instance +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +x : 045000 : 001001 : integer : Primitive Instance +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +a : 016000 : 001001 : integer : Primitive Instance +orig_a : 016000 : 001001 : integer : Primitive Instance +ret : 016000 : 001001 : llnode : Record Instance +curr : 016000 : 001001 : llnode : Record Instance +temp : 016000 : 001001 : llnode : Record Instance +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +prev : 008000 : 001001 : llnode : Record Instance +val : 008000 : 001001 : integer : Primitive Instance +next : 008000 : 001001 : llnode : Record Instance +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +x : 004000 : 001001 : integer : Primitive Instance +y : 004000 : 001001 : integer : Primitive Instance diff --git a/tests/sprint2/expected/sp2_llnode.expected b/tests/sprint2/expected/sp2_llnode_bad.st.exp similarity index 72% rename from tests/sprint2/expected/sp2_llnode.expected rename to tests/sprint2/expected/sp2_llnode_bad.st.exp index ab13e6f..d6e60a4 100644 --- a/tests/sprint2/expected/sp2_llnode.expected +++ b/tests/sprint2/expected/sp2_llnode_bad.st.exp @@ -1,66 +1,62 @@ 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 +Boolean : 001001 : : Primitive Type : size-1 bytes reserve type : 001001 : : integer -> address : Type of Function -reserve : 001001 : : undefined : Function Definition +reserve : 001001 : : reserve type : Function not defined before runtime release type : 001001 : : address -> integer : Type of Function -release : 001001 : : undefined : Function Definition +release : 001001 : : release type : Function not defined before runtime +main : 001001 : : string -> integer : Type of Function +entry : 001001 : : main : Function Definition that starts at line 69 +rec : 001001 : : Record Type : elements-2 size-8 bytes +T1 : 001001 : : integer -> integer : Type of Function +T2 : 001001 : : rec -> integer : Type of Function +llnode : 001001 : : Record Type : elements-3 size-24 bytes +list : 001001 : : integer -> llnode : Type of Function +foo : 001001 : : T1 : Function Definition that starts at line 46 +bar1 : 001001 : : T2 : Function Definition that starts at line 50 +bar2 : 001001 : : T2 : Function Definition that starts at line 54 +make_list : 001001 : : list : Function Definition that starts at line 16 ------------------------------:--------:--------:-----------------------------------:-----------------------------------: -li : 069000 : 001001 : llnode : Record Instance -w : 069000 : 001001 : rec : Record Instance -result : 069000 : 001001 : integer : Primitive Instance arg : 069000 : 001001 : string : Array Instance +result : 069000 : 001001 : integer : Primitive Instance +w : 069000 : 001001 : rec : Record Instance +li : 069000 : 001001 : llnode : Record 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 +orig_a : 016000 : 001001 : integer : Primitive Instance +ret : 016000 : 001001 : llnode : Record Instance +curr : 016000 : 001001 : llnode : Record Instance +temp : 016000 : 001001 : llnode : Record 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 +val : 008000 : 001001 : integer : Primitive Instance +next : 008000 : 001001 : llnode : Record Instance ------------------------------:--------:--------:-----------------------------------:-----------------------------------: -y : 004000 : 001001 : integer : Primitive Instance x : 004000 : 001001 : integer : Primitive Instance +y : 004000 : 001001 : integer : Primitive Instance diff --git a/tests/sprint2/expected/sp2_one_line.expected b/tests/sprint2/expected/sp2_one_line.st.exp similarity index 77% rename from tests/sprint2/expected/sp2_one_line.expected rename to tests/sprint2/expected/sp2_one_line.st.exp index dcdd20a..f8d9751 100644 --- a/tests/sprint2/expected/sp2_one_line.expected +++ b/tests/sprint2/expected/sp2_one_line.st.exp @@ -1,22 +1,22 @@ 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 +Boolean : 001001 : : Primitive Type : size-1 bytes reserve type : 001001 : : integer -> address : Type of Function -reserve : 001001 : : undefined : Function Definition +reserve : 001001 : : reserve type : Function not defined before runtime release type : 001001 : : address -> integer : Type of Function -release : 001001 : : undefined : Function Definition +release : 001001 : : release type : Function not defined before runtime +main : 001001 : : string -> integer : Type of Function +entry : 001001 : : main : Function not defined before runtime +rec : 001001 : : Record Type : elements-2 size-8 bytes +T1 : 001001 : : integer -> integer : Type of Function +T2 : 001001 : : rec -> integer : Type of Function +foo : 001001 : : T1 : Function Definition that starts at line 1 +bar1 : 001001 : : T2 : Function Definition that starts at line 1 +bar2 : 001001 : : T2 : Function not defined before runtime ------------------------------:--------:--------:-----------------------------------:-----------------------------------: : 000000 : 001001 : : Empty Scope ------------------------------:--------:--------:-----------------------------------:-----------------------------------: @@ -25,5 +25,5 @@ undefined : 001000 : 001001 : integer ------------------------------:--------:--------:-----------------------------------:-----------------------------------: x : 001000 : 001001 : integer : Primitive Instance ------------------------------:--------:--------:-----------------------------------:-----------------------------------: -y : 001000 : 001001 : integer : Primitive Instance x : 001000 : 001001 : integer : Primitive Instance +y : 001000 : 001001 : integer : Primitive Instance diff --git a/tests/sprint2/expected/sp2_presidence.expected b/tests/sprint2/expected/sp2_presidence.st.exp similarity index 84% rename from tests/sprint2/expected/sp2_presidence.expected rename to tests/sprint2/expected/sp2_presidence.st.exp index 80d2312..2c97464 100644 --- a/tests/sprint2/expected/sp2_presidence.expected +++ b/tests/sprint2/expected/sp2_presidence.st.exp @@ -1,23 +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 +Boolean : 001001 : : Primitive Type : size-1 bytes reserve type : 001001 : : integer -> address : Type of Function -reserve : 001001 : : undefined : Function Definition +reserve : 001001 : : reserve type : Function not defined before runtime release type : 001001 : : address -> integer : Type of Function -release : 001001 : : undefined : Function Definition +release : 001001 : : release type : Function not defined before runtime +main : 001001 : : string -> integer : Type of Function +rec : 001001 : : Record Type : elements-2 size-8 bytes +entry : 001001 : : main : Function Definition that starts at line 6 ------------------------------:--------:--------:-----------------------------------:-----------------------------------: -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 +arg_x : 006000 : 001001 : integer : Primitive Instance +arg_y : 006000 : 001001 : integer : Primitive Instance +arg_record : 006000 : 001001 : rec : Record Instance +arg_bool : 006000 : 001001 : Boolean : Primitive Instance ------------------------------:--------:--------:-----------------------------------:-----------------------------------: -rec_y : 002000 : 001001 : integer : Primitive Instance rec_x : 002000 : 001001 : integer : Primitive Instance +rec_y : 002000 : 001001 : integer : Primitive Instance diff --git a/tests/sprint2/expected/sp2_simple.expected b/tests/sprint2/expected/sp2_simple.st.exp similarity index 77% rename from tests/sprint2/expected/sp2_simple.expected rename to tests/sprint2/expected/sp2_simple.st.exp index 649bea7..71d24c9 100644 --- a/tests/sprint2/expected/sp2_simple.expected +++ b/tests/sprint2/expected/sp2_simple.st.exp @@ -1,16 +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 +Boolean : 001001 : : Primitive Type : size-1 bytes reserve type : 001001 : : integer -> address : Type of Function -reserve : 001001 : : undefined : Function Definition +reserve : 001001 : : reserve type : Function not defined before runtime release type : 001001 : : address -> integer : Type of Function -release : 001001 : : undefined : Function Definition +release : 001001 : : release type : Function not defined before runtime +main : 001001 : : string -> integer : Type of Function +entry : 001001 : : main : Function Definition that starts at line 4 ------------------------------:--------:--------:-----------------------------------:-----------------------------------: -x : 004000 : 001001 : integer : Primitive Instance arg : 004000 : 001001 : string : Array Instance +x : 004000 : 001001 : integer : Primitive Instance diff --git a/tests/sprint2/expected/sp2_sp2_arrayargs.expected b/tests/sprint2/expected/sp2_sp2_arrayargs.st.exp similarity index 56% rename from tests/sprint2/expected/sp2_sp2_arrayargs.expected rename to tests/sprint2/expected/sp2_sp2_arrayargs.st.exp index 0db9d5a..028f8a4 100644 --- a/tests/sprint2/expected/sp2_sp2_arrayargs.expected +++ b/tests/sprint2/expected/sp2_sp2_arrayargs.st.exp @@ -1,17 +1,24 @@ 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 +Boolean : 001001 : : Primitive Type : size-1 bytes reserve type : 001001 : : integer -> address : Type of Function -reserve : 001001 : : undefined : Function Definition +reserve : 001001 : : reserve type : Function not defined before runtime release type : 001001 : : address -> integer : Type of Function -release : 001001 : : undefined : Function Definition +release : 001001 : : release type : Function not defined before runtime +a_of_s : 001001 : : 1 -> string : Type of Array ------------------------------:--------:--------:-----------------------------------:-----------------------------------: -many_names : 006000 : 001001 : a_of_s : Array Instance -another_name : 006000 : 001001 : string : Array Instance one_name : 006000 : 001001 : string : Array Instance +another_name : 006000 : 001001 : string : Array Instance +many_names : 006000 : 001001 : a_of_s : Array Instance +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +------------------------------:--------:--------:-----------------------------------:-----------------------------------: +------------------------------:--------:--------:-----------------------------------:-----------------------------------: diff --git a/tests/sprint2/expected/sp2_valid_assignable_and_mem.expected b/tests/sprint2/expected/sp2_valid_assignable_and_mem.st.exp similarity index 83% rename from tests/sprint2/expected/sp2_valid_assignable_and_mem.expected rename to tests/sprint2/expected/sp2_valid_assignable_and_mem.st.exp index aa4b733..3714bab 100644 --- a/tests/sprint2/expected/sp2_valid_assignable_and_mem.expected +++ b/tests/sprint2/expected/sp2_valid_assignable_and_mem.st.exp @@ -1,21 +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 +Boolean : 001001 : : Primitive Type : size-1 bytes reserve type : 001001 : : integer -> address : Type of Function -reserve : 001001 : : undefined : Function Definition +reserve : 001001 : : reserve type : Function not defined before runtime release type : 001001 : : address -> integer : Type of Function -release : 001001 : : undefined : Function Definition +release : 001001 : : release type : Function not defined before runtime +main : 001001 : : string -> integer : Type of Function +entry : 001001 : : main : Function Definition that starts at line 7 +rec : 001001 : : Record Type : elements-2 size-8 bytes +T2 : 001001 : : rec -> integer : Type of Function ------------------------------:--------:--------:-----------------------------------:-----------------------------------: -w : 007000 : 001001 : rec : Record Instance arg : 007000 : 001001 : string : Array Instance +w : 007000 : 001001 : rec : Record Instance ------------------------------:--------:--------:-----------------------------------:-----------------------------------: -y : 004000 : 001001 : integer : Primitive Instance x : 004000 : 001001 : integer : Primitive Instance +y : 004000 : 001001 : integer : Primitive Instance diff --git a/tests/sprint2/test/sp2_carls_mistake.alpha b/tests/sprint2/test/sp2_carls_mistake.alpha index b7fa8ee..72fa548 100644 --- a/tests/sprint2/test/sp2_carls_mistake.alpha +++ b/tests/sprint2/test/sp2_carls_mistake.alpha @@ -1,3 +1,4 @@ +(* TEST: [-st] *) type rec: [integer: x; integer: y] type T1: integer -> integer diff --git a/tests/sprint2/test/sp2_function_types.alpha b/tests/sprint2/test/sp2_function_types.alpha index 62711c3..00dba5a 100644 --- a/tests/sprint2/test/sp2_function_types.alpha +++ b/tests/sprint2/test/sp2_function_types.alpha @@ -1,3 +1,4 @@ +(* TEST: [-st] *) type Boolean2Boolean: Boolean -> Boolean type integer2integer: integer -> integer type character2integer: character -> integer diff --git a/tests/sprint2/test/sp2_integer_binary_op.alpha b/tests/sprint2/test/sp2_integer_binary_op.alpha index 2dfeb73..cd14c82 100644 --- a/tests/sprint2/test/sp2_integer_binary_op.alpha +++ b/tests/sprint2/test/sp2_integer_binary_op.alpha @@ -1,3 +1,4 @@ +(* TEST: [-st] *) type main: string -> integer function entry: main type testarr : 1 -> integer diff --git a/tests/sprint2/test/sp2_invalid_multiple_params_no_as.alpha b/tests/sprint2/test/sp2_invalid_multiple_params_no_as.alpha index 805fb6e..882688e 100644 --- a/tests/sprint2/test/sp2_invalid_multiple_params_no_as.alpha +++ b/tests/sprint2/test/sp2_invalid_multiple_params_no_as.alpha @@ -1,3 +1,4 @@ +(* TEST: [-st] *) type rec: [integer: x; integer: y] type main: rec -> integer function test: main diff --git a/tests/sprint2/test/sp2_invalid_recop.alpha b/tests/sprint2/test/sp2_invalid_recop.alpha index 41b3a55..79202f5 100644 --- a/tests/sprint2/test/sp2_invalid_recop.alpha +++ b/tests/sprint2/test/sp2_invalid_recop.alpha @@ -1,3 +1,4 @@ +(* TEST: [-st] *) type main: string -> integer function entry: main diff --git a/tests/sprint2/test/sp2_invalid_release.alpha b/tests/sprint2/test/sp2_invalid_release.alpha index 2bd645a..e29ac0b 100644 --- a/tests/sprint2/test/sp2_invalid_release.alpha +++ b/tests/sprint2/test/sp2_invalid_release.alpha @@ -1,3 +1,4 @@ +(* TEST: [-st] *) type rec: [integer: x; integer: y] entry (arg) := { diff --git a/tests/sprint2/test/sp2_library.alpha b/tests/sprint2/test/sp2_library.alpha index 82120be..d0c9d6c 100644 --- a/tests/sprint2/test/sp2_library.alpha +++ b/tests/sprint2/test/sp2_library.alpha @@ -1,3 +1,4 @@ +(* TEST: [-st] *) (* At compiler start-up your program should create symbol table entries for the four primitive types: Boolean (1 byte) diff --git a/tests/sprint2/test/sp2_llnode.alpha b/tests/sprint2/test/sp2_llnode.alpha index 3ecfb11..7367fb5 100644 --- a/tests/sprint2/test/sp2_llnode.alpha +++ b/tests/sprint2/test/sp2_llnode.alpha @@ -1,3 +1,4 @@ +(* TEST: [-st] *) type main: string -> integer function entry: main @@ -15,7 +16,6 @@ function make_list : list make_list (a) := { [integer:orig_a; llnode: ret; llnode: curr; llnode: temp] - if (a < 0 | a = 0) then { return null; } else { @@ -73,8 +73,8 @@ entry (arg) := { w := reserve w; w.x := 5; w.y := 7; - result := bar1(w); + (* result := bar1(w); *) result := bar2(5,7); return 0; -} \ No newline at end of file +} diff --git a/tests/sprint2/test/sp2_llnode_bad.alpha b/tests/sprint2/test/sp2_llnode_bad.alpha new file mode 100644 index 0000000..0862fa0 --- /dev/null +++ b/tests/sprint2/test/sp2_llnode_bad.alpha @@ -0,0 +1,81 @@ +(* TEST: [-st] *) +type main: string -> integer +function entry: main + +type rec: [integer: x; integer: y] +type T1: integer -> integer +type T2: rec -> integer + +type llnode: [llnode: prev; integer: val; llnode: next] +type list: integer -> llnode + +function foo : T1 +function bar1 : T2 +function bar2 : T2 +function make_list : list + +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,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; boolean: b] + li := make_list(6, 7); + result := foo(5); + w := reserve w; + w.x := 5; + w.y := 7; + result := bar1(w); + result := bar2(5,7); + + return 'a'; +} diff --git a/tests/sprint2/test/sp2_one_line.alpha b/tests/sprint2/test/sp2_one_line.alpha index f1062e9..5502979 100644 --- a/tests/sprint2/test/sp2_one_line.alpha +++ b/tests/sprint2/test/sp2_one_line.alpha @@ -1 +1,2 @@ +(* TEST: [-st] *) 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; } diff --git a/tests/sprint2/test/sp2_presidence.alpha b/tests/sprint2/test/sp2_presidence.alpha index d60611d..a81a5eb 100644 --- a/tests/sprint2/test/sp2_presidence.alpha +++ b/tests/sprint2/test/sp2_presidence.alpha @@ -1,3 +1,4 @@ +(* TEST: [-st] *) type main: string -> integer type rec: [integer: rec_x; integer: rec_y] diff --git a/tests/sprint2/test/sp2_simple.alpha b/tests/sprint2/test/sp2_simple.alpha index 4042a5a..bc56caf 100644 --- a/tests/sprint2/test/sp2_simple.alpha +++ b/tests/sprint2/test/sp2_simple.alpha @@ -1,3 +1,4 @@ +(* TEST: [-st] *) type main: string -> integer function entry: main diff --git a/tests/sprint2/test/sp2_sp2_arrayargs.alpha b/tests/sprint2/test/sp2_sp2_arrayargs.alpha index dfb0332..9ea2a1c 100644 --- a/tests/sprint2/test/sp2_sp2_arrayargs.alpha +++ b/tests/sprint2/test/sp2_sp2_arrayargs.alpha @@ -1,3 +1,4 @@ +(* TEST: [-st] *) type string: 1 -> character type a_of_s: 1 -> string diff --git a/tests/sprint2/test/sp2_sp2_arrayargs.alpha~ b/tests/sprint2/test/sp2_sp2_arrayargs.alpha~ deleted file mode 100644 index ce1673d..0000000 --- a/tests/sprint2/test/sp2_sp2_arrayargs.alpha~ +++ /dev/null @@ -1,16 +0,0 @@ -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; -} \ No newline at end of file diff --git a/tests/sprint2/test/sp2_valid_assignable_and_mem.alpha b/tests/sprint2/test/sp2_valid_assignable_and_mem.alpha index a49c5dd..3fc875e 100644 --- a/tests/sprint2/test/sp2_valid_assignable_and_mem.alpha +++ b/tests/sprint2/test/sp2_valid_assignable_and_mem.alpha @@ -1,3 +1,4 @@ +(* TEST: [-st] *) type main: string -> integer function entry: main diff --git a/tests/sprint3/expected/sp3_and_or_type_check.asc.exp b/tests/sprint3/expected/sp3_and_or_type_check.asc.exp new file mode 100644 index 0000000..304d268 --- /dev/null +++ b/tests/sprint3/expected/sp3_and_or_type_check.asc.exp @@ -0,0 +1,92 @@ +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; + LINE (8:9) ** TYPE ERROR: Assignable Assign Expression - Object undefined of type undefined != Object $t1 of type integer + LINE (8:9) ** TYPE ERROR: Invalid type passed to assignable. + LINE (8:3) ** TYPE ERROR: Undefined variable x +009: } +010: +011: while (7) { +012: x := 1; + LINE (12:9) ** TYPE ERROR: Assignable Assign Expression - Object undefined of type undefined != Object $t3 of type integer + LINE (12:9) ** TYPE ERROR: Invalid type passed to assignable. + LINE (12:3) ** TYPE ERROR: Undefined variable x +013: } +014: +015: if (true) then { +016: x := 1; + LINE (16:9) ** TYPE ERROR: Assignable Assign Expression - Object undefined of type undefined != Object $t5 of type integer + LINE (16:9) ** TYPE ERROR: Invalid type passed to assignable. + LINE (16:3) ** TYPE ERROR: Undefined variable x +017: } else { +018: x := 0; + LINE (18:9) ** TYPE ERROR: Assignable Assign Expression - Object undefined of type undefined != Object $t6 of type integer + LINE (18:9) ** TYPE ERROR: Invalid type passed to assignable. + LINE (18:3) ** TYPE ERROR: Undefined variable x +019: } +020: +021: if (x) then { + LINE (21:6) ** TYPE ERROR: Undefined variable x +022: x := 0; + LINE (22:9) ** TYPE ERROR: Assignable Assign Expression - Object undefined of type undefined != Object $t7 of type integer + LINE (22:9) ** TYPE ERROR: Invalid type passed to assignable. + LINE (22:3) ** TYPE ERROR: Undefined variable x +023: } else { +024: x := 1; + LINE (24:9) ** TYPE ERROR: Assignable Assign Expression - Object undefined of type undefined != Object $t8 of type integer + LINE (24:9) ** TYPE ERROR: Invalid type passed to assignable. + LINE (24:3) ** TYPE ERROR: Undefined variable x +025: } +026: +027: b := b | b; + LINE (27:12) ** TYPE ERROR: Invalid type passed to assignable. + LINE (27:12) ** TYPE ERROR: Object undefined of type undefined and Object undefined of type undefined must both be Boolean + LINE (27:11) ** TYPE ERROR: Undefined variable b + LINE (27:7) ** TYPE ERROR: Undefined variable b + LINE (27:2) ** TYPE ERROR: Undefined variable b +028: b := b & b; + LINE (28:12) ** TYPE ERROR: Invalid type passed to assignable. + LINE (28:12) ** TYPE ERROR: Object undefined of type undefined and Object undefined of type undefined must both be Boolean + LINE (28:11) ** TYPE ERROR: Undefined variable b + LINE (28:7) ** TYPE ERROR: Undefined variable b + LINE (28:2) ** TYPE ERROR: Undefined variable b +029: b := 1 | b; + LINE (29:12) ** TYPE ERROR: Invalid type passed to assignable. + LINE (29:12) ** TYPE ERROR: Object $t11 of type integer and Object undefined of type undefined must both be Boolean + LINE (29:11) ** TYPE ERROR: Undefined variable b + LINE (29:2) ** TYPE ERROR: Undefined variable b +030: b := b | 1; + LINE (30:12) ** TYPE ERROR: Invalid type passed to assignable. + LINE (30:12) ** TYPE ERROR: Object undefined of type undefined and Object $t13 of type integer must both be Boolean + LINE (30:7) ** TYPE ERROR: Undefined variable b + LINE (30:2) ** TYPE ERROR: Undefined variable b +031: b := b & 1; + LINE (31:12) ** TYPE ERROR: Invalid type passed to assignable. + LINE (31:12) ** TYPE ERROR: Object undefined of type undefined and Object $t15 of type integer must both be Boolean + LINE (31:7) ** TYPE ERROR: Undefined variable b + LINE (31:2) ** TYPE ERROR: Undefined variable b +032: b := 1 & b; + LINE (32:12) ** TYPE ERROR: Invalid type passed to assignable. + LINE (32:12) ** TYPE ERROR: Object $t17 of type integer and Object undefined of type undefined must both be Boolean + LINE (32:11) ** TYPE ERROR: Undefined variable b + LINE (32:2) ** TYPE ERROR: Undefined variable b +033: b := 1 = 1; + LINE (33:12) ** TYPE ERROR: Assignable Assign Expression - Object undefined of type undefined != Object $t21 of type Boolean + LINE (33:12) ** TYPE ERROR: Invalid type passed to assignable. + LINE (33:2) ** TYPE ERROR: Undefined variable b +034: +035: +036: +037: b := 1 = b; + LINE (37:12) ** TYPE ERROR: Invalid type passed to assignable. + LINE (37:12) ** TYPE ERROR: Object $t22 of type integer and Object undefined of type undefined must both be the same type + LINE (37:11) ** TYPE ERROR: Undefined variable b + LINE (37:2) ** TYPE ERROR: Undefined variable b +038: +039: return 0; +040: } diff --git a/tests/sprint3/expected/sp3_and_or_type_check.expected b/tests/sprint3/expected/sp3_and_or_type_check.expected deleted file mode 100644 index 493f53b..0000000 --- a/tests/sprint3/expected/sp3_and_or_type_check.expected +++ /dev/null @@ -1,50 +0,0 @@ -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: } diff --git a/tests/sprint3/expected/sp3_arr_reserve.asc.exp b/tests/sprint3/expected/sp3_arr_reserve.asc.exp new file mode 100644 index 0000000..cb1d755 --- /dev/null +++ b/tests/sprint3/expected/sp3_arr_reserve.asc.exp @@ -0,0 +1,10 @@ +001: type main: string -> integer +002: function entry: main +003: type t: 3 -> integer +004: +005: +006: entry (arg) := { +007: [ t:a] +008: a := reserve a(1, 3, 4); +009: return 0; +010: } diff --git a/tests/sprint3/expected/sp3_boolean_binary_op_typecheck.asc.exp b/tests/sprint3/expected/sp3_boolean_binary_op_typecheck.asc.exp new file mode 100644 index 0000000..fd029ac --- /dev/null +++ b/tests/sprint3/expected/sp3_boolean_binary_op_typecheck.asc.exp @@ -0,0 +1,17 @@ +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: Assignable Assign Expression - Object b1 of type Boolean != Object undefined of type undefined + LINE (8:18) ** TYPE ERROR: Object arr of type address and Object $t2 of type integer must both be the same type +009: b1 := 6<7 & arr2=7; + LINE (9:23) ** TYPE ERROR: Assignable Assign Expression - Object b1 of type Boolean != Object undefined of type undefined + LINE (9:23) ** TYPE ERROR: Object $t6 of type Boolean and Object undefined of type undefined must both be Boolean + LINE (9:23) ** TYPE ERROR: Object arr2 of type address and Object $t7 of type integer must both be the same type +010: +011: return 0; +012: } diff --git a/tests/sprint3/expected/sp3_boolean_binary_op_typecheck.expected b/tests/sprint3/expected/sp3_boolean_binary_op_typecheck.expected deleted file mode 100644 index f95e765..0000000 --- a/tests/sprint3/expected/sp3_boolean_binary_op_typecheck.expected +++ /dev/null @@ -1,16 +0,0 @@ -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: } diff --git a/tests/sprint3/expected/sp3_boolean_unary_op_typecheck.expected b/tests/sprint3/expected/sp3_boolean_unary_op_typecheck.asc.exp similarity index 52% rename from tests/sprint3/expected/sp3_boolean_unary_op_typecheck.expected rename to tests/sprint3/expected/sp3_boolean_unary_op_typecheck.asc.exp index 39237bc..181f3c4 100644 --- a/tests/sprint3/expected/sp3_boolean_unary_op_typecheck.expected +++ b/tests/sprint3/expected/sp3_boolean_unary_op_typecheck.asc.exp @@ -6,8 +6,8 @@ 006: 007: b2 := !(3 < 2); 008: b1 := !5; - LINE (8:13) ** TYPE ERROR: b1 != undefined - + LINE (8:13) ** TYPE ERROR: Assignable Assign Expression - Object b1 of type Boolean != Object undefined of type undefined + LINE (8:12) ** TYPE ERROR: Object $t4 of type integer is not of type Boolean and can't be negated 009: 010: return 0; 011: } diff --git a/tests/sprint3/expected/sp3_carls_second_mistake.asc.exp b/tests/sprint3/expected/sp3_carls_second_mistake.asc.exp new file mode 100644 index 0000000..c67a27b --- /dev/null +++ b/tests/sprint3/expected/sp3_carls_second_mistake.asc.exp @@ -0,0 +1,33 @@ +001: type main: string -> integer +002: function entry: main +003: +004: type string: 1 -> character +005: type a_of_s: 1 -> string +006: +007: (* maybe some other type definitions *) +008: +009: entry (arg) := { +010: [ string: one_name; string: another_name; a_of_s: many_names ] +011: +012: one_name := "a string literal"; +013: another_name := reserve another_name(4); (* reserve space for an an array of character, with 4 members *) +014: another_name(0) := 'C'; +015: another_name(1) := 'a'; +016: another_name(2) := 'r'; +017: another_name(3) := 'l'; +018: many_names := reserve many_names(3); +019: many_names(0) := one_name; +020: many_names(1) := another_name; +021: many_names(2) := reserve many_names(2)(6); (* reserve space for an item of the same type as a_of_s(2), an array of character, with 6 members *) + LINE (21:45) ** SYNTAX ERROR: Incorrect syntax at token ')' + LINE (21:44) ** SYNTAX ERROR: Incorrect syntax at token '6' + LINE (21:43) ** SYNTAX ERROR: Incorrect syntax at token '(' +022: many_names(2)(0) := 'P'; +023: many_names(2)(1) := 'a'; +024: many_names(2)(2) := 'r'; +025: many_names(2)(3) := 't'; +026: many_names(2)(4) := 'h'; +027: many_names(2)(5) := 'o'; +028: +029: return 0; +030: } \ No newline at end of file diff --git a/tests/sprint3/expected/sp3_carls_second_mistake.expected b/tests/sprint3/expected/sp3_carls_second_mistake.expected deleted file mode 100644 index 6f509e0..0000000 --- a/tests/sprint3/expected/sp3_carls_second_mistake.expected +++ /dev/null @@ -1,20 +0,0 @@ -NAME : SCOPE : PARENT : TYPE : EXTRA ANNOTATION : -------------------------------:--------:--------:-----------------------------------:-----------------------------------: -a_of_s : 001001 : : 1 -> string : Type of Array -string : 001001 : : 1 -> character : 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 -------------------------------:--------:--------:-----------------------------------:-----------------------------------: -many_names : 009000 : 001001 : a_of_s : Array Instance -another_name : 009000 : 001001 : string : Array Instance -one_name : 009000 : 001001 : string : Array Instance -arg : 009000 : 001001 : string : Array Instance diff --git a/tests/sprint3/expected/sp3_if_else.asc.exp b/tests/sprint3/expected/sp3_if_else.asc.exp new file mode 100644 index 0000000..0bd0f6d --- /dev/null +++ b/tests/sprint3/expected/sp3_if_else.asc.exp @@ -0,0 +1,22 @@ +001: type rec: [character: x; integer: y] +002: +003: type T2: rec -> integer +004: +005: type main: string -> integer +006: function entry: main +007: function bar: T2 +008: +009: bar (r,s) := { +010: return 0; +011: } +012: +013: entry (arg) := { +014: [ integer: r ; integer: s; Boolean: x] +015: (* x := (r < s) & x; *) +016: if ( ( r < s ) & (s = r) ) then { +017: r := 5; +018: } else { +019: r := 7; +020: } +021: return 0; +022: } diff --git a/tests/sprint3/expected/sp3_if_else_nested_exp.asc.exp b/tests/sprint3/expected/sp3_if_else_nested_exp.asc.exp new file mode 100644 index 0000000..1832760 --- /dev/null +++ b/tests/sprint3/expected/sp3_if_else_nested_exp.asc.exp @@ -0,0 +1,25 @@ +001: type rec: [character: x; integer: y] +002: +003: type T2: rec -> integer +004: +005: type main: string -> integer +006: function entry: main +007: function bar: T2 +008: +009: bar (r,s) := { +010: return 0; +011: } +012: +013: entry (arg) := { +014: [ integer: x ; integer: y; integer: z;integer: t] +015: +016: if ( (x = y) < ( z = t ) ) then { +017: if ( (x < y) = ( z < t ) ) then { +018: x := x; +019: } else { +020: x := 1; (* bar('c', 7); *) +021: } +022: } else { +023: return 0; +024: } +025: } diff --git a/tests/sprint3/expected/sp3_if_else_sse.asc.exp b/tests/sprint3/expected/sp3_if_else_sse.asc.exp new file mode 100644 index 0000000..5cb09f5 --- /dev/null +++ b/tests/sprint3/expected/sp3_if_else_sse.asc.exp @@ -0,0 +1,31 @@ +001: type rec: [character: x; integer: y] +002: +003: type T2: rec -> integer +004: +005: type main: string -> integer +006: function entry: main +007: function bar: T2 +008: +009: (* +010: bar (r,s) := { +011: return 0; +012: } +013: +014: *) +015: entry (arg) := { +016: [ Boolean:x ; Boolean:y ; Boolean:z ; Boolean:t] +017: if ( ( x & y ) ) then { +018: +019: (* +020: if ( x integer +004: +005: type main: string -> integer +006: function entry: main +007: function bar: T2 +008: +009: bar (r,s) := { +010: return 0; +011: } +012: +013: entry (arg) := { +014: [ Boolean:x ; Boolean:y ; Boolean:z ; Boolean:t] +015: (* if ( y & (z | t) ) then { *) +016: if ( ( x = y ) & ( z < t ) ) then { +017: (* y := z < t; *) +018: t:= 0; +019: } else { +020: (* t := z = t; *) +021: z := 1; +022: } +023: (* +024: if ( x & y ) then { +025: t := true; +026: } else { +027: y := true; +028: } +029: *) +030: (* } else { *) +031: (* } *) +032: (* x := x & y; *) +033: return 0; +034: } diff --git a/tests/sprint3/expected/sp3_if_while.asc.exp b/tests/sprint3/expected/sp3_if_while.asc.exp new file mode 100644 index 0000000..f071f8c --- /dev/null +++ b/tests/sprint3/expected/sp3_if_while.asc.exp @@ -0,0 +1,27 @@ +001: type rec: [character: x; integer: y] +002: +003: type T2: rec -> integer +004: +005: type main: string -> integer +006: function entry: main +007: function bar: T2 +008: +009: bar (r,s) := { +010: return 0; +011: } +012: +013: entry (arg) := { +014: [ integer: result ; rec: w] +015: while ( result = result ) { +016: result := result + 8; +017: if ( result < w.y ) then { +018: while (true) { +019: result := 8; +020: } +021: } else { +022: result := 9; +023: } +024: result := bar('c', 7); +025: } +026: return 0; +027: } diff --git a/tests/sprint3/expected/sp3_integer_binary_op_typecheck.asc.exp b/tests/sprint3/expected/sp3_integer_binary_op_typecheck.asc.exp new file mode 100644 index 0000000..bff4a30 --- /dev/null +++ b/tests/sprint3/expected/sp3_integer_binary_op_typecheck.asc.exp @@ -0,0 +1,28 @@ +001: type main: string -> integer +002: +003: type rec: [integer: x; integer: y] +004: function entry: main +005: +006: entry (arg) := { +007: [integer:x; address: arr; address: arr2; Boolean : b2; Boolean : b1; character : a; rec : r] +008: +009: x := 3 + 2 * 8; +010: x := 3 - 2 / 8; +011: x := a * 2 % 8; + LINE (11:20) ** TYPE ERROR: Assignable Assign Expression - Object x of type integer != Object undefined of type undefined + LINE (11:19) ** TYPE ERROR: Object undefined of type undefined and Object $t11 of type integer must both be integers + LINE (11:15) ** TYPE ERROR: Object a of type character and Object $t10 of type integer must both be integers +012: b2 := 3 * 2 % 8; +013: x := 3 % 2 * 8; +014: x := 3 + arr - 8; + LINE (14:22) ** TYPE ERROR: Assignable Assign Expression - Object x of type integer != Object undefined of type undefined + LINE (14:22) ** TYPE ERROR: Object undefined of type undefined and Object $t23 of type integer must both be integers + LINE (14:19) ** TYPE ERROR: Object $t22 of type integer and Object arr of type address must both be integers + LINE (14:19) ** TYPE ERROR: $t22 != arr +015: x := r.x; +016: x := a.x; + LINE (16:10) ** TYPE ERROR: Assignable Assign Expression - Object x of type integer != Object undefined of type undefined + LINE (16:9) ** TYPE ERROR: Invalid type passed to record access +017: +018: return 0; +019: } diff --git a/tests/sprint3/expected/sp3_integer_binary_op_typecheck.expected b/tests/sprint3/expected/sp3_integer_binary_op_typecheck.expected deleted file mode 100644 index 0b4c83f..0000000 --- a/tests/sprint3/expected/sp3_integer_binary_op_typecheck.expected +++ /dev/null @@ -1,25 +0,0 @@ -001: type main: string -> integer -002: -003: type rec: [integer: x; integer: y] -004: function entry: main -005: -006: entry (arg) := { -007: [integer:x; address: arr; address: arr2; Boolean : b2; Boolean : b1; character : a; rec : r] -008: -009: x := 3 + 2 * 8; -010: x := 3 - 2 / 8; -011: x := a * 2 % 8; - LINE (11:20) ** TYPE ERROR: x != undefined - -012: b2 := 3 * 2 % 8; -013: x := 3 % 2 * 8; -014: x := 3 + arr - 8; - LINE (14:22) ** TYPE ERROR: x != undefined - -015: x := r.x; - LINE (15:10) ** TYPE ERROR: x != r - -016: x := a.x; -017: -018: return 0; -019: } diff --git a/tests/sprint3/expected/sp3_integer_unary_op_typecheck.expected b/tests/sprint3/expected/sp3_integer_unary_op_typecheck.asc.exp similarity index 53% rename from tests/sprint3/expected/sp3_integer_unary_op_typecheck.expected rename to tests/sprint3/expected/sp3_integer_unary_op_typecheck.asc.exp index 18bd5a7..0ed98b5 100644 --- a/tests/sprint3/expected/sp3_integer_unary_op_typecheck.expected +++ b/tests/sprint3/expected/sp3_integer_unary_op_typecheck.asc.exp @@ -6,8 +6,8 @@ 006: 007: x := -8; 008: x := -b1; - LINE (8:10) ** TYPE ERROR: x != undefined - + LINE (8:10) ** TYPE ERROR: Assignable Assign Expression - Object x of type integer != Object undefined of type undefined + LINE (8:10) ** TYPE ERROR: Object b1 of type Boolean is not of type integer and can't be negated 009: b2 := -x; 010: 011: return 0; diff --git a/tests/sprint3/expected/sp3_multiple_args.asc.exp b/tests/sprint3/expected/sp3_multiple_args.asc.exp new file mode 100644 index 0000000..ffd92c2 --- /dev/null +++ b/tests/sprint3/expected/sp3_multiple_args.asc.exp @@ -0,0 +1,23 @@ +001: type rec: [character: x; integer: y] +002: +003: type T2: rec -> integer +004: +005: type main: string -> integer +006: function entry: main +007: function bar: T2 +008: +009: bar (r,s) := { +010: return 0; +011: } +012: +013: entry (arg) := { +014: [ integer: result ; rec: w] +015: while ( result = result ) { +016: while ( result < w.y ) { +017: result := 8; +018: } +019: result := 9; +020: } +021: result := bar('c', 7); +022: return 0; +023: } diff --git a/tests/sprint3/expected/sp3_multiple_args.expected b/tests/sprint3/expected/sp3_multiple_args.expected deleted file mode 100644 index c0128e1..0000000 --- a/tests/sprint3/expected/sp3_multiple_args.expected +++ /dev/null @@ -1,25 +0,0 @@ -NAME : SCOPE : PARENT : TYPE : EXTRA ANNOTATION : -------------------------------:--------:--------:-----------------------------------:-----------------------------------: -bar : 001001 : : undefined : Function Definition -entry : 001001 : : undefined : Function Definition -main : 001001 : : string -> integer : Type of Function -T2 : 001001 : : rec -> integer : Type of Function -rec : 001001 : : Record Type : elements-2 size-6 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 : 013000 : 001001 : rec : Record Instance -result : 013000 : 001001 : integer : Primitive Instance -arg : 013000 : 001001 : string : Array Instance -------------------------------:--------:--------:-----------------------------------:-----------------------------------: - : 009000 : 001001 : : Empty Scope -------------------------------:--------:--------:-----------------------------------:-----------------------------------: -y : 001000 : 001001 : integer : Primitive Instance -x : 001000 : 001001 : character : Primitive Instance diff --git a/tests/sprint3/expected/sp3_primitive_type_check.asc.exp b/tests/sprint3/expected/sp3_primitive_type_check.asc.exp new file mode 100644 index 0000000..7afd2a4 --- /dev/null +++ b/tests/sprint3/expected/sp3_primitive_type_check.asc.exp @@ -0,0 +1,23 @@ +001: (* +002: Testing the following type checks: +003: - integer : primitive +004: - character : primitive +005: - boolean : primitive +006: +007: - address (not included, special case) +008: *) +009: +010: +011: +012: type main: string -> integer +013: function entry: main +014: +015: entry (arg) := { +016: [integer: i; address: add; character: char; Boolean: bool] +017: +018: i := 3 + 2 * 8; +019: char := 'a'; +020: bool := true; +021: +022: return 0; +023: } diff --git a/tests/sprint3/expected/sp3_primitive_type_check.expected b/tests/sprint3/expected/sp3_primitive_type_check.expected deleted file mode 100644 index 0a57752..0000000 --- a/tests/sprint3/expected/sp3_primitive_type_check.expected +++ /dev/null @@ -1,19 +0,0 @@ -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 -------------------------------:--------:--------:-----------------------------------:-----------------------------------: -bool : 015000 : 001001 : Boolean : Primitive Instance -char : 015000 : 001001 : character : Primitive Instance -add : 015000 : 001001 : address : Primitive Instance -i : 015000 : 001001 : integer : Primitive Instance -arg : 015000 : 001001 : string : Array Instance diff --git a/tests/sprint3/expected/sp3_record_size_check.asc.exp b/tests/sprint3/expected/sp3_record_size_check.asc.exp new file mode 100644 index 0000000..2b5700c --- /dev/null +++ b/tests/sprint3/expected/sp3_record_size_check.asc.exp @@ -0,0 +1,3 @@ +001: type tom : [integer : x; integer: y] +002: type rec : [integer : x; tom : prev; character : c; character : d; Boolean: b; integer : y] +003: type tricky : [Boolean : b1; integer : k1; Boolean : b2; integer : k2] \ No newline at end of file diff --git a/tests/sprint3/expected/sp3_record_size_check.expected b/tests/sprint3/expected/sp3_record_size_check.expected deleted file mode 100644 index a061979..0000000 --- a/tests/sprint3/expected/sp3_record_size_check.expected +++ /dev/null @@ -1,29 +0,0 @@ -NAME : SCOPE : PARENT : TYPE : EXTRA ANNOTATION : -------------------------------:--------:--------:-----------------------------------:-----------------------------------: -tricky : 001001 : : Record Type : elements-4 size-16 bytes -rec : 001001 : : Record Type : elements-6 size-24 bytes -tom : 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 -------------------------------:--------:--------:-----------------------------------:-----------------------------------: -k2 : 003000 : 001001 : integer : Primitive Instance -b2 : 003000 : 001001 : Boolean : Primitive Instance -k1 : 003000 : 001001 : integer : Primitive Instance -b1 : 003000 : 001001 : Boolean : Primitive Instance -------------------------------:--------:--------:-----------------------------------:-----------------------------------: -y : 002000 : 001001 : integer : Primitive Instance -b : 002000 : 001001 : Boolean : Primitive Instance -d : 002000 : 001001 : character : Primitive Instance -c : 002000 : 001001 : character : Primitive Instance -prev : 002000 : 001001 : tom : Record Instance -x : 002000 : 001001 : integer : Primitive Instance -------------------------------:--------:--------:-----------------------------------:-----------------------------------: -y : 001000 : 001001 : integer : Primitive Instance -x : 001000 : 001001 : integer : Primitive Instance diff --git a/tests/sprint3/expected/sp3_while_nested_bools.asc.exp b/tests/sprint3/expected/sp3_while_nested_bools.asc.exp new file mode 100644 index 0000000..a3444d6 --- /dev/null +++ b/tests/sprint3/expected/sp3_while_nested_bools.asc.exp @@ -0,0 +1,29 @@ +001: type rec: [character: x; integer: y] +002: +003: type T2: rec -> integer +004: +005: type main: string -> integer +006: function entry: main +007: function bar: T2 +008: +009: bar (r,s) := { +010: return 0; +011: } +012: +013: entry (arg) := { +014: [ Boolean: x ; Boolean: y; Boolean: z;Boolean: t] +015: while ( ((x = y)) < ( z | t ) ) { +016: while ( (x & y) = ( z < t ) ) { +017: y := y; +018: } +019: (* +020: x := x; +021: *) +022: if ( (x = y) = ( z < t ) ) then { +023: x := 1; +024: } else { +025: x := 1; +026: } +027: } +028: return 0; +029: } diff --git a/tests/sprint3/expected/sp3_while_sse.asc.exp b/tests/sprint3/expected/sp3_while_sse.asc.exp new file mode 100644 index 0000000..fe8e2ae --- /dev/null +++ b/tests/sprint3/expected/sp3_while_sse.asc.exp @@ -0,0 +1,27 @@ +001: type rec: [character: x; integer: y] +002: +003: type T2: rec -> integer +004: +005: type main: string -> integer +006: function entry: main +007: function bar: T2 +008: +009: bar (r,s) := { +010: return 0; +011: } +012: +013: entry (arg) := { +014: [ Boolean:x ; Boolean:y ; Boolean:z ; Boolean:t] +015: while ( ( x | y ) (* | ( z | t ) *) ) { +016: (* +017: if ( ( x < y ) & ( z = t ) ) then { +018: y := z < t; +019: } else { +020: t := z = t; +021: } +022: *) +023: y := t < z; (* bar('c', 7); *) +024: } +025: (* x := x & y; *) +026: return 0; +027: } diff --git a/tests/sprint3/test/sp3_and_or_type_check.alpha b/tests/sprint3/test/sp3_and_or_type_check.alpha index c01fc10..63c9f62 100644 --- a/tests/sprint3/test/sp3_and_or_type_check.alpha +++ b/tests/sprint3/test/sp3_and_or_type_check.alpha @@ -1,3 +1,4 @@ +(* TEST: [-asc -tc] *) type rec: [integer: x; integer: y] type main: rec -> integer function test: main diff --git a/tests/sprint3/test/sp3_arr_reserve.alpha b/tests/sprint3/test/sp3_arr_reserve.alpha new file mode 100644 index 0000000..e78640f --- /dev/null +++ b/tests/sprint3/test/sp3_arr_reserve.alpha @@ -0,0 +1,11 @@ +(* TEST: [-asc -tc] *) +type main: string -> integer +function entry: main +type t: 3 -> integer + + +entry (arg) := { + [ t:a] + a := reserve a(1, 3, 4); + return 0; +} diff --git a/tests/sprint3/test/sp3_boolean_binary_op_typecheck.alpha b/tests/sprint3/test/sp3_boolean_binary_op_typecheck.alpha index 538d982..53ef65c 100644 --- a/tests/sprint3/test/sp3_boolean_binary_op_typecheck.alpha +++ b/tests/sprint3/test/sp3_boolean_binary_op_typecheck.alpha @@ -1,3 +1,4 @@ +(* TEST: [-asc -tc] *) type main: string -> integer function entry: main diff --git a/tests/sprint3/test/sp3_boolean_unary_op_typecheck.alpha b/tests/sprint3/test/sp3_boolean_unary_op_typecheck.alpha index 6a23ff6..d099993 100644 --- a/tests/sprint3/test/sp3_boolean_unary_op_typecheck.alpha +++ b/tests/sprint3/test/sp3_boolean_unary_op_typecheck.alpha @@ -1,3 +1,4 @@ +(* TEST: [-asc -tc] *) type main: string -> integer function entry: main diff --git a/tests/sprint3/test/sp3_carls_second_mistake.alpha b/tests/sprint3/test/sp3_carls_second_mistake.alpha index ddb58a4..652dc48 100644 --- a/tests/sprint3/test/sp3_carls_second_mistake.alpha +++ b/tests/sprint3/test/sp3_carls_second_mistake.alpha @@ -1,3 +1,4 @@ +(* TEST: [-asc -tc] *) type main: string -> integer function entry: main diff --git a/tests/sprint3/test/sp3_if_else.alpha b/tests/sprint3/test/sp3_if_else.alpha new file mode 100644 index 0000000..6825b77 --- /dev/null +++ b/tests/sprint3/test/sp3_if_else.alpha @@ -0,0 +1,23 @@ +(* TEST: [-asc -tc] *) +type rec: [character: x; integer: y] + +type T2: rec -> integer + +type main: string -> integer +function entry: main +function bar: T2 + +bar (r,s) := { + return 0; +} + +entry (arg) := { + [ integer: r ; integer: s; Boolean: x] + (* x := (r < s) & x; *) + if ( ( r < s ) & (s = r) ) then { + r := 5; + } else { + r := 7; + } + return 0; +} diff --git a/tests/sprint3/test/sp3_if_else_nested_exp.alpha b/tests/sprint3/test/sp3_if_else_nested_exp.alpha new file mode 100644 index 0000000..c89da43 --- /dev/null +++ b/tests/sprint3/test/sp3_if_else_nested_exp.alpha @@ -0,0 +1,26 @@ +(* TEST: [-asc -tc] *) +type rec: [character: x; integer: y] + +type T2: rec -> integer + +type main: string -> integer +function entry: main +function bar: T2 + +bar (r,s) := { + return 0; +} + +entry (arg) := { + [ integer: x ; integer: y; integer: z;integer: t] + + if ( (x = y) < ( z = t ) ) then { + if ( (x < y) = ( z < t ) ) then { + x := x; + } else { + x := 1; (* bar('c', 7); *) + } + } else { + return 0; + } +} diff --git a/tests/sprint3/test/sp3_if_else_sse.alpha b/tests/sprint3/test/sp3_if_else_sse.alpha new file mode 100644 index 0000000..8cb74e3 --- /dev/null +++ b/tests/sprint3/test/sp3_if_else_sse.alpha @@ -0,0 +1,32 @@ +(* TEST: [-asc -tc] *) +type rec: [character: x; integer: y] + +type T2: rec -> integer + +type main: string -> integer +function entry: main +function bar: T2 + + (* +bar (r,s) := { + return 0; +} + + *) +entry (arg) := { + [ Boolean:x ; Boolean:y ; Boolean:z ; Boolean:t] + if ( ( x & y ) ) then { + + (* + if ( x integer + +type main: string -> integer +function entry: main +function bar: T2 + +bar (r,s) := { + return 0; +} + +entry (arg) := { + [ Boolean:x ; Boolean:y ; Boolean:z ; Boolean:t] + (* if ( y & (z | t) ) then { *) + if ( ( x = y ) & ( z < t ) ) then { + (* y := z < t; *) + t:= 0; + } else { + (* t := z = t; *) + z := 1; + } + (* + if ( x & y ) then { + t := true; + } else { + y := true; + } + *) + (* } else { *) + (* } *) + (* x := x & y; *) + return 0; +} diff --git a/tests/sprint3/test/sp3_if_while.alpha b/tests/sprint3/test/sp3_if_while.alpha new file mode 100644 index 0000000..45300bc --- /dev/null +++ b/tests/sprint3/test/sp3_if_while.alpha @@ -0,0 +1,28 @@ +(* TEST: [-asc -tc] *) +type rec: [character: x; integer: y] + +type T2: rec -> integer + +type main: string -> integer +function entry: main +function bar: T2 + +bar (r,s) := { + return 0; +} + +entry (arg) := { + [ integer: result ; rec: w] + while ( result = result ) { + result := result + 8; + if ( result < w.y ) then { + while (true) { + result := 8; + } + } else { + result := 9; + } + result := bar('c', 7); + } + return 0; +} diff --git a/tests/sprint3/test/sp3_integer_binary_op_typecheck.alpha b/tests/sprint3/test/sp3_integer_binary_op_typecheck.alpha index 2adb394..71bb0e5 100644 --- a/tests/sprint3/test/sp3_integer_binary_op_typecheck.alpha +++ b/tests/sprint3/test/sp3_integer_binary_op_typecheck.alpha @@ -1,3 +1,4 @@ +(* TEST: [-asc -tc] *) type main: string -> integer type rec: [integer: x; integer: y] diff --git a/tests/sprint3/test/sp3_integer_unary_op_typecheck.alpha b/tests/sprint3/test/sp3_integer_unary_op_typecheck.alpha index 7ab6817..3469bb6 100644 --- a/tests/sprint3/test/sp3_integer_unary_op_typecheck.alpha +++ b/tests/sprint3/test/sp3_integer_unary_op_typecheck.alpha @@ -1,3 +1,4 @@ +(* TEST: [-asc -tc] *) type main: string -> integer function entry: main diff --git a/tests/sprint3/test/sp3_multiple_args.alpha b/tests/sprint3/test/sp3_multiple_args.alpha index 8475d92..6cd4144 100644 --- a/tests/sprint3/test/sp3_multiple_args.alpha +++ b/tests/sprint3/test/sp3_multiple_args.alpha @@ -1,3 +1,4 @@ +(* TEST: [-asc -tc] *) type rec: [character: x; integer: y] type T2: rec -> integer @@ -12,7 +13,12 @@ bar (r,s) := { entry (arg) := { [ integer: result ; rec: w] - result := bar(1,2); + while ( result = result ) { + while ( result < w.y ) { + result := 8; + } + result := 9; + } result := bar('c', 7); return 0; -} \ No newline at end of file +} diff --git a/tests/sprint3/test/sp3_primitive_type_check.alpha b/tests/sprint3/test/sp3_primitive_type_check.alpha index 6980aba..9a078ad 100644 --- a/tests/sprint3/test/sp3_primitive_type_check.alpha +++ b/tests/sprint3/test/sp3_primitive_type_check.alpha @@ -1,3 +1,4 @@ +(* TEST: [-asc -tc] *) (* Testing the following type checks: - integer : primitive diff --git a/tests/sprint3/test/sp3_record_size_check.alpha b/tests/sprint3/test/sp3_record_size_check.alpha index 8e123d0..d8526d5 100644 --- a/tests/sprint3/test/sp3_record_size_check.alpha +++ b/tests/sprint3/test/sp3_record_size_check.alpha @@ -1,3 +1,4 @@ +(* TEST: [-asc -tc] *) type tom : [integer : x; integer: y] type rec : [integer : x; tom : prev; character : c; character : d; Boolean: b; integer : y] type tricky : [Boolean : b1; integer : k1; Boolean : b2; integer : k2] \ No newline at end of file diff --git a/tests/sprint3/test/sp3_while_nested_bools.alpha b/tests/sprint3/test/sp3_while_nested_bools.alpha new file mode 100644 index 0000000..e9ac27e --- /dev/null +++ b/tests/sprint3/test/sp3_while_nested_bools.alpha @@ -0,0 +1,30 @@ +(* TEST: [-asc -tc] *) +type rec: [character: x; integer: y] + +type T2: rec -> integer + +type main: string -> integer +function entry: main +function bar: T2 + +bar (r,s) := { + return 0; +} + +entry (arg) := { + [ Boolean: x ; Boolean: y; Boolean: z;Boolean: t] + while ( ((x = y)) < ( z | t ) ) { + while ( (x & y) = ( z < t ) ) { + y := y; + } + (* + x := x; + *) + if ( (x = y) = ( z < t ) ) then { + x := 1; + } else { + x := 1; + } + } + return 0; +} diff --git a/tests/sprint3/test/sp3_while_sse.alpha b/tests/sprint3/test/sp3_while_sse.alpha new file mode 100644 index 0000000..58d8f6a --- /dev/null +++ b/tests/sprint3/test/sp3_while_sse.alpha @@ -0,0 +1,28 @@ +(* TEST: [-asc -tc] *) +type rec: [character: x; integer: y] + +type T2: rec -> integer + +type main: string -> integer +function entry: main +function bar: T2 + +bar (r,s) := { + return 0; +} + +entry (arg) := { + [ Boolean:x ; Boolean:y ; Boolean:z ; Boolean:t] + while ( ( x | y ) (* | ( z | t ) *) ) { + (* + if ( ( x < y ) & ( z = t ) ) then { + y := z < t; + } else { + t := z = t; + } + *) + y := t < z; (* bar('c', 7); *) + } + (* x := x & y; *) + return 0; +} diff --git a/tests/sprint4/expected/sp4_cg_add.asc.exp b/tests/sprint4/expected/sp4_cg_add.asc.exp new file mode 100644 index 0000000..d4499a0 --- /dev/null +++ b/tests/sprint4/expected/sp4_cg_add.asc.exp @@ -0,0 +1,47 @@ +001: +002: type string: 1 -> character +003: type BooleanXBoolean: [Boolean: x; Boolean: y] +004: type characterXcharacter: [character: x; character: y] +005: type integerXinteger: [integer: x; integer: y] +006: +007: type Boolean2Boolean: Boolean -> Boolean +008: type integer2integer: integer -> integer +009: type character2integer: character -> integer +010: type Boolean2integer: Boolean -> integer +011: type string2integer: string -> integer +012: type integerXinteger2integer: integerXinteger -> integer +013: type integerXinteger2Boolean: integerXinteger -> Boolean +014: type characterXcharacter2Boolean: characterXcharacter -> Boolean +015: type BooleanXBoolean2Boolean: BooleanXBoolean -> Boolean +016: type integer2address: integer -> address +017: type address2integer: address -> integer +018: type integer2string: integer -> string +019: type integer2character: integer -> character +020: type integer2Boolean: integer -> Boolean +021: +022: +023: external function printInteger: integer2integer +024: external function printCharacter: character2integer +025: external function printBoolean: Boolean2integer +026: +027: external function printS: string2integer +028: external function printI: integer2integer +029: external function printC: character2integer +030: external function printB: Boolean2integer +031: +032: external function inS: integer2string +033: external function inI: integer2integer +034: external function inC: integer2character +035: +036: function entry: string2integer +037: +038: entry (arg) := { +039: [integer:x; integer:y; integer: result] +040: +041: y := 1; +042: x := 3; +043: y := x + y; +044: +045: result := printInteger(y); +046: return y; +047: } \ No newline at end of file diff --git a/tests/sprint4/expected/sp4_cg_add.expected b/tests/sprint4/expected/sp4_cg_add.expected deleted file mode 100644 index 4764400..0000000 --- a/tests/sprint4/expected/sp4_cg_add.expected +++ /dev/null @@ -1,12 +0,0 @@ - movl $1, -4(%rbp) #constant assign - movl -4(%rbp), %eax #assign start - movl %eax, -8(%rbp) #assign end - movl $3, -12(%rbp) #constant assign - movl -12(%rbp), %eax #assign start - movl %eax, -16(%rbp) #assign end - movl -16(%rbp), %eax #addition start - movl -16(%rbp), %eax - addl %edx, %eax - movl %eax, -20(%rbp) #addition end - movl -20(%rbp), %eax #assign start - movl %eax, -8(%rbp) #assign end diff --git a/tests/sprint4/expected/sp4_cg_add.ir.exp b/tests/sprint4/expected/sp4_cg_add.ir.exp new file mode 100644 index 0000000..80451f3 --- /dev/null +++ b/tests/sprint4/expected/sp4_cg_add.ir.exp @@ -0,0 +1,12 @@ + 1: func_dec : entry + 2: func : entry + 3: $t0 = 1 + 4: y = $t0 + 5: $t1 = 3 + 6: x = $t1 + 7: $t2 = x + y + 8: y = $t2 + 9: param y + 10: call : printInteger 1 + 11: result = $t3 + 12: return : y diff --git a/tests/sprint4/expected/sp4_cg_add.s.exp b/tests/sprint4/expected/sp4_cg_add.s.exp new file mode 100644 index 0000000..c47a3d4 --- /dev/null +++ b/tests/sprint4/expected/sp4_cg_add.s.exp @@ -0,0 +1,26 @@ +.globl entry +entry: + pushq %rbp + movq %rsp, %rbp + subq $400, %rsp + movl %edi, -8(%rbp) #FunctionStart1param end + movl $1, -12(%rbp) #constant assign + movl -12(%rbp), %eax #assign start + movl %eax, -16(%rbp) #assign end + movl $3, -20(%rbp) #constant assign + movl -20(%rbp), %eax #assign start + movl %eax, -24(%rbp) #assign end + + movl -24(%rbp), %eax #addition start + addl -16(%rbp), %eax + movl %eax, -28(%rbp) #addition end + movl -28(%rbp), %eax #assign start + movl %eax, -16(%rbp) #assign end + movl -16(%rbp), %edi #adding param start + call printInteger + movl %eax, -32(%rbp) #store return from call + movl -32(%rbp), %eax #assign start + movl %eax, -36(%rbp) #assign end + movl -16(%rbp), %eax #return y + leave + ret diff --git a/tests/sprint4/expected/sp4_cg_and.asc.exp b/tests/sprint4/expected/sp4_cg_and.asc.exp new file mode 100644 index 0000000..17aa547 --- /dev/null +++ b/tests/sprint4/expected/sp4_cg_and.asc.exp @@ -0,0 +1,50 @@ +001: +002: type string: 1 -> character +003: type BooleanXBoolean: [Boolean: x; Boolean: y] +004: type characterXcharacter: [character: x; character: y] +005: type integerXinteger: [integer: x; integer: y] +006: +007: type Boolean2Boolean: Boolean -> Boolean +008: type integer2integer: integer -> integer +009: type character2integer: character -> integer +010: type Boolean2integer: Boolean -> integer +011: type string2integer: string -> integer +012: type integerXinteger2integer: integerXinteger -> integer +013: type integerXinteger2Boolean: integerXinteger -> Boolean +014: type characterXcharacter2Boolean: characterXcharacter -> Boolean +015: type BooleanXBoolean2Boolean: BooleanXBoolean -> Boolean +016: type integer2address: integer -> address +017: type address2integer: address -> integer +018: type integer2string: integer -> string +019: type integer2character: integer -> character +020: type integer2Boolean: integer -> Boolean +021: +022: +023: external function printInteger: integer2integer +024: external function printCharacter: character2integer +025: external function printBoolean: Boolean2integer +026: +027: external function printS: string2integer +028: external function printI: integer2integer +029: external function printC: character2integer +030: external function printB: Boolean2integer +031: +032: external function inS: integer2string +033: external function inI: integer2integer +034: external function inC: integer2character +035: +036: function entry: string2integer +037: +038: entry (arg) := { +039: [Boolean:b; Boolean: c; Boolean: d; integer: result] +040: +041: z := true; + LINE (41:14) ** TYPE ERROR: Assignable Assign Expression - Object undefined of type undefined != Object $t0 of type Boolean + LINE (41:14) ** TYPE ERROR: Invalid type passed to assignable. + LINE (41:5) ** TYPE ERROR: Undefined variable z +042: d := false; +043: d := c & d; +044: +045: result := printBoolean(d); +046: return 1; +047: } \ No newline at end of file diff --git a/tests/sprint4/expected/sp4_cg_and.expected b/tests/sprint4/expected/sp4_cg_and.expected deleted file mode 100644 index be6a53e..0000000 --- a/tests/sprint4/expected/sp4_cg_and.expected +++ /dev/null @@ -1,20 +0,0 @@ - movl $-1, -4(%rbp) #constant assign - movl -4(%rbp), %eax #assign start - movl %eax, -8(%rbp) #assign end - movl $-1, -12(%rbp) #constant assign - movl -12(%rbp), %eax #assign start - movl %eax, -16(%rbp) #assign end - cmpl $0, -8(%rbp) #start and - je .L1or2 - cmpl $0, -16(%rbp) - je .L1or2 - movl $1, %eax - jmp .L1or3 -.L1or2: - movl $0, %eax -.L1or3: - movb %al, -20(%rbp) - andb $1, -20(%rbp) #and end - movl -20(%rbp), %eax #assign start - movl %eax, -16(%rbp) #assign end - movl $1, -24(%rbp) #constant assign diff --git a/tests/sprint4/expected/sp4_cg_and.ir.exp b/tests/sprint4/expected/sp4_cg_and.ir.exp new file mode 100644 index 0000000..462a6ad --- /dev/null +++ b/tests/sprint4/expected/sp4_cg_and.ir.exp @@ -0,0 +1,9 @@ + 1: func : test + 2: $t0 = true + 3: c = $t0 + 4: $t1 = false + 5: d = $t1 + 6: $t2 = c & d + 7: d = $t2 + 8: $t3 = 1 + 9: return : $t3 diff --git a/tests/sprint4/expected/sp4_cg_and.s.exp b/tests/sprint4/expected/sp4_cg_and.s.exp new file mode 100644 index 0000000..0a3128d --- /dev/null +++ b/tests/sprint4/expected/sp4_cg_and.s.exp @@ -0,0 +1,20 @@ + movl $-1, -1(%rbp) #constant assign + movl -1(%rbp), %eax #assign start + movl %eax, -2(%rbp) #assign end + movl $-1, -3(%rbp) #constant assign + movl -3(%rbp), %eax #assign start + movl %eax, -4(%rbp) #assign end + cmpl $0, -2(%rbp) #start and + je .L1or2 + cmpl $0, -4(%rbp) + je .L1or2 + movl $1, %eax + jmp .L1or3 +.L1or2: + movl $0, %eax +.L1or3: + movb %al, -5(%rbp) + andb $1, -5(%rbp) #and end + movl -5(%rbp), %eax #assign start + movl %eax, -4(%rbp) #assign end + movl $1, -9(%rbp) #constant assign diff --git a/tests/sprint4/expected/sp4_cg_calls.asc.exp b/tests/sprint4/expected/sp4_cg_calls.asc.exp new file mode 100644 index 0000000..831976b --- /dev/null +++ b/tests/sprint4/expected/sp4_cg_calls.asc.exp @@ -0,0 +1,60 @@ +001: +002: type string: 1 -> character +003: type BooleanXBoolean: [Boolean: x; Boolean: y] +004: type characterXcharacter: [character: x; character: y] +005: type integerXinteger: [integer: x; integer: y] +006: +007: type Boolean2Boolean: Boolean -> Boolean +008: type integer2integer: integer -> integer +009: type character2integer: character -> integer +010: type Boolean2integer: Boolean -> integer +011: type string2integer: string -> integer +012: type integerXinteger2integer: integerXinteger -> integer +013: type integerXinteger2Boolean: integerXinteger -> Boolean +014: type characterXcharacter2Boolean: characterXcharacter -> Boolean +015: type BooleanXBoolean2Boolean: BooleanXBoolean -> Boolean +016: type integer2address: integer -> address +017: type address2integer: address -> integer +018: type integer2string: integer -> string +019: type integer2character: integer -> character +020: type integer2Boolean: integer -> Boolean +021: +022: +023: external function printInteger: integer2integer +024: external function printCharacter: character2integer +025: external function printBoolean: Boolean2integer +026: +027: external function printS: string2integer +028: external function printI: integer2integer +029: external function printC: character2integer +030: external function printB: Boolean2integer +031: +032: external function inS: integer2string +033: external function inI: integer2integer +034: external function inC: integer2character +035: +036: function entry: string2integer +037: +038: type rec: [integer: x; integer: y; integer: z; integer: a; integer: b; integer: c; integer: d] +039: type T2: rec -> integer +040: type T: integer -> integer +041: function bar: T2 +042: function ahh: T +043: +044: ahh (a) := { +045: a := printInteger(a); +046: return -1; +047: } +048: +049: bar (a, b, c,d,e,f,g) := { +050: a := printInteger(g); +051: return b; +052: } +053: +054: entry (arg) := { +055: [integer:x; integer:y; integer: result; character: a] +056: a := 'a'; +057: x := printCharacter(a); +058: result := bar(1,2,3,4,5,6,7); +059: return 1; +060: } diff --git a/tests/sprint4/expected/sp4_cg_calls.ir.exp b/tests/sprint4/expected/sp4_cg_calls.ir.exp new file mode 100644 index 0000000..cbaa89e --- /dev/null +++ b/tests/sprint4/expected/sp4_cg_calls.ir.exp @@ -0,0 +1,39 @@ + 1: func_dec : entry + 2: func_dec : bar + 3: func_dec : ahh + 4: func : ahh + 5: param a + 6: call : printInteger 1 + 7: a = $t0 + 8: $t1 = 1 + 9: $t2 = -$t1 + 10: return : $t2 + 11: func : bar + 12: param g + 13: call : printInteger 1 + 14: a = $t3 + 15: return : b + 16: func : entry + 17: $t4 = a + 18: a = $t4 + 19: param a + 20: call : printCharacter 1 + 21: x = $t5 + 22: $t6 = 1 + 23: $t7 = 2 + 24: $t8 = 3 + 25: $t9 = 4 + 26: $t10 = 5 + 27: $t11 = 6 + 28: $t12 = 7 + 29: param $t12 + 30: param $t11 + 31: param $t10 + 32: param $t9 + 33: param $t8 + 34: param $t7 + 35: param $t6 + 36: call : bar 7 + 37: result = $t13 + 38: $t14 = 1 + 39: return : $t14 diff --git a/tests/sprint4/expected/sp4_cg_calls.s.exp b/tests/sprint4/expected/sp4_cg_calls.s.exp new file mode 100644 index 0000000..0d28c99 --- /dev/null +++ b/tests/sprint4/expected/sp4_cg_calls.s.exp @@ -0,0 +1,74 @@ +.globl entry +ahh: + pushq %rbp + movq %rsp, %rbp + subq $576, %rsp + movl %edi, -4(%rbp) #FunctionStart1param end + movl -4(%rbp), %edi #adding param start + call printInteger + movl %eax, -8(%rbp) #store return from call + movl -8(%rbp), %eax #assign start + movl %eax, -4(%rbp) #assign end + movl $1, -12(%rbp) #constant assign + movl -12(%rbp), %eax #negation start + negl %eax + movl %eax, -16(%rbp) #negation end + movl -16(%rbp), %eax #return $t2 + leave + ret +bar: + pushq %rbp + movq %rsp, %rbp + subq $576, %rsp + movl 20(%rbp), %eax #FunctionStart1Param start + movl %eax, -4(%rbp) #FunctionStart1param end + movl %r9d, -12(%rbp) #FunctionStart1param end + movl %r8d, -16(%rbp) #FunctionStart1param end + movl %ecx, -20(%rbp) #FunctionStart1param end + movl %edx, -24(%rbp) #FunctionStart1param end + movl %esi, -28(%rbp) #FunctionStart1param end + movl %edi, -32(%rbp) #FunctionStart1param end + movl -32(%rbp), %edi #adding param start + call printInteger + movl %eax, -36(%rbp) #store return from call + movl -36(%rbp), %eax #assign start + movl %eax, -4(%rbp) #assign end + movl -12(%rbp), %eax #return b + leave + ret +entry: + pushq %rbp + movq %rsp, %rbp + subq $576, %rsp + movl %edi, -12(%rbp) #FunctionStart1param end + movl $97, -13(%rbp) #constant assign + movl -13(%rbp), %eax #assign start + movl %eax, -14(%rbp) #assign end + movl -14(%rbp), %edi #adding param start + call printCharacter + movl %eax, -20(%rbp) #store return from call + movl -20(%rbp), %eax #assign start + movl %eax, -24(%rbp) #assign end + movl $1, -28(%rbp) #constant assign + movl $2, -32(%rbp) #constant assign + movl $3, -36(%rbp) #constant assign + movl $4, -40(%rbp) #constant assign + movl $5, -44(%rbp) #constant assign + movl $6, -48(%rbp) #constant assign + movl $7, -52(%rbp) #constant assign + movl -52(%rbp), %edi #adding param start + movl -48(%rbp), %esi #adding param start + movl -44(%rbp), %edx #adding param start + movl -40(%rbp), %ecx #adding param start + movl -36(%rbp), %r8d #adding param start + movl -32(%rbp), %r9d #adding param start + movl -28(%rbp), %eax #adding param start + movl %eax, 152(%rbp) #adding param end + call bar + movl %eax, -60(%rbp) #store return from call + movl -60(%rbp), %eax #assign start + movl %eax, -64(%rbp) #assign end + movl $1, -68(%rbp) #constant assign + movl -68(%rbp), %eax #return $t14 + leave + ret diff --git a/tests/sprint4/expected/sp4_cg_div.asc.exp b/tests/sprint4/expected/sp4_cg_div.asc.exp new file mode 100644 index 0000000..5e0a832 --- /dev/null +++ b/tests/sprint4/expected/sp4_cg_div.asc.exp @@ -0,0 +1,47 @@ +001: +002: type string: 1 -> character +003: type BooleanXBoolean: [Boolean: x; Boolean: y] +004: type characterXcharacter: [character: x; character: y] +005: type integerXinteger: [integer: x; integer: y] +006: +007: type Boolean2Boolean: Boolean -> Boolean +008: type integer2integer: integer -> integer +009: type character2integer: character -> integer +010: type Boolean2integer: Boolean -> integer +011: type string2integer: string -> integer +012: type integerXinteger2integer: integerXinteger -> integer +013: type integerXinteger2Boolean: integerXinteger -> Boolean +014: type characterXcharacter2Boolean: characterXcharacter -> Boolean +015: type BooleanXBoolean2Boolean: BooleanXBoolean -> Boolean +016: type integer2address: integer -> address +017: type address2integer: address -> integer +018: type integer2string: integer -> string +019: type integer2character: integer -> character +020: type integer2Boolean: integer -> Boolean +021: +022: +023: external function printInteger: integer2integer +024: external function printCharacter: character2integer +025: external function printBoolean: Boolean2integer +026: +027: external function printS: string2integer +028: external function printI: integer2integer +029: external function printC: character2integer +030: external function printB: Boolean2integer +031: +032: external function inS: integer2string +033: external function inI: integer2integer +034: external function inC: integer2character +035: +036: function entry: string2integer +037: +038: entry (arg) := { +039: [integer:x; integer:y; integer: result] +040: +041: x := 24; +042: y := 3; +043: y := x / y; +044: +045: result := printInteger(y); +046: return y; +047: } \ No newline at end of file diff --git a/tests/sprint4/expected/sp4_cg_div.expected b/tests/sprint4/expected/sp4_cg_div.expected deleted file mode 100644 index 1a71c6e..0000000 --- a/tests/sprint4/expected/sp4_cg_div.expected +++ /dev/null @@ -1,12 +0,0 @@ - movl $1, -4(%rbp) #constant assign - movl -4(%rbp), %eax #assign start - movl %eax, -8(%rbp) #assign end - movl $3, -12(%rbp) #constant assign - movl -12(%rbp), %eax #assign start - movl %eax, -16(%rbp) #assign end - movl -16(%rbp), %eax #division start - cltd - idivl -8(%rbp) - movl %eax, -20(%rbp) #division end - movl -20(%rbp), %eax #assign start - movl %eax, -8(%rbp) #assign end diff --git a/tests/sprint4/expected/sp4_cg_div.ir.exp b/tests/sprint4/expected/sp4_cg_div.ir.exp new file mode 100644 index 0000000..56f58fd --- /dev/null +++ b/tests/sprint4/expected/sp4_cg_div.ir.exp @@ -0,0 +1,12 @@ + 1: func_dec : entry + 2: func : entry + 3: $t0 = 24 + 4: x = $t0 + 5: $t1 = 3 + 6: y = $t1 + 7: $t2 = x / y + 8: y = $t2 + 9: param y + 10: call : printInteger 1 + 11: result = $t3 + 12: return : y diff --git a/tests/sprint4/expected/sp4_cg_div.s.exp b/tests/sprint4/expected/sp4_cg_div.s.exp new file mode 100644 index 0000000..53861da --- /dev/null +++ b/tests/sprint4/expected/sp4_cg_div.s.exp @@ -0,0 +1,26 @@ +.globl entry +entry: + pushq %rbp + movq %rsp, %rbp + subq $400, %rsp + movl %edi, -8(%rbp) #FunctionStart1param end + movl $24, -12(%rbp) #constant assign + movl -12(%rbp), %eax #assign start + movl %eax, -16(%rbp) #assign end + movl $3, -20(%rbp) #constant assign + movl -20(%rbp), %eax #assign start + movl %eax, -24(%rbp) #assign end + movl -16(%rbp), %eax #division start + cltd + idivl -24(%rbp) + movl %eax, -28(%rbp) #division end + movl -28(%rbp), %eax #assign start + movl %eax, -24(%rbp) #assign end + movl -24(%rbp), %edi #adding param start + call printInteger + movl %eax, -32(%rbp) #store return from call + movl -32(%rbp), %eax #assign start + movl %eax, -36(%rbp) #assign end + movl -24(%rbp), %eax #return y + leave + ret diff --git a/tests/sprint4/expected/sp4_cg_equal_to.asc.exp b/tests/sprint4/expected/sp4_cg_equal_to.asc.exp new file mode 100644 index 0000000..d43e036 --- /dev/null +++ b/tests/sprint4/expected/sp4_cg_equal_to.asc.exp @@ -0,0 +1,47 @@ +001: +002: type string: 1 -> character +003: type BooleanXBoolean: [Boolean: x; Boolean: y] +004: type characterXcharacter: [character: x; character: y] +005: type integerXinteger: [integer: x; integer: y] +006: +007: type Boolean2Boolean: Boolean -> Boolean +008: type integer2integer: integer -> integer +009: type character2integer: character -> integer +010: type Boolean2integer: Boolean -> integer +011: type string2integer: string -> integer +012: type integerXinteger2integer: integerXinteger -> integer +013: type integerXinteger2Boolean: integerXinteger -> Boolean +014: type characterXcharacter2Boolean: characterXcharacter -> Boolean +015: type BooleanXBoolean2Boolean: BooleanXBoolean -> Boolean +016: type integer2address: integer -> address +017: type address2integer: address -> integer +018: type integer2string: integer -> string +019: type integer2character: integer -> character +020: type integer2Boolean: integer -> Boolean +021: +022: +023: external function printInteger: integer2integer +024: external function printCharacter: character2integer +025: external function printBoolean: Boolean2integer +026: +027: external function printS: string2integer +028: external function printI: integer2integer +029: external function printC: character2integer +030: external function printB: Boolean2integer +031: +032: external function inS: integer2string +033: external function inI: integer2integer +034: external function inC: integer2character +035: +036: function entry: string2integer +037: +038: entry (arg) := { +039: [Boolean: b; integer: x; integer: y; integer: result] +040: +041: x := 1; +042: y := 2; +043: b := x = y; +044: +045: result := printBoolean(b); +046: return 1; +047: } \ No newline at end of file diff --git a/tests/sprint4/expected/sp4_cg_equal_to.expected b/tests/sprint4/expected/sp4_cg_equal_to.expected deleted file mode 100644 index e29c6c1..0000000 --- a/tests/sprint4/expected/sp4_cg_equal_to.expected +++ /dev/null @@ -1,13 +0,0 @@ - movl $1, -4(%rbp) #constant assign - movl -4(%rbp), %eax #assign start - movl %eax, -8(%rbp) #assign end - movl $2, -12(%rbp) #constant assign - movl -12(%rbp), %eax #assign start - movl %eax, -16(%rbp) #assign end - movl -8(%rbp), %eax #equal to start - cmpl -16(%rbp), %eax - sete %al - movb %al, -20(%rbp) #equal to end - movl -20(%rbp), %eax #assign start - movl %eax, -24(%rbp) #assign end - movl $1, -28(%rbp) #constant assign diff --git a/tests/sprint4/expected/sp4_cg_equal_to.ir.exp b/tests/sprint4/expected/sp4_cg_equal_to.ir.exp new file mode 100644 index 0000000..c8ec780 --- /dev/null +++ b/tests/sprint4/expected/sp4_cg_equal_to.ir.exp @@ -0,0 +1,16 @@ + 1: func_dec : entry + 2: func : entry + 3: $t0 = 1 + 4: x = $t0 + 5: $t1 = 2 + 6: y = $t1 + 7: $t2 = x == y + 8: if $t2 True GOTO 1 + 9: GOTO : 1 + 10: Label : 1 + 11: b = $t2 + 12: param b + 13: call : printBoolean 1 + 14: result = $t3 + 15: $t4 = 1 + 16: return : $t4 diff --git a/tests/sprint4/expected/sp4_cg_equal_to.s.exp b/tests/sprint4/expected/sp4_cg_equal_to.s.exp new file mode 100644 index 0000000..038d473 --- /dev/null +++ b/tests/sprint4/expected/sp4_cg_equal_to.s.exp @@ -0,0 +1,32 @@ +.globl entry +entry: + pushq %rbp + movq %rsp, %rbp + subq $416, %rsp + movl %edi, -8(%rbp) #FunctionStart1param end + movl $1, -12(%rbp) #constant assign + movl -12(%rbp), %eax #assign start + movl %eax, -16(%rbp) #assign end + movl $2, -20(%rbp) #constant assign + movl -20(%rbp), %eax #assign start + movl %eax, -24(%rbp) #assign end + movl -16(%rbp), %eax #equal to start + cmpl -24(%rbp), %eax + sete %al + movb $0, -25(%rbp) + movb %al, -25(%rbp) #equal to end + cmpb $0, -25(%rbp) #if true start + jne .L1 #if true end + jmp .L1 +.L1: + movl -25(%rbp), %eax #assign start + movl %eax, -26(%rbp) #assign end + movl -26(%rbp), %edi #adding param start + call printBoolean + movl %eax, -32(%rbp) #store return from call + movl -32(%rbp), %eax #assign start + movl %eax, -36(%rbp) #assign end + movl $1, -40(%rbp) #constant assign + movl -40(%rbp), %eax #return $t4 + leave + ret diff --git a/tests/sprint4/expected/sp4_cg_less_than.asc.exp b/tests/sprint4/expected/sp4_cg_less_than.asc.exp new file mode 100644 index 0000000..ab65623 --- /dev/null +++ b/tests/sprint4/expected/sp4_cg_less_than.asc.exp @@ -0,0 +1,47 @@ +001: +002: type string: 1 -> character +003: type BooleanXBoolean: [Boolean: x; Boolean: y] +004: type characterXcharacter: [character: x; character: y] +005: type integerXinteger: [integer: x; integer: y] +006: +007: type Boolean2Boolean: Boolean -> Boolean +008: type integer2integer: integer -> integer +009: type character2integer: character -> integer +010: type Boolean2integer: Boolean -> integer +011: type string2integer: string -> integer +012: type integerXinteger2integer: integerXinteger -> integer +013: type integerXinteger2Boolean: integerXinteger -> Boolean +014: type characterXcharacter2Boolean: characterXcharacter -> Boolean +015: type BooleanXBoolean2Boolean: BooleanXBoolean -> Boolean +016: type integer2address: integer -> address +017: type address2integer: address -> integer +018: type integer2string: integer -> string +019: type integer2character: integer -> character +020: type integer2Boolean: integer -> Boolean +021: +022: +023: external function printInteger: integer2integer +024: external function printCharacter: character2integer +025: external function printBoolean: Boolean2integer +026: +027: external function printS: string2integer +028: external function printI: integer2integer +029: external function printC: character2integer +030: external function printB: Boolean2integer +031: +032: external function inS: integer2string +033: external function inI: integer2integer +034: external function inC: integer2character +035: +036: function entry: string2integer +037: +038: entry (arg) := { +039: [Boolean: b; integer: x; integer: y; integer: result] +040: +041: x := 1; +042: y := 2; +043: b := x < y; +044: +045: result := printBoolean(b); +046: return 1; +047: } diff --git a/tests/sprint4/expected/sp4_cg_less_than.expected b/tests/sprint4/expected/sp4_cg_less_than.expected deleted file mode 100644 index b8d8904..0000000 --- a/tests/sprint4/expected/sp4_cg_less_than.expected +++ /dev/null @@ -1,13 +0,0 @@ - movl $1, -4(%rbp) #constant assign - movl -4(%rbp), %eax #assign start - movl %eax, -8(%rbp) #assign end - movl $2, -12(%rbp) #constant assign - movl -12(%rbp), %eax #assign start - movl %eax, -16(%rbp) #assign end - movl -8(%rbp), %eax #less than start - cmpl -16(%rbp), %eax - setl %al - movb %al, -20(%rbp) #less than end - movl -20(%rbp), %eax #assign start - movl %eax, -24(%rbp) #assign end - movl $1, -28(%rbp) #constant assign diff --git a/tests/sprint4/expected/sp4_cg_less_than.ir.exp b/tests/sprint4/expected/sp4_cg_less_than.ir.exp new file mode 100644 index 0000000..ff83dbc --- /dev/null +++ b/tests/sprint4/expected/sp4_cg_less_than.ir.exp @@ -0,0 +1,16 @@ + 1: func_dec : entry + 2: func : entry + 3: $t0 = 1 + 4: x = $t0 + 5: $t1 = 2 + 6: y = $t1 + 7: $t2 = x < y + 8: if $t2 True GOTO 1 + 9: GOTO : 1 + 10: Label : 1 + 11: b = $t2 + 12: param b + 13: call : printBoolean 1 + 14: result = $t3 + 15: $t4 = 1 + 16: return : $t4 diff --git a/tests/sprint4/expected/sp4_cg_less_than.s.exp b/tests/sprint4/expected/sp4_cg_less_than.s.exp new file mode 100644 index 0000000..a9235cd --- /dev/null +++ b/tests/sprint4/expected/sp4_cg_less_than.s.exp @@ -0,0 +1,31 @@ +.globl entry +entry: + pushq %rbp + movq %rsp, %rbp + subq $416, %rsp + movl %edi, -8(%rbp) #FunctionStart1param end + movl $1, -12(%rbp) #constant assign + movl -12(%rbp), %eax #assign start + movl %eax, -16(%rbp) #assign end + movl $2, -20(%rbp) #constant assign + movl -20(%rbp), %eax #assign start + movl %eax, -24(%rbp) #assign end + movl -16(%rbp), %eax #less than start + cmpl -24(%rbp), %eax + setl %al + movb %al, -25(%rbp) #less than end + cmpb $0, -25(%rbp) #if true start + jne .L1 #if true end + jmp .L1 +.L1: + movl -25(%rbp), %eax #assign start + movl %eax, -26(%rbp) #assign end + movl -26(%rbp), %edi #adding param start + call printBoolean + movl %eax, -32(%rbp) #store return from call + movl -32(%rbp), %eax #assign start + movl %eax, -36(%rbp) #assign end + movl $1, -40(%rbp) #constant assign + movl -40(%rbp), %eax #return $t4 + leave + ret diff --git a/tests/sprint4/expected/sp4_cg_mod.asc.exp b/tests/sprint4/expected/sp4_cg_mod.asc.exp new file mode 100644 index 0000000..3edad31 --- /dev/null +++ b/tests/sprint4/expected/sp4_cg_mod.asc.exp @@ -0,0 +1,47 @@ +001: +002: type string: 1 -> character +003: type BooleanXBoolean: [Boolean: x; Boolean: y] +004: type characterXcharacter: [character: x; character: y] +005: type integerXinteger: [integer: x; integer: y] +006: +007: type Boolean2Boolean: Boolean -> Boolean +008: type integer2integer: integer -> integer +009: type character2integer: character -> integer +010: type Boolean2integer: Boolean -> integer +011: type string2integer: string -> integer +012: type integerXinteger2integer: integerXinteger -> integer +013: type integerXinteger2Boolean: integerXinteger -> Boolean +014: type characterXcharacter2Boolean: characterXcharacter -> Boolean +015: type BooleanXBoolean2Boolean: BooleanXBoolean -> Boolean +016: type integer2address: integer -> address +017: type address2integer: address -> integer +018: type integer2string: integer -> string +019: type integer2character: integer -> character +020: type integer2Boolean: integer -> Boolean +021: +022: +023: external function printInteger: integer2integer +024: external function printCharacter: character2integer +025: external function printBoolean: Boolean2integer +026: +027: external function printS: string2integer +028: external function printI: integer2integer +029: external function printC: character2integer +030: external function printB: Boolean2integer +031: +032: external function inS: integer2string +033: external function inI: integer2integer +034: external function inC: integer2character +035: +036: function entry: string2integer +037: +038: entry (arg) := { +039: [integer:x; integer:y; integer: result] +040: +041: x := 4; +042: y := 20; +043: y := y % x; +044: +045: result := printInteger(y); +046: return y; +047: } \ No newline at end of file diff --git a/tests/sprint4/expected/sp4_cg_mod.expected b/tests/sprint4/expected/sp4_cg_mod.expected deleted file mode 100644 index 97d4259..0000000 --- a/tests/sprint4/expected/sp4_cg_mod.expected +++ /dev/null @@ -1,12 +0,0 @@ - movl $1, -4(%rbp) #constant assign - movl -4(%rbp), %eax #assign start - movl %eax, -8(%rbp) #assign end - movl $3, -12(%rbp) #constant assign - movl -12(%rbp), %eax #assign start - movl %eax, -16(%rbp) #assign end - movl -16(%rbp), %eax #mod start - cltd - idivl -8(%rbp) - movl %edx, -20(%rbp) #mod end - movl -20(%rbp), %eax #assign start - movl %eax, -8(%rbp) #assign end diff --git a/tests/sprint4/expected/sp4_cg_mod.ir.exp b/tests/sprint4/expected/sp4_cg_mod.ir.exp new file mode 100644 index 0000000..1148d7e --- /dev/null +++ b/tests/sprint4/expected/sp4_cg_mod.ir.exp @@ -0,0 +1,12 @@ + 1: func_dec : entry + 2: func : entry + 3: $t0 = 4 + 4: x = $t0 + 5: $t1 = 20 + 6: y = $t1 + 7: $t2 = y % x + 8: y = $t2 + 9: param y + 10: call : printInteger 1 + 11: result = $t3 + 12: return : y diff --git a/tests/sprint4/expected/sp4_cg_mod.s.exp b/tests/sprint4/expected/sp4_cg_mod.s.exp new file mode 100644 index 0000000..c76ec55 --- /dev/null +++ b/tests/sprint4/expected/sp4_cg_mod.s.exp @@ -0,0 +1,26 @@ +.globl entry +entry: + pushq %rbp + movq %rsp, %rbp + subq $400, %rsp + movl %edi, -8(%rbp) #FunctionStart1param end + movl $4, -12(%rbp) #constant assign + movl -12(%rbp), %eax #assign start + movl %eax, -16(%rbp) #assign end + movl $20, -20(%rbp) #constant assign + movl -20(%rbp), %eax #assign start + movl %eax, -24(%rbp) #assign end + movl -24(%rbp), %eax #mod start + cltd + idivl -16(%rbp) + movl %edx, -28(%rbp) #mod end + movl -28(%rbp), %eax #assign start + movl %eax, -24(%rbp) #assign end + movl -24(%rbp), %edi #adding param start + call printInteger + movl %eax, -32(%rbp) #store return from call + movl -32(%rbp), %eax #assign start + movl %eax, -36(%rbp) #assign end + movl -24(%rbp), %eax #return y + leave + ret diff --git a/tests/sprint4/expected/sp4_cg_mult.asc.exp b/tests/sprint4/expected/sp4_cg_mult.asc.exp new file mode 100644 index 0000000..3a66591 --- /dev/null +++ b/tests/sprint4/expected/sp4_cg_mult.asc.exp @@ -0,0 +1,47 @@ +001: +002: type string: 1 -> character +003: type BooleanXBoolean: [Boolean: x; Boolean: y] +004: type characterXcharacter: [character: x; character: y] +005: type integerXinteger: [integer: x; integer: y] +006: +007: type Boolean2Boolean: Boolean -> Boolean +008: type integer2integer: integer -> integer +009: type character2integer: character -> integer +010: type Boolean2integer: Boolean -> integer +011: type string2integer: string -> integer +012: type integerXinteger2integer: integerXinteger -> integer +013: type integerXinteger2Boolean: integerXinteger -> Boolean +014: type characterXcharacter2Boolean: characterXcharacter -> Boolean +015: type BooleanXBoolean2Boolean: BooleanXBoolean -> Boolean +016: type integer2address: integer -> address +017: type address2integer: address -> integer +018: type integer2string: integer -> string +019: type integer2character: integer -> character +020: type integer2Boolean: integer -> Boolean +021: +022: +023: external function printInteger: integer2integer +024: external function printCharacter: character2integer +025: external function printBoolean: Boolean2integer +026: +027: external function printS: string2integer +028: external function printI: integer2integer +029: external function printC: character2integer +030: external function printB: Boolean2integer +031: +032: external function inS: integer2string +033: external function inI: integer2integer +034: external function inC: integer2character +035: +036: function entry: string2integer +037: +038: entry (arg) := { +039: [integer:x; integer:y; integer: result] +040: +041: x := 3; +042: y := 20; +043: y := x * y; +044: +045: result := printInteger(y); +046: return y; +047: } \ No newline at end of file diff --git a/tests/sprint4/expected/sp4_cg_mult.expected b/tests/sprint4/expected/sp4_cg_mult.expected deleted file mode 100644 index 20b0a57..0000000 --- a/tests/sprint4/expected/sp4_cg_mult.expected +++ /dev/null @@ -1,11 +0,0 @@ - movl $1, -4(%rbp) #constant assign - movl -4(%rbp), %eax #assign start - movl %eax, -8(%rbp) #assign end - movl $3, -12(%rbp) #constant assign - movl -12(%rbp), %eax #assign start - movl %eax, -16(%rbp) #assign end - movl -16(%rbp), %eax #multiplication start - imull -16(%rbp), %eax - movl %eax, -20(%rbp) #multiplication end - movl -20(%rbp), %eax #assign start - movl %eax, -8(%rbp) #assign end diff --git a/tests/sprint4/expected/sp4_cg_mult.ir.exp b/tests/sprint4/expected/sp4_cg_mult.ir.exp new file mode 100644 index 0000000..12ec01d --- /dev/null +++ b/tests/sprint4/expected/sp4_cg_mult.ir.exp @@ -0,0 +1,12 @@ + 1: func_dec : entry + 2: func : entry + 3: $t0 = 3 + 4: x = $t0 + 5: $t1 = 20 + 6: y = $t1 + 7: $t2 = x * y + 8: y = $t2 + 9: param y + 10: call : printInteger 1 + 11: result = $t3 + 12: return : y diff --git a/tests/sprint4/expected/sp4_cg_mult.s.exp b/tests/sprint4/expected/sp4_cg_mult.s.exp new file mode 100644 index 0000000..019a840 --- /dev/null +++ b/tests/sprint4/expected/sp4_cg_mult.s.exp @@ -0,0 +1,25 @@ +.globl entry +entry: + pushq %rbp + movq %rsp, %rbp + subq $400, %rsp + movl %edi, -8(%rbp) #FunctionStart1param end + movl $3, -12(%rbp) #constant assign + movl -12(%rbp), %eax #assign start + movl %eax, -16(%rbp) #assign end + movl $20, -20(%rbp) #constant assign + movl -20(%rbp), %eax #assign start + movl %eax, -24(%rbp) #assign end + movl -16(%rbp), %eax #multiplication start + imull -24(%rbp), %eax + movl %eax, -28(%rbp) #multiplication end + movl -28(%rbp), %eax #assign start + movl %eax, -24(%rbp) #assign end + movl -24(%rbp), %edi #adding param start + call printInteger + movl %eax, -32(%rbp) #store return from call + movl -32(%rbp), %eax #assign start + movl %eax, -36(%rbp) #assign end + movl -24(%rbp), %eax #return y + leave + ret diff --git a/tests/sprint4/expected/sp4_cg_neg.asc.exp b/tests/sprint4/expected/sp4_cg_neg.asc.exp new file mode 100644 index 0000000..701f487 --- /dev/null +++ b/tests/sprint4/expected/sp4_cg_neg.asc.exp @@ -0,0 +1,46 @@ +001: +002: type string: 1 -> character +003: type BooleanXBoolean: [Boolean: x; Boolean: y] +004: type characterXcharacter: [character: x; character: y] +005: type integerXinteger: [integer: x; integer: y] +006: +007: type Boolean2Boolean: Boolean -> Boolean +008: type integer2integer: integer -> integer +009: type character2integer: character -> integer +010: type Boolean2integer: Boolean -> integer +011: type string2integer: string -> integer +012: type integerXinteger2integer: integerXinteger -> integer +013: type integerXinteger2Boolean: integerXinteger -> Boolean +014: type characterXcharacter2Boolean: characterXcharacter -> Boolean +015: type BooleanXBoolean2Boolean: BooleanXBoolean -> Boolean +016: type integer2address: integer -> address +017: type address2integer: address -> integer +018: type integer2string: integer -> string +019: type integer2character: integer -> character +020: type integer2Boolean: integer -> Boolean +021: +022: +023: external function printInteger: integer2integer +024: external function printCharacter: character2integer +025: external function printBoolean: Boolean2integer +026: +027: external function printS: string2integer +028: external function printI: integer2integer +029: external function printC: character2integer +030: external function printB: Boolean2integer +031: +032: external function inS: integer2string +033: external function inI: integer2integer +034: external function inC: integer2character +035: +036: function entry: string2integer +037: +038: entry (arg) := { +039: [integer:x; integer:y; integer: result] +040: +041: x := 3; +042: y := -x; +043: +044: result := printInteger(y); +045: return y; +046: } \ No newline at end of file diff --git a/tests/sprint4/expected/sp4_cg_neg.expected b/tests/sprint4/expected/sp4_cg_neg.expected deleted file mode 100644 index 5f61770..0000000 --- a/tests/sprint4/expected/sp4_cg_neg.expected +++ /dev/null @@ -1,8 +0,0 @@ - movl $3, -4(%rbp) #constant assign - movl -4(%rbp), %eax #assign start - movl %eax, -8(%rbp) #assign end - movl -8(%rbp), %eax #negation start - negl %eax - movl %eax, -12(%rbp) #negation end - movl -12(%rbp), %eax #assign start - movl %eax, -16(%rbp) #assign end diff --git a/tests/sprint4/expected/sp4_cg_neg.ir.exp b/tests/sprint4/expected/sp4_cg_neg.ir.exp new file mode 100644 index 0000000..88e0fc4 --- /dev/null +++ b/tests/sprint4/expected/sp4_cg_neg.ir.exp @@ -0,0 +1,10 @@ + 1: func_dec : entry + 2: func : entry + 3: $t0 = 3 + 4: x = $t0 + 5: $t1 = -x + 6: y = $t1 + 7: param y + 8: call : printInteger 1 + 9: result = $t2 + 10: return : y diff --git a/tests/sprint4/expected/sp4_cg_neg.s.exp b/tests/sprint4/expected/sp4_cg_neg.s.exp new file mode 100644 index 0000000..6e92063 --- /dev/null +++ b/tests/sprint4/expected/sp4_cg_neg.s.exp @@ -0,0 +1,22 @@ +.globl entry +entry: + pushq %rbp + movq %rsp, %rbp + subq $400, %rsp + movl %edi, -8(%rbp) #FunctionStart1param end + movl $3, -12(%rbp) #constant assign + movl -12(%rbp), %eax #assign start + movl %eax, -16(%rbp) #assign end + movl -16(%rbp), %eax #negation start + negl %eax + movl %eax, -20(%rbp) #negation end + movl -20(%rbp), %eax #assign start + movl %eax, -24(%rbp) #assign end + movl -24(%rbp), %edi #adding param start + call printInteger + movl %eax, -28(%rbp) #store return from call + movl -28(%rbp), %eax #assign start + movl %eax, -32(%rbp) #assign end + movl -24(%rbp), %eax #return y + leave + ret diff --git a/tests/sprint4/expected/sp4_cg_not.asc.exp b/tests/sprint4/expected/sp4_cg_not.asc.exp new file mode 100644 index 0000000..634b5f6 --- /dev/null +++ b/tests/sprint4/expected/sp4_cg_not.asc.exp @@ -0,0 +1,46 @@ +001: +002: type string: 1 -> character +003: type BooleanXBoolean: [Boolean: x; Boolean: y] +004: type characterXcharacter: [character: x; character: y] +005: type integerXinteger: [integer: x; integer: y] +006: +007: type Boolean2Boolean: Boolean -> Boolean +008: type integer2integer: integer -> integer +009: type character2integer: character -> integer +010: type Boolean2integer: Boolean -> integer +011: type string2integer: string -> integer +012: type integerXinteger2integer: integerXinteger -> integer +013: type integerXinteger2Boolean: integerXinteger -> Boolean +014: type characterXcharacter2Boolean: characterXcharacter -> Boolean +015: type BooleanXBoolean2Boolean: BooleanXBoolean -> Boolean +016: type integer2address: integer -> address +017: type address2integer: address -> integer +018: type integer2string: integer -> string +019: type integer2character: integer -> character +020: type integer2Boolean: integer -> Boolean +021: +022: +023: external function printInteger: integer2integer +024: external function printCharacter: character2integer +025: external function printBoolean: Boolean2integer +026: +027: external function printS: string2integer +028: external function printI: integer2integer +029: external function printC: character2integer +030: external function printB: Boolean2integer +031: +032: external function inS: integer2string +033: external function inI: integer2integer +034: external function inC: integer2character +035: +036: function entry: string2integer +037: +038: entry (arg) := { +039: [Boolean: c; Boolean: d; integer: result] +040: +041: c := true; +042: d := !c; +043: +044: result := printBoolean(d); +045: return 1; +046: } \ No newline at end of file diff --git a/tests/sprint4/expected/sp4_cg_not.expected b/tests/sprint4/expected/sp4_cg_not.expected deleted file mode 100644 index b2e4bda..0000000 --- a/tests/sprint4/expected/sp4_cg_not.expected +++ /dev/null @@ -1,13 +0,0 @@ - movl $-1, -4(%rbp) #constant assign - movl -4(%rbp), %eax #assign start - movl %eax, -8(%rbp) #assign end - movzbl -8(%rbp), %eax #not start - testl %eax, %eax - setne %al - xorl $1, %eax - movzbl %al, %eax - movb %al, -12(%rbp) - andb $1, -12(%rbp) #not end - movl -12(%rbp), %eax #assign start - movl %eax, -16(%rbp) #assign end - movl $1, -20(%rbp) #constant assign diff --git a/tests/sprint4/expected/sp4_cg_not.ir.exp b/tests/sprint4/expected/sp4_cg_not.ir.exp new file mode 100644 index 0000000..eb3abe9 --- /dev/null +++ b/tests/sprint4/expected/sp4_cg_not.ir.exp @@ -0,0 +1,12 @@ + 1: func_dec : entry + 2: func : entry + 3: $t0 = true + 4: Label : 1 + 5: c = $t0 + 6: Label : 2 + 7: d = $t1 + 8: param d + 9: call : printBoolean 1 + 10: result = $t2 + 11: $t3 = 1 + 12: return : $t3 diff --git a/tests/sprint4/expected/sp4_cg_not.s.exp b/tests/sprint4/expected/sp4_cg_not.s.exp new file mode 100644 index 0000000..8739ed0 --- /dev/null +++ b/tests/sprint4/expected/sp4_cg_not.s.exp @@ -0,0 +1,20 @@ +.globl entry +entry: + pushq %rbp + movq %rsp, %rbp + subq $400, %rsp + movl %edi, -8(%rbp) #FunctionStart1param end + movl $1, -9(%rbp) #constant assign +.L1: + movl -9(%rbp), %eax #assign start + movl %eax, -10(%rbp) #assign end +.L2: + movl -11(%rbp), %edi #adding param start + call printBoolean + movl %eax, -18(%rbp) #store return from call + movl -18(%rbp), %eax #assign start + movl %eax, -24(%rbp) #assign end + movl $1, -28(%rbp) #constant assign + movl -28(%rbp), %eax #return $t3 + leave + ret diff --git a/tests/sprint4/expected/sp4_cg_or.asc.exp b/tests/sprint4/expected/sp4_cg_or.asc.exp new file mode 100644 index 0000000..44414e0 --- /dev/null +++ b/tests/sprint4/expected/sp4_cg_or.asc.exp @@ -0,0 +1,47 @@ +001: +002: type string: 1 -> character +003: type BooleanXBoolean: [Boolean: x; Boolean: y] +004: type characterXcharacter: [character: x; character: y] +005: type integerXinteger: [integer: x; integer: y] +006: +007: type Boolean2Boolean: Boolean -> Boolean +008: type integer2integer: integer -> integer +009: type character2integer: character -> integer +010: type Boolean2integer: Boolean -> integer +011: type string2integer: string -> integer +012: type integerXinteger2integer: integerXinteger -> integer +013: type integerXinteger2Boolean: integerXinteger -> Boolean +014: type characterXcharacter2Boolean: characterXcharacter -> Boolean +015: type BooleanXBoolean2Boolean: BooleanXBoolean -> Boolean +016: type integer2address: integer -> address +017: type address2integer: address -> integer +018: type integer2string: integer -> string +019: type integer2character: integer -> character +020: type integer2Boolean: integer -> Boolean +021: +022: +023: external function printInteger: integer2integer +024: external function printCharacter: character2integer +025: external function printBoolean: Boolean2integer +026: +027: external function printS: string2integer +028: external function printI: integer2integer +029: external function printC: character2integer +030: external function printB: Boolean2integer +031: +032: external function inS: integer2string +033: external function inI: integer2integer +034: external function inC: integer2character +035: +036: function entry: string2integer +037: +038: entry (arg) := { +039: [Boolean:b; Boolean: c; Boolean: d; integer: result] +040: +041: c := true; +042: d := false; +043: d := c | d; +044: +045: result := printBoolean(d); +046: return 1; +047: } \ No newline at end of file diff --git a/tests/sprint4/expected/sp4_cg_or.expected b/tests/sprint4/expected/sp4_cg_or.expected deleted file mode 100644 index 120058f..0000000 --- a/tests/sprint4/expected/sp4_cg_or.expected +++ /dev/null @@ -1,21 +0,0 @@ - movl $-1, -4(%rbp) #constant assign - movl -4(%rbp), %eax #assign start - movl %eax, -8(%rbp) #assign end - movl $-1, -12(%rbp) #constant assign - movl -12(%rbp), %eax #assign start - movl %eax, -16(%rbp) #assign end - cmpl $0, -8(%rbp) #start or - jne .L1or2 - cmpl $0, -16(%rbp) - je .L1or3 -.L1or2: - movl $1, %eax - jmp .L1or4 -.L1or3: - movl $0, %eax -.L1or4: - movb %al, -20(%rbp) - andb $1, -20(%rbp) #or end - movl -20(%rbp), %eax #assign start - movl %eax, -16(%rbp) #assign end - movl $1, -24(%rbp) #constant assign diff --git a/tests/sprint4/expected/sp4_cg_or.ir.exp b/tests/sprint4/expected/sp4_cg_or.ir.exp new file mode 100644 index 0000000..4470879 --- /dev/null +++ b/tests/sprint4/expected/sp4_cg_or.ir.exp @@ -0,0 +1,22 @@ + 1: func_dec : entry + 2: func : entry + 3: $t0 = true + 4: Label : 1 + 5: c = $t0 + 6: $t1 = false + 7: Label : 2 + 8: d = $t1 + 9: $t2 = true + 10: if c True GOTO 4 + 11: GOTO : 3 + 12: Label : 3 + 13: if d True GOTO 4 + 14: $t2 = false + 15: GOTO : 4 + 16: Label : 4 + 17: d = $t2 + 18: param d + 19: call : printBoolean 1 + 20: result = $t3 + 21: $t4 = 1 + 22: return : $t4 diff --git a/tests/sprint4/expected/sp4_cg_or.s.exp b/tests/sprint4/expected/sp4_cg_or.s.exp new file mode 100644 index 0000000..1ca0a6a --- /dev/null +++ b/tests/sprint4/expected/sp4_cg_or.s.exp @@ -0,0 +1,35 @@ +.globl entry +entry: + pushq %rbp + movq %rsp, %rbp + subq $416, %rsp + movl %edi, -8(%rbp) #FunctionStart1param end + movl $1, -9(%rbp) #constant assign +.L1: + movl -9(%rbp), %eax #assign start + movl %eax, -10(%rbp) #assign end + movl $0, -11(%rbp) #constant assign +.L2: + movl -11(%rbp), %eax #assign start + movl %eax, -12(%rbp) #assign end + movl $1, -13(%rbp) #constant assign + cmpb $0, -10(%rbp) #if true start + jne .L4 #if true end + jmp .L3 +.L3: + cmpb $0, -12(%rbp) #if true start + jne .L4 #if true end + movl $0, -13(%rbp) #constant assign + jmp .L4 +.L4: + movl -13(%rbp), %eax #assign start + movl %eax, -12(%rbp) #assign end + movl -12(%rbp), %edi #adding param start + call printBoolean + movl %eax, -18(%rbp) #store return from call + movl -18(%rbp), %eax #assign start + movl %eax, -24(%rbp) #assign end + movl $1, -28(%rbp) #constant assign + movl -28(%rbp), %eax #return $t4 + leave + ret diff --git a/tests/sprint4/expected/sp4_cg_sub.asc.exp b/tests/sprint4/expected/sp4_cg_sub.asc.exp new file mode 100644 index 0000000..8726fb3 --- /dev/null +++ b/tests/sprint4/expected/sp4_cg_sub.asc.exp @@ -0,0 +1,47 @@ +001: +002: type string: 1 -> character +003: type BooleanXBoolean: [Boolean: x; Boolean: y] +004: type characterXcharacter: [character: x; character: y] +005: type integerXinteger: [integer: x; integer: y] +006: +007: type Boolean2Boolean: Boolean -> Boolean +008: type integer2integer: integer -> integer +009: type character2integer: character -> integer +010: type Boolean2integer: Boolean -> integer +011: type string2integer: string -> integer +012: type integerXinteger2integer: integerXinteger -> integer +013: type integerXinteger2Boolean: integerXinteger -> Boolean +014: type characterXcharacter2Boolean: characterXcharacter -> Boolean +015: type BooleanXBoolean2Boolean: BooleanXBoolean -> Boolean +016: type integer2address: integer -> address +017: type address2integer: address -> integer +018: type integer2string: integer -> string +019: type integer2character: integer -> character +020: type integer2Boolean: integer -> Boolean +021: +022: +023: external function printInteger: integer2integer +024: external function printCharacter: character2integer +025: external function printBoolean: Boolean2integer +026: +027: external function printS: string2integer +028: external function printI: integer2integer +029: external function printC: character2integer +030: external function printB: Boolean2integer +031: +032: external function inS: integer2string +033: external function inI: integer2integer +034: external function inC: integer2character +035: +036: function entry: string2integer +037: +038: entry (arg) := { +039: [integer:x; integer:y; integer: result] +040: +041: y := 1; +042: x := 3; +043: y := x - y; +044: +045: result := printInteger(y); +046: return y; +047: } \ No newline at end of file diff --git a/tests/sprint4/expected/sp4_cg_sub.expected b/tests/sprint4/expected/sp4_cg_sub.expected deleted file mode 100644 index 743ef59..0000000 --- a/tests/sprint4/expected/sp4_cg_sub.expected +++ /dev/null @@ -1,11 +0,0 @@ - movl $1, -4(%rbp) #constant assign - movl -4(%rbp), %eax #assign start - movl %eax, -8(%rbp) #assign end - movl $3, -12(%rbp) #constant assign - movl -12(%rbp), %eax #assign start - movl %eax, -16(%rbp) #assign end - movl -16(%rbp), %eax #subtraction start - subl -8(%rbp), %eax - movl %eax, -20(%rbp) #subtraction end - movl -20(%rbp), %eax #assign start - movl %eax, -8(%rbp) #assign end diff --git a/tests/sprint4/expected/sp4_cg_sub.ir.exp b/tests/sprint4/expected/sp4_cg_sub.ir.exp new file mode 100644 index 0000000..468b1eb --- /dev/null +++ b/tests/sprint4/expected/sp4_cg_sub.ir.exp @@ -0,0 +1,12 @@ + 1: func_dec : entry + 2: func : entry + 3: $t0 = 1 + 4: y = $t0 + 5: $t1 = 3 + 6: x = $t1 + 7: $t2 = x - y + 8: y = $t2 + 9: param y + 10: call : printInteger 1 + 11: result = $t3 + 12: return : y diff --git a/tests/sprint4/expected/sp4_cg_sub.s.exp b/tests/sprint4/expected/sp4_cg_sub.s.exp new file mode 100644 index 0000000..8f2c60e --- /dev/null +++ b/tests/sprint4/expected/sp4_cg_sub.s.exp @@ -0,0 +1,25 @@ +.globl entry +entry: + pushq %rbp + movq %rsp, %rbp + subq $400, %rsp + movl %edi, -8(%rbp) #FunctionStart1param end + movl $1, -12(%rbp) #constant assign + movl -12(%rbp), %eax #assign start + movl %eax, -16(%rbp) #assign end + movl $3, -20(%rbp) #constant assign + movl -20(%rbp), %eax #assign start + movl %eax, -24(%rbp) #assign end + movl -24(%rbp), %eax #subtraction start + subl -16(%rbp), %eax + movl %eax, -28(%rbp) #subtraction end + movl -28(%rbp), %eax #assign start + movl %eax, -16(%rbp) #assign end + movl -16(%rbp), %edi #adding param start + call printInteger + movl %eax, -32(%rbp) #store return from call + movl -32(%rbp), %eax #assign start + movl %eax, -36(%rbp) #assign end + movl -16(%rbp), %eax #return y + leave + ret diff --git a/tests/sprint4/test/sp4_cg_add.alpha b/tests/sprint4/test/sp4_cg_add.alpha index f4f8138..1b63c8d 100644 --- a/tests/sprint4/test/sp4_cg_add.alpha +++ b/tests/sprint4/test/sp4_cg_add.alpha @@ -1,10 +1,48 @@ -type main: integer -> integer -function test: main - -test (a) := { - [integer:x; integer:y] +(* TEST: [-asc -tc -cg -ir] *) + +type string: 1 -> character +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 +type integer2string: integer -> string +type integer2character: integer -> character +type integer2Boolean: integer -> Boolean + + +external function printInteger: integer2integer +external function printCharacter: character2integer +external function printBoolean: Boolean2integer + +external function printS: string2integer +external function printI: integer2integer +external function printC: character2integer +external function printB: Boolean2integer + +external function inS: integer2string +external function inI: integer2integer +external function inC: integer2character + +function entry: string2integer + +entry (arg) := { + [integer:x; integer:y; integer: result] + y := 1; x := 3; y := x + y; + + result := printInteger(y); return y; } \ No newline at end of file diff --git a/tests/sprint4/test/sp4_cg_and.alpha b/tests/sprint4/test/sp4_cg_and.alpha index 5017e35..c4a1d47 100644 --- a/tests/sprint4/test/sp4_cg_and.alpha +++ b/tests/sprint4/test/sp4_cg_and.alpha @@ -1,10 +1,48 @@ -type main: integer -> integer -function test: main +(* TEST: [-asc -tc -cg -ir] *) -test (a) := { - [Boolean:b; Boolean: c; Boolean: d] - c := true; - d := false; - d := c & d; - return 1; +type string: 1 -> character +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 +type integer2string: integer -> string +type integer2character: integer -> character +type integer2Boolean: integer -> Boolean + + +external function printInteger: integer2integer +external function printCharacter: character2integer +external function printBoolean: Boolean2integer + +external function printS: string2integer +external function printI: integer2integer +external function printC: character2integer +external function printB: Boolean2integer + +external function inS: integer2string +external function inI: integer2integer +external function inC: integer2character + +function entry: string2integer + +entry (arg) := { + [Boolean:b; Boolean: c; Boolean: d; integer: result] + + z := true; + d := false; + d := c & d; + + result := printBoolean(d); + return 1; } \ No newline at end of file diff --git a/tests/sprint4/test/sp4_cg_calls.alpha b/tests/sprint4/test/sp4_cg_calls.alpha new file mode 100644 index 0000000..ab70dbc --- /dev/null +++ b/tests/sprint4/test/sp4_cg_calls.alpha @@ -0,0 +1,61 @@ +(* TEST: [-asc -tc -cg -ir] *) + +type string: 1 -> character +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 +type integer2string: integer -> string +type integer2character: integer -> character +type integer2Boolean: integer -> Boolean + + +external function printInteger: integer2integer +external function printCharacter: character2integer +external function printBoolean: Boolean2integer + +external function printS: string2integer +external function printI: integer2integer +external function printC: character2integer +external function printB: Boolean2integer + +external function inS: integer2string +external function inI: integer2integer +external function inC: integer2character + +function entry: string2integer + +type rec: [integer: x; integer: y; integer: z; integer: a; integer: b; integer: c; integer: d] +type T2: rec -> integer +type T: integer -> integer +function bar: T2 +function ahh: T + +ahh (a) := { + a := printInteger(a); + return -1; +} + +bar (a, b, c,d,e,f,g) := { + a := printInteger(g); + return b; +} + +entry (arg) := { + [integer:x; integer:y; integer: result; character: a] + a := 'a'; + x := printCharacter(a); + result := bar(1,2,3,4,5,6,7); + return 1; +} diff --git a/tests/sprint4/test/sp4_cg_div.alpha b/tests/sprint4/test/sp4_cg_div.alpha index 32d3537..097b978 100644 --- a/tests/sprint4/test/sp4_cg_div.alpha +++ b/tests/sprint4/test/sp4_cg_div.alpha @@ -1,10 +1,48 @@ -type main: integer -> integer -function test: main +(* TEST: [-asc -tc -cg -ir] *) -test (a) := { - [integer:x; integer:y] - y := 1; - x := 3; - y := x / y; - return y; +type string: 1 -> character +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 +type integer2string: integer -> string +type integer2character: integer -> character +type integer2Boolean: integer -> Boolean + + +external function printInteger: integer2integer +external function printCharacter: character2integer +external function printBoolean: Boolean2integer + +external function printS: string2integer +external function printI: integer2integer +external function printC: character2integer +external function printB: Boolean2integer + +external function inS: integer2string +external function inI: integer2integer +external function inC: integer2character + +function entry: string2integer + +entry (arg) := { + [integer:x; integer:y; integer: result] + + x := 24; + y := 3; + y := x / y; + + result := printInteger(y); + return y; } \ No newline at end of file diff --git a/tests/sprint4/test/sp4_cg_equal_to.alpha b/tests/sprint4/test/sp4_cg_equal_to.alpha index a3da50c..1baae8e 100644 --- a/tests/sprint4/test/sp4_cg_equal_to.alpha +++ b/tests/sprint4/test/sp4_cg_equal_to.alpha @@ -1,10 +1,48 @@ -type main: integer -> integer -function test: main +(* TEST: [-asc -tc -cg -ir] *) -test (a) := { - [Boolean: b; integer: x; integer: y] - x := 1; +type string: 1 -> character +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 +type integer2string: integer -> string +type integer2character: integer -> character +type integer2Boolean: integer -> Boolean + + +external function printInteger: integer2integer +external function printCharacter: character2integer +external function printBoolean: Boolean2integer + +external function printS: string2integer +external function printI: integer2integer +external function printC: character2integer +external function printB: Boolean2integer + +external function inS: integer2string +external function inI: integer2integer +external function inC: integer2character + +function entry: string2integer + +entry (arg) := { + [Boolean: b; integer: x; integer: y; integer: result] + + x := 1; y := 2; b := x = y; - return 1; + + result := printBoolean(b); + return 1; } \ No newline at end of file diff --git a/tests/sprint4/test/sp4_cg_less_than.alpha b/tests/sprint4/test/sp4_cg_less_than.alpha index 8f41ced..86ce4b7 100644 --- a/tests/sprint4/test/sp4_cg_less_than.alpha +++ b/tests/sprint4/test/sp4_cg_less_than.alpha @@ -1,10 +1,48 @@ -type main: integer -> integer -function test: main +(* TEST: [-asc -tc -cg -ir] *) -test (a) := { - [Boolean: b; integer: x; integer: y] - x := 1; +type string: 1 -> character +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 +type integer2string: integer -> string +type integer2character: integer -> character +type integer2Boolean: integer -> Boolean + + +external function printInteger: integer2integer +external function printCharacter: character2integer +external function printBoolean: Boolean2integer + +external function printS: string2integer +external function printI: integer2integer +external function printC: character2integer +external function printB: Boolean2integer + +external function inS: integer2string +external function inI: integer2integer +external function inC: integer2character + +function entry: string2integer + +entry (arg) := { + [Boolean: b; integer: x; integer: y; integer: result] + + x := 1; y := 2; b := x < y; - return 1; -} \ No newline at end of file + + result := printBoolean(b); + return 1; +} diff --git a/tests/sprint4/test/sp4_cg_mod.alpha b/tests/sprint4/test/sp4_cg_mod.alpha index 1b579d5..c405ec4 100644 --- a/tests/sprint4/test/sp4_cg_mod.alpha +++ b/tests/sprint4/test/sp4_cg_mod.alpha @@ -1,10 +1,48 @@ -type main: integer -> integer -function test: main +(* TEST: [-asc -tc -cg -ir] *) -test (a) := { - [integer:x; integer:y] - y := 1; - x := 3; - y := x % y; - return y; +type string: 1 -> character +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 +type integer2string: integer -> string +type integer2character: integer -> character +type integer2Boolean: integer -> Boolean + + +external function printInteger: integer2integer +external function printCharacter: character2integer +external function printBoolean: Boolean2integer + +external function printS: string2integer +external function printI: integer2integer +external function printC: character2integer +external function printB: Boolean2integer + +external function inS: integer2string +external function inI: integer2integer +external function inC: integer2character + +function entry: string2integer + +entry (arg) := { + [integer:x; integer:y; integer: result] + + x := 4; + y := 20; + y := y % x; + + result := printInteger(y); + return y; } \ No newline at end of file diff --git a/tests/sprint4/test/sp4_cg_mult.alpha b/tests/sprint4/test/sp4_cg_mult.alpha index c151a6b..157ba35 100644 --- a/tests/sprint4/test/sp4_cg_mult.alpha +++ b/tests/sprint4/test/sp4_cg_mult.alpha @@ -1,10 +1,48 @@ -type main: integer -> integer -function test: main +(* TEST: [-asc -tc -cg -ir] *) -test (a) := { - [integer:x; integer:y] - y := 1; - x := 3; - y := x * x; - return y; +type string: 1 -> character +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 +type integer2string: integer -> string +type integer2character: integer -> character +type integer2Boolean: integer -> Boolean + + +external function printInteger: integer2integer +external function printCharacter: character2integer +external function printBoolean: Boolean2integer + +external function printS: string2integer +external function printI: integer2integer +external function printC: character2integer +external function printB: Boolean2integer + +external function inS: integer2string +external function inI: integer2integer +external function inC: integer2character + +function entry: string2integer + +entry (arg) := { + [integer:x; integer:y; integer: result] + + x := 3; + y := 20; + y := x * y; + + result := printInteger(y); + return y; } \ No newline at end of file diff --git a/tests/sprint4/test/sp4_cg_neg.alpha b/tests/sprint4/test/sp4_cg_neg.alpha index 345980b..bae60fa 100644 --- a/tests/sprint4/test/sp4_cg_neg.alpha +++ b/tests/sprint4/test/sp4_cg_neg.alpha @@ -1,9 +1,47 @@ -type main: integer -> integer -function test: main +(* TEST: [-asc -tc -cg -ir] *) -test (a) := { - [integer:x; integer:y] - x := 3; - y := -x; - return y; +type string: 1 -> character +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 +type integer2string: integer -> string +type integer2character: integer -> character +type integer2Boolean: integer -> Boolean + + +external function printInteger: integer2integer +external function printCharacter: character2integer +external function printBoolean: Boolean2integer + +external function printS: string2integer +external function printI: integer2integer +external function printC: character2integer +external function printB: Boolean2integer + +external function inS: integer2string +external function inI: integer2integer +external function inC: integer2character + +function entry: string2integer + +entry (arg) := { + [integer:x; integer:y; integer: result] + + x := 3; + y := -x; + + result := printInteger(y); + return y; } \ No newline at end of file diff --git a/tests/sprint4/test/sp4_cg_not.alpha b/tests/sprint4/test/sp4_cg_not.alpha index 40252f9..1fd4ca4 100644 --- a/tests/sprint4/test/sp4_cg_not.alpha +++ b/tests/sprint4/test/sp4_cg_not.alpha @@ -1,9 +1,47 @@ -type main: integer -> integer -function test: main +(* TEST: [-asc -tc -cg -ir] *) -test (a) := { - [Boolean: c; Boolean: d] - c := true; - d := !c; - return 1; +type string: 1 -> character +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 +type integer2string: integer -> string +type integer2character: integer -> character +type integer2Boolean: integer -> Boolean + + +external function printInteger: integer2integer +external function printCharacter: character2integer +external function printBoolean: Boolean2integer + +external function printS: string2integer +external function printI: integer2integer +external function printC: character2integer +external function printB: Boolean2integer + +external function inS: integer2string +external function inI: integer2integer +external function inC: integer2character + +function entry: string2integer + +entry (arg) := { + [Boolean: c; Boolean: d; integer: result] + + c := true; + d := !c; + + result := printBoolean(d); + return 1; } \ No newline at end of file diff --git a/tests/sprint4/test/sp4_cg_or.alpha b/tests/sprint4/test/sp4_cg_or.alpha index b6d6766..6ecac00 100644 --- a/tests/sprint4/test/sp4_cg_or.alpha +++ b/tests/sprint4/test/sp4_cg_or.alpha @@ -1,10 +1,48 @@ -type main: integer -> integer -function test: main +(* TEST: [-asc -tc -cg -ir] *) -test (a) := { - [Boolean:b; Boolean: c; Boolean: d] - c := true; - d := false; - d := c | d; - return 1; +type string: 1 -> character +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 +type integer2string: integer -> string +type integer2character: integer -> character +type integer2Boolean: integer -> Boolean + + +external function printInteger: integer2integer +external function printCharacter: character2integer +external function printBoolean: Boolean2integer + +external function printS: string2integer +external function printI: integer2integer +external function printC: character2integer +external function printB: Boolean2integer + +external function inS: integer2string +external function inI: integer2integer +external function inC: integer2character + +function entry: string2integer + +entry (arg) := { + [Boolean:b; Boolean: c; Boolean: d; integer: result] + + c := true; + d := false; + d := c | d; + + result := printBoolean(d); + return 1; } \ No newline at end of file diff --git a/tests/sprint4/test/sp4_cg_sub.alpha b/tests/sprint4/test/sp4_cg_sub.alpha index f280c9d..43420bb 100644 --- a/tests/sprint4/test/sp4_cg_sub.alpha +++ b/tests/sprint4/test/sp4_cg_sub.alpha @@ -1,10 +1,48 @@ -type main: integer -> integer -function test: main +(* TEST: [-asc -tc -cg -ir] *) -test (a) := { - [integer:x; integer:y] - y := 1; - x := 3; - y := x - y; - return y; +type string: 1 -> character +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 +type integer2string: integer -> string +type integer2character: integer -> character +type integer2Boolean: integer -> Boolean + + +external function printInteger: integer2integer +external function printCharacter: character2integer +external function printBoolean: Boolean2integer + +external function printS: string2integer +external function printI: integer2integer +external function printC: character2integer +external function printB: Boolean2integer + +external function inS: integer2string +external function inI: integer2integer +external function inC: integer2character + +function entry: string2integer + +entry (arg) := { + [integer:x; integer:y; integer: result] + + y := 1; + x := 3; + y := x - y; + + result := printInteger(y); + return y; } \ No newline at end of file