-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
58df330
commit 53b4775
Showing
89 changed files
with
1,539 additions
and
0 deletions.
There are no files selected for viewing
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
# Change "no" to "yes" to use our binaries | ||
USE_BINARIES = no | ||
|
||
ifeq ($(USE_BINARIES),yes) | ||
SRCS = lib/linkedlist.o lib/talloc.o lib/tokenizer.o lib/parser.o \ | ||
main.c interpreter.c | ||
HDRS = lib/parser.h lib/linkedlist.h lib/talloc.h lib/tokenizer.h \ | ||
lib/value.h interpreter.h | ||
else | ||
SRCS = linkedlist.c talloc.c main.c tokenizer.c parser.c interpreter.c | ||
HDRS = tokenizer.h linkedlist.h talloc.h parser.h value.h interpreter.h | ||
endif | ||
|
||
CC = clang | ||
CFLAGS = -g | ||
|
||
OBJS = $(SRCS:.c=.o) | ||
|
||
.PHONY: interpreter | ||
interpreter: $(OBJS) | ||
$(CC) $(CFLAGS) $^ -o $@ | ||
rm -f *.o | ||
rm -f vgcore.* | ||
|
||
.PHONY: phony_target | ||
phony_target: | ||
|
||
%.o : %.c $(HDRS) phony_target | ||
$(CC) $(CFLAGS) -c $< -o $@ | ||
|
||
clean: | ||
rm -f *.o | ||
rm -f interpreter | ||
|
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,131 @@ | ||
/* | ||
interpreter.c | ||
Written by Victor Huang and Thien K. M. Bui | ||
Last editted 02-23-22 | ||
*/ | ||
|
||
#include <string.h> | ||
|
||
#include "value.h" | ||
#include "linkedlist.h" | ||
#include "talloc.h" | ||
|
||
Value *eval(Value *expr, Frame *frame) | ||
{ | ||
|
||
switch (expr->type) | ||
{ | ||
case INT_TYPE: | ||
{ | ||
return expr; | ||
break; | ||
} | ||
case SYMBOL_TYPE: | ||
{ | ||
return expr; | ||
// return lookUpSymbol(expr, frame); | ||
break; | ||
} | ||
case CONS_TYPE: | ||
{ | ||
Value *first = car(expr); | ||
Value *args = cdr(expr); | ||
|
||
// if first is "if" | ||
if (strcmp(first->s, "if")) | ||
{ | ||
// Frame *result = evalIf(args, frame); | ||
} | ||
else if (strcmp(first->s, "let")) | ||
{ | ||
Frame *let_frame; | ||
let_frame->parent = frame; | ||
let_frame->bindings = makeNull(); | ||
|
||
Value *current = car(args); | ||
// evalLet | ||
while (!isNull(current)) | ||
{ | ||
if (current->type == CONS_TYPE) | ||
{ | ||
// valid symbol | ||
if (car(current)->type == SYMBOL_TYPE) | ||
{ | ||
Value *current_binding = car(current); | ||
|
||
// need to skip ahead twice so that our check for invalid binding works | ||
current = cdr(current); | ||
if (isNull(current)) | ||
{ | ||
printf("Syntax Error: incorrect number of arguments for function let\n"); | ||
texit(1); | ||
} | ||
else | ||
{ | ||
Value *current_value = car(current); | ||
// add this to the frame | ||
let_frame->bindings = cons(cons(current_binding, current_value), let_frame->bindings); | ||
|
||
current = cdr(current); | ||
} | ||
} | ||
else | ||
{ | ||
char symbol_type[10]; | ||
switch (car(current)->type) | ||
{ | ||
case INT_TYPE: | ||
strcpy(symbol_type, "INT"); | ||
break; | ||
case DOUBLE_TYPE: | ||
strcpy(symbol_type, "DOUBLE"); | ||
break; | ||
case STR_TYPE: | ||
strcpy(symbol_type, "STR"); | ||
break; | ||
default: | ||
strcpy(symbol_type, "OTHER"); | ||
} | ||
printf("Syntax Error: symbol of type %s not supported, unable to bind\n", symbol_type); | ||
texit(1); | ||
} | ||
} | ||
else | ||
{ | ||
printf("Syntax Error: incorrect number of arguments for function let\n"); | ||
texit(1); | ||
} | ||
current = cdr(current); | ||
} | ||
} | ||
|
||
// Other special forms go here... | ||
|
||
else | ||
{ | ||
// 'first' is not a recognized special form | ||
// evalationError(); | ||
printf("Symbol not recognized\n"); | ||
texit(1); | ||
} | ||
break; | ||
} | ||
} | ||
} | ||
|
||
/* | ||
interpret() | ||
call eval() on EVERY top-level node | ||
*/ | ||
void interpret(Value *tree) | ||
{ | ||
Value *current = tree; | ||
while (!isNull(current)) | ||
{ | ||
// make empty Frame | ||
Frame *empty_frame; | ||
empty_frame->bindings = makeNull(); | ||
eval(car(current), empty_frame); | ||
current = cdr(current); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
#ifndef _INTERPRETER | ||
#define _INTERPRETER | ||
|
||
void interpret(Value *tree); | ||
|
||
Value *eval(Value *expr, Frame *frame); | ||
|
||
#endif | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,164 @@ | ||
/* | ||
linkedlist.c | ||
Written by Victor Huang and Thien K. M. Bui | ||
Last modified 02/12/22 | ||
*/ | ||
|
||
#include <stdio.h> | ||
#include <stdlib.h> | ||
#include <assert.h> | ||
#include <string.h> | ||
|
||
#include "linkedlist.h" | ||
#include "talloc.h" | ||
// Create a pointer to a new NULL_TYPE Value (hint: where in memory will | ||
// the Value have to live?) | ||
Value *makeNull() | ||
{ | ||
Value *new_null = talloc(sizeof(Value)); | ||
new_null->type = NULL_TYPE; | ||
|
||
return new_null; | ||
} | ||
|
||
// Return whether the given pointer points at a NULL_TYPE Value. Use assertions | ||
// to make sure that this is a legitimate operation. See the assignment | ||
// instructions for further explanation on assertions. | ||
bool isNull(Value *value) | ||
{ | ||
if (value->type == NULL_TYPE) | ||
{ | ||
return true; | ||
} | ||
return false; | ||
} | ||
|
||
// Create a pointer to a new CONS_TYPE Value | ||
Value *cons(Value *newCar, Value *newCdr) | ||
{ | ||
Value *new_value = talloc(sizeof(Value)); | ||
new_value->type = CONS_TYPE; | ||
|
||
struct ConsCell new_cons_cell; | ||
new_cons_cell.car = newCar; | ||
new_cons_cell.cdr = newCdr; | ||
|
||
new_value->c = new_cons_cell; | ||
return new_value; | ||
} | ||
|
||
// Return a pointer to the car value for the cons cell at the head of the given | ||
// linked list. Use assertions here to make sure that this is a legitimate operation | ||
// (e.g., there is no car value at the head of an empty list). See the assignment | ||
// instructions for further explanation. | ||
Value *car(Value *list) | ||
{ | ||
// if not empty | ||
if (list->type == CONS_TYPE) | ||
{ | ||
return list->c.car; | ||
} | ||
else if (list->type == NULL_TYPE) | ||
{ | ||
return list; | ||
} | ||
// error, should never be of type int/null here | ||
else | ||
{ | ||
assert(false != true && "Incorrect type, something went wrong --kb"); | ||
return list; | ||
} | ||
} | ||
|
||
// Return a pointer to the cdr value for the cons cell at the head of the given linked | ||
// list. Again use assertions to make sure that this is a legitimate operation. | ||
Value *cdr(Value *list) | ||
{ | ||
// if not empty | ||
if (list->type == CONS_TYPE) | ||
{ | ||
return list->c.cdr; | ||
} | ||
else | ||
{ | ||
assert(false != true && "invalid operation on empty list --kb"); | ||
return list; | ||
} | ||
} | ||
|
||
// Display the contents of the linked list to the screen in the | ||
// format of a Scheme list -- e.g., ( 33 "lol" 9.9 ). It's okay | ||
// to just use printf here, though you'll have to add the quotes in | ||
// yourself, for strings. | ||
void display(Value *list) | ||
{ | ||
bool at_end = false; | ||
Value *current_value = list; | ||
|
||
printf("( "); | ||
while (!at_end) | ||
{ | ||
|
||
if (current_value->type == CONS_TYPE) | ||
{ | ||
// copy over whatever addresses are in the current ConsCell, it'll get deleted anyway so it doesn't matter | ||
struct ConsCell printed_value = current_value->c; | ||
// check the type of the car cell (Value typed pointer) | ||
switch (printed_value.car->type) | ||
{ | ||
case INT_TYPE: | ||
printf("%i ", printed_value.car->i); | ||
break; | ||
case DOUBLE_TYPE: | ||
printf("%f ", printed_value.car->d); | ||
break; | ||
case STR_TYPE: | ||
printf("\"%s\" ", printed_value.car->s); | ||
break; | ||
default: | ||
printf("%i", printed_value.car->i); | ||
} | ||
|
||
current_value = cdr(current_value); | ||
} | ||
else | ||
{ | ||
printf(")\n"); | ||
at_end = true; | ||
} | ||
} | ||
} | ||
|
||
// Return a new list that is the reverse of the one that is passed in. None of | ||
// the values in the original linked list should be copied this time. Instead, | ||
// create a new linked list of CONS_TYPE nodes whose car values point to the | ||
// corresponding car values in the original list. | ||
Value *reverse(Value *list) | ||
{ | ||
// copy over the current values into heap | ||
Value *current = list; | ||
Value *reverse_list = makeNull(); | ||
|
||
// at the last node of the list | ||
while (!isNull(current)) | ||
{ | ||
reverse_list = cons(car(current), reverse_list); | ||
current = cdr(current); | ||
} | ||
return reverse_list; | ||
} | ||
|
||
// Return the length of the given list, i.e., the number of cons cells. | ||
// Use assertions to make sure that this is a legitimate operation. | ||
int length(Value *value) | ||
{ | ||
|
||
int length = 0; | ||
Value *current = value; | ||
while (!isNull(current)) | ||
{ | ||
length = length + 1; | ||
current = cdr(current); | ||
} | ||
return length; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
#include <stdbool.h> | ||
#include "value.h" | ||
|
||
#ifndef _LINKEDLIST | ||
#define _LINKEDLIST | ||
|
||
// Create a pointer to a new NULL_TYPE Value (hint: where in memory will | ||
// the value have to live?) | ||
Value *makeNull(); | ||
|
||
// Return whether the given pointer points at a NULL_TYPE Value. Use assertions | ||
// to make sure that this is a legitimate operation. See the assignment | ||
// instructions for further explanation on assertions. | ||
bool isNull(Value *value); | ||
|
||
// Create a pointer to a new CONS_TYPE Value | ||
Value *cons(Value *newCar, Value *newCdr); | ||
|
||
// Return a pointer to the car value for the cons cell at the head of the given | ||
// linked list. Use assertions here to make sure that this is a legitimate operation | ||
// (e.g., there is no car value at the head of an empty list). See the assignment | ||
// instructions for further explanation. | ||
Value *car(Value *list); | ||
|
||
// Return a pointer to the cdr value for the cons cell at the head of the given linked | ||
// list. Again use assertions to make sure that this is a legitimate operation. | ||
Value *cdr(Value *list); | ||
|
||
// Display the contents of the linked list to the screen in the | ||
// format of a Scheme list -- e.g., ( 33 "lol" 9.9 ). It's okay | ||
// to just use printf here, though you'll have to add the quotes in | ||
// yourself, for strings. | ||
void display(Value *list); | ||
|
||
// Return a new list that is the reverse of the one that is passed in. None of | ||
// the values in the original linked list should be copied this time. Instead, | ||
// create a new linked list of CONS_TYPE nodes whose car values point to the | ||
// corresponding car values in the original list. | ||
Value *reverse(Value *list); | ||
|
||
// Return the length of the given list, i.e., the number of cons cells. | ||
// Use assertions to make sure that this is a legitimate operation. | ||
int length(Value *list); | ||
|
||
#endif |
Oops, something went wrong.