Skip to content

Commit a83410e

Browse files
author
Ryan Lewis
committed
Add cs545
- Added pascal compiler
1 parent b2cf1c1 commit a83410e

26 files changed

+2462
-0
lines changed

cs545/pascal/LICENSE

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
License: MIT
2+
3+
Copyright (C) 2012 Ryan Lewis
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
6+
7+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
8+
9+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

cs545/pascal/Makefile

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
CC = gcc
2+
CFLAGS = -g
3+
#CFLAGS = -g -DPRINT_SYMBOL_TABLE -DPRINT_SYNTAX_TREE
4+
LEX = flex
5+
LFLAGS = -l
6+
YACC = bison
7+
YFLAGS = -dv
8+
LIBS = -ll -ly
9+
HEADERS = scope.h tree.h symtab.h decl_list.h arg_list.h semantics.h gencode.h type.h
10+
SOURCES = scope.c tree.c symtab.c decl_list.c arg_list.c semantics.c gencode.c
11+
OBJECTS = pascal.tab.o lex.yy.o scope.o tree.o symtab.o decl_list.o arg_list.o semantics.o gencode.o
12+
BINARY = pascal
13+
14+
all: pascal.tab.c lex.yy.c $(SOURCES) $(BINARY)
15+
16+
$(BINARY): $(OBJECTS)
17+
$(CC) $(CFLAGS) $(OBJECTS) -o $(BINARY) $(LIBS)
18+
19+
.c.o:
20+
$(CC) $(CFLAGS) -c $<
21+
22+
pascal.tab.c: pascal.y
23+
$(YACC) $(YFLAGS) pascal.y
24+
25+
lex.yy.c: pascal.lex
26+
$(LEX) $(LFLAGS) pascal.lex
27+
28+
tar:
29+
tar -cvf pascal.tar Makefile pascal.lex pascal.y test_files $(HEADERS) $(SOURCES)
30+
31+
clean:
32+
rm -f pascal.tab.* lex.yy.* *.o pascal.output $(BINARY)

cs545/pascal/README

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
Ryan Lewis
2+
CS545
3+
Pascal Compiler
4+
--------------------
5+
6+
0. Building and Running:
7+
* Note: This was tested in Mac OS X 10.6.7 with GCC 4.2.1
8+
I couldn't get the assembly to work in x86 Ubuntu... maybe you'll
9+
have better luck?
10+
* Note: There are two debug flags that can be enabled in the Makefile:
11+
** PRINT_SYNTAX_TREE: will print the syntax tree for each BEGIN-END block
12+
** PRINT_SYMBOL_TABLE: will print the symbol table in each scope
13+
- run `make`
14+
- run `./pascal < program.p > output.s`
15+
16+
1. Test Files:
17+
- In test_files folder
18+
- ifthen.p: tests if-then-else support, nested statments, write()
19+
- example.p: tests function calls, expressions, write()
20+
- boo.p: the sample file that you made when I was demoing it for you
21+
- *.s files in there are example assembly output in case it doesn't compile
22+
23+
2. Limitations:
24+
- No loop support
25+
- No real support
26+
- No array (int or real) support
27+
- No non-local access
28+
- No expr_gencode() panic mode support
29+
- No read (scanf) support
30+
- Saving register states will save all values of all registers,not just
31+
those that were used.
32+
- Maximum number of scopes is static (upper bound of 10), not dynamic

cs545/pascal/arg_list.c

+117
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
#include <stdio.h>
2+
#include <stdlib.h>
3+
#include "arg_list.h"
4+
5+
/* Free argument list */
6+
void arg_destroy(arg_elem *head) {
7+
if (head == NULL)
8+
return;
9+
10+
fprintf(stderr, "destroying arg_head\n");
11+
12+
arg_elem *curr, *tmp;
13+
14+
curr = head->next;
15+
head->next = NULL;
16+
17+
while (curr != NULL) {
18+
tmp = curr->next;
19+
free(curr);
20+
curr = tmp;
21+
}
22+
}
23+
24+
/* Append to the end of an argument list */
25+
arg_elem *arg_append(arg_elem *head, symtab_type type) {
26+
arg_elem *tmp;
27+
28+
if (head == NULL) {
29+
//fprintf(stderr, "head is null\n");
30+
if ((head = (arg_elem *) malloc(sizeof(arg_elem))) == NULL) {
31+
printf("could not malloc\n");
32+
exit(1);
33+
}
34+
35+
head->type = type;
36+
head->next = head;
37+
}
38+
else {
39+
//fprintf(stderr, "entered else, name = %s\n", name);
40+
tmp = head;
41+
42+
while (tmp->next != head)
43+
tmp = tmp->next;
44+
45+
if ((tmp->next = (arg_elem *)malloc(sizeof(arg_elem))) == NULL) {
46+
printf("coul not malloc\n");
47+
exit(1);
48+
}
49+
50+
tmp = tmp->next;
51+
tmp->type = type;
52+
tmp->next = head;
53+
}
54+
55+
//fprintf(stderr, "head->name before return: %s\n", head->name);
56+
57+
return head;
58+
}
59+
60+
/* Return the number of elements in a given list.
61+
Used for funciton/procedure semantics. */
62+
int arg_list_size(arg_elem *head) {
63+
arg_elem *data = head;
64+
int size = 0;
65+
66+
if (data != NULL) {
67+
do {
68+
size++;
69+
70+
data = data->next;
71+
}
72+
while (data != head);
73+
}
74+
else
75+
fprintf(stderr, "print_arg_list: data is null\n");
76+
77+
return size;
78+
}
79+
80+
/* Returns zero if there are no differences in two argument lists
81+
Used for function/procedure semantics */
82+
int arg_list_compare(arg_elem *one, arg_elem *two) {
83+
arg_elem *data_one = one, *data_two = two;
84+
int diff = 0;
85+
86+
if (one == NULL || two == NULL)
87+
error("arg_list_compare: null comparison");
88+
89+
do {
90+
//fprintf(stderr, "compare: one: %d, two: %d\n", data_one->type, data_two->type);
91+
if (data_one->type != data_two->type)
92+
diff++;
93+
94+
data_one = data_one->next;
95+
data_two = data_two->next;
96+
}
97+
while (data_one != one);
98+
99+
return diff;
100+
}
101+
102+
/* Print an argument list (for debugging) */
103+
void print_arg_list(arg_elem *head) {
104+
arg_elem *data = head;
105+
106+
if (data != NULL) {
107+
do {
108+
fprintf(stderr, "arg_list, type: %d\n", data->type);
109+
110+
data = data->next;
111+
}
112+
while (data != head);
113+
}
114+
else
115+
fprintf(stderr, "print_arg_list: data is null\n");
116+
117+
}

cs545/pascal/arg_list.h

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
#ifndef ARG_LIST_H
2+
#define ARG_LIST_H
3+
4+
#include "type.h"
5+
6+
/*
7+
* Argument Type List
8+
*
9+
* A linked list of symbol table types.
10+
*/
11+
typedef struct arg_elem_s {
12+
symtab_type type;
13+
14+
struct arg_elem_s *next;
15+
} arg_elem;
16+
17+
void arg_destroy(arg_elem *head);
18+
arg_elem *arg_append(arg_elem *head, symtab_type type);
19+
int arg_list_size(arg_elem *head);
20+
int arg_list_compare(arg_elem *one, arg_elem *two);
21+
22+
void print_arg_list(arg_elem *head);
23+
24+
#endif

cs545/pascal/decl_list.c

+58
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
#include <stdio.h>
2+
#include <stdlib.h>
3+
#include "decl_list.h"
4+
5+
/*
6+
* Code here is functionally equivalent to arg_elem.c
7+
*/
8+
void decl_destroy(decl_elem *head) {
9+
if (head == NULL)
10+
return;
11+
12+
decl_elem *curr, *tmp;
13+
14+
curr = head->next;
15+
head->next = NULL;
16+
17+
while (curr != NULL) {
18+
tmp = curr->next;
19+
free(curr);
20+
curr = tmp;
21+
}
22+
}
23+
24+
25+
decl_elem *decl_append(decl_elem *head, char *name) {
26+
decl_elem *tmp;
27+
28+
if (head == NULL) {
29+
//fprintf(stderr, "head is null\n");
30+
if ((head = (decl_elem *) malloc(sizeof(decl_elem))) == NULL) {
31+
printf("could not malloc\n");
32+
exit(1);
33+
}
34+
35+
head->name = name;
36+
head->next = head;
37+
}
38+
else {
39+
//fprintf(stderr, "entered else, name = %s\n", name);
40+
tmp = head;
41+
42+
while (tmp->next != head)
43+
tmp = tmp->next;
44+
45+
if ((tmp->next = (decl_elem *)malloc(sizeof(decl_elem))) == NULL) {
46+
printf("coul not malloc\n");
47+
exit(1);
48+
}
49+
50+
tmp = tmp->next;
51+
tmp->name = name;
52+
tmp->next = head;
53+
}
54+
55+
//fprintf(stderr, "head->name before return: %s\n", head->name);
56+
57+
return head;
58+
}

cs545/pascal/decl_list.h

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#ifndef DECL_LIST_H
2+
#define DECL_LIST_H
3+
4+
/*
5+
* Declaration List
6+
*
7+
* A linked list of declared variable names
8+
*
9+
* Code here is functionally equivalent to arg_elem.h, this just keeps
10+
* track of a name rather than a type
11+
*/
12+
typedef struct decl_elem_s {
13+
char *name;
14+
15+
struct decl_elem_s *next;
16+
} decl_elem;
17+
18+
//void decl_init(decl_elem *d);
19+
void decl_destroy(decl_elem *head);
20+
decl_elem *decl_append(decl_elem *head, char *name);
21+
22+
#endif

0 commit comments

Comments
 (0)