Имплементирана процедура за дефиницање променљивих
This commit is contained in:
		
							parent
							
								
									da7568e644
								
							
						
					
					
						commit
						405739c217
					
				
					 9 changed files with 122 additions and 29 deletions
				
			
		
							
								
								
									
										4
									
								
								Makefile
									
										
									
									
									
								
							
							
						
						
									
										4
									
								
								Makefile
									
										
									
									
									
								
							|  | @ -7,8 +7,8 @@ VERSION = 0.5 | ||||||
| PREFIX = /usr/local | PREFIX = /usr/local | ||||||
| 
 | 
 | ||||||
| # флегови за C компајлер и линкер
 | # флегови за C компајлер и линкер
 | ||||||
| # CFLAGS   = -g -std=c99 -pedantic -Wall -O0
 | CFLAGS   = -g -std=c99 -pedantic -Wall -O0 | ||||||
| CFLAGS  = -std=c99 -pedantic -Wall -O1 | # CFLAGS  = -std=c99 -pedantic -Wall -O1
 | ||||||
| LDFLAGS = -lm -lc | LDFLAGS = -lm -lc | ||||||
| 
 | 
 | ||||||
| CC = cc | CC = cc | ||||||
|  |  | ||||||
							
								
								
									
										11
									
								
								eval.c
									
										
									
									
									
								
							
							
						
						
									
										11
									
								
								eval.c
									
										
									
									
									
								
							|  | @ -20,7 +20,14 @@ object eval(object input) | ||||||
| 	{ | 	{ | ||||||
| 		if (symbolExists(SYM(input))) | 		if (symbolExists(SYM(input))) | ||||||
| 		{ | 		{ | ||||||
| 			result = copyObject(input); | 			if (typeOf(SYM(input)) == variableSymbol) | ||||||
|  | 			{ | ||||||
|  | 				result = referVariable(SYM(input)); | ||||||
|  | 			} | ||||||
|  | 			else | ||||||
|  | 			{ | ||||||
|  | 				result = copyObject(input); | ||||||
|  | 			} | ||||||
| 		} | 		} | ||||||
| 		else | 		else | ||||||
| 		{ | 		{ | ||||||
|  | @ -42,7 +49,7 @@ object eval(object input) | ||||||
| 			while (TYPE(*currentCell) != nilObject) | 			while (TYPE(*currentCell) != nilObject) | ||||||
| 			{ | 			{ | ||||||
| 				if (TYPE(CAR(input)) != symbolObject || | 				if (TYPE(CAR(input)) != symbolObject || | ||||||
| 					strcmp(SYM(CAR(input)), "навод") != 0) | 					!isSpecialForm(SYM(CAR(input)))) | ||||||
| 				{ | 				{ | ||||||
| 					CAR(*currentCell) = | 					CAR(*currentCell) = | ||||||
| 						eval(CAR(*currentCell)); | 						eval(CAR(*currentCell)); | ||||||
|  |  | ||||||
							
								
								
									
										1
									
								
								init.c
									
										
									
									
									
								
							
							
						
						
									
										1
									
								
								init.c
									
										
									
									
									
								
							|  | @ -21,6 +21,7 @@ void init() | ||||||
| 	addSymbolInternal("*", &multiply); | 	addSymbolInternal("*", &multiply); | ||||||
| 	addSymbolInternal("/", ÷); | 	addSymbolInternal("/", ÷); | ||||||
| 	addSymbolInternal("навод", "e); | 	addSymbolInternal("навод", "e); | ||||||
|  | 	addSymbolInternal("дефиниши", &define); | ||||||
| 	addSymbolInternal("тачно->нетачно", &exactToInexact); | 	addSymbolInternal("тачно->нетачно", &exactToInexact); | ||||||
| 	addSymbolInternal("нетачно->тачно", &inexactToExact); | 	addSymbolInternal("нетачно->тачно", &inexactToExact); | ||||||
| } | } | ||||||
|  |  | ||||||
							
								
								
									
										20
									
								
								internals.c
									
										
									
									
									
								
							
							
						
						
									
										20
									
								
								internals.c
									
										
									
									
									
								
							|  | @ -1,4 +1,6 @@ | ||||||
|  | #include "symtable.h" | ||||||
| #include "util.h" | #include "util.h" | ||||||
|  | #include "eval.h" | ||||||
| 
 | 
 | ||||||
| int allNumbers(object list) | int allNumbers(object list) | ||||||
| { | { | ||||||
|  | @ -189,3 +191,21 @@ object quote(object parameters) | ||||||
| 	} | 	} | ||||||
| 	return result; | 	return result; | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | object define(object parameters) | ||||||
|  | { | ||||||
|  | 	object result; | ||||||
|  | 	if (listLength(parameters) != 2) | ||||||
|  | 	{ | ||||||
|  | 		TYPE(result) = errorObject; | ||||||
|  | 		ERR(result) = argumentNumberError; | ||||||
|  | 	} | ||||||
|  | 	else if (TYPE(CAR(parameters)) == symbolObject) | ||||||
|  | 	{ | ||||||
|  | 		result = copyObject(CAR(parameters)); | ||||||
|  | 		addSymbolVariable(SYM(result), | ||||||
|  | 				eval(copyObject(CAR(CDR(parameters))))); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return result; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @ -1,4 +1,5 @@ | ||||||
| #pragma once | #pragma once | ||||||
|  | #include "util.h" | ||||||
| 
 | 
 | ||||||
| object add(object parameters); | object add(object parameters); | ||||||
| object subtract(object parameters); | object subtract(object parameters); | ||||||
|  | @ -7,3 +8,4 @@ object divide(object parameters); | ||||||
| object exactToInexact(object parameters); | object exactToInexact(object parameters); | ||||||
| object inexactToExact(object parameters); | object inexactToExact(object parameters); | ||||||
| object quote(object parameters); | object quote(object parameters); | ||||||
|  | object define(object parameters); | ||||||
|  |  | ||||||
							
								
								
									
										80
									
								
								symtable.c
									
										
									
									
									
								
							
							
						
						
									
										80
									
								
								symtable.c
									
										
									
									
									
								
							|  | @ -5,12 +5,6 @@ | ||||||
| #include "util.h" | #include "util.h" | ||||||
| #include "symtable.h" | #include "symtable.h" | ||||||
| 
 | 
 | ||||||
| typedef enum |  | ||||||
| { |  | ||||||
| 	internalSymbol, |  | ||||||
| 	objectSymbol |  | ||||||
| } symbolType; |  | ||||||
| 
 |  | ||||||
| typedef struct entry | typedef struct entry | ||||||
| { | { | ||||||
| 	symbolType type; | 	symbolType type; | ||||||
|  | @ -18,7 +12,7 @@ typedef struct entry | ||||||
| 	union | 	union | ||||||
| 	{ | 	{ | ||||||
| 		object (*function)(); | 		object (*function)(); | ||||||
| 		object definition; | 		object variable; | ||||||
| 	} value; | 	} value; | ||||||
| 	struct entry *left; | 	struct entry *left; | ||||||
| 	struct entry *right; | 	struct entry *right; | ||||||
|  | @ -54,47 +48,67 @@ entry **findEntry(entry **current, char *symbol) | ||||||
| 	 * одвојене ради читљивости */ | 	 * одвојене ради читљивости */ | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void freeEntry(entry **current) | ||||||
|  | { | ||||||
|  | 	free((*current)->name); | ||||||
|  | 	if ((*current)->type == variableSymbol) | ||||||
|  | 	{ | ||||||
|  | 		deleteObject((*current)->value.variable); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | symbolType typeOf(char *symbol) | ||||||
|  | { | ||||||
|  | 	entry **e = findEntry(&root, symbol); | ||||||
|  | 
 | ||||||
|  | 	return (*e)->type; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| int addSymbolInternal(char *symbol, object (*function)()) | int addSymbolInternal(char *symbol, object (*function)()) | ||||||
| { | { | ||||||
| 	int status = 1; | 	int status = 1; | ||||||
| 	entry **e = findEntry(&root, symbol); | 	entry **e = findEntry(&root, symbol); | ||||||
| 
 | 
 | ||||||
| 	if (*e == NULL) | 	if (*e != NULL) | ||||||
| 	{ | 	{ | ||||||
| 		*e = malloc(sizeof(entry)); | 		status = 0; | ||||||
| 		(*e)->type = internalSymbol; | 		freeEntry(e); | ||||||
| 		(*e)->name = malloc(sizeof(char) * (strlen(symbol) + 1)); |  | ||||||
| 		strcpy((*e)->name, symbol); |  | ||||||
| 		(*e)->value.function = function; |  | ||||||
| 		(*e)->left = (*e)->right = NULL; |  | ||||||
| 	} | 	} | ||||||
| 	else | 	else | ||||||
| 	{ | 	{ | ||||||
| 		status = 0; | 		*e = malloc(sizeof(entry)); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	(*e)->type = internalSymbol; | ||||||
|  | 	(*e)->name = malloc(sizeof(char) * (strlen(symbol) + 1)); | ||||||
|  | 	strcpy((*e)->name, symbol); | ||||||
|  | 	(*e)->value.function = function; | ||||||
|  | 	(*e)->left = (*e)->right = NULL; | ||||||
|  | 
 | ||||||
| 	return status; | 	return status; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| int addSymbolDefinition(char *symbol, object definition) | int addSymbolVariable(char *symbol, object variable) | ||||||
| { | { | ||||||
| 	int status = 1; | 	int status = 1; | ||||||
| 	entry **e = findEntry(&root, symbol); | 	entry **e = findEntry(&root, symbol); | ||||||
| 
 | 
 | ||||||
| 	if (*e == NULL) | 	if (*e != NULL) | ||||||
| 	{ | 	{ | ||||||
| 		*e = malloc(sizeof(entry)); | 		status = 0; | ||||||
| 		(*e)->type = objectSymbol; | 		freeEntry(e); | ||||||
| 		(*e)->name = malloc(sizeof(char) * (strlen(symbol) + 1)); |  | ||||||
| 		strcpy((*e)->name, symbol); |  | ||||||
| 		(*e)->value.definition = copyObject(definition); |  | ||||||
| 		(*e)->left = (*e)->right = NULL; |  | ||||||
| 	} | 	} | ||||||
| 	else | 	else | ||||||
| 	{ | 	{ | ||||||
| 		status = 0; | 		*e = malloc(sizeof(entry)); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	(*e)->type = variableSymbol; | ||||||
|  | 	(*e)->name = malloc(sizeof(char) * (strlen(symbol) + 1)); | ||||||
|  | 	strcpy((*e)->name, symbol); | ||||||
|  | 	(*e)->value.variable = copyObject(variable); | ||||||
|  | 	(*e)->left = (*e)->right = NULL; | ||||||
|  | 
 | ||||||
| 	return status; | 	return status; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -128,3 +142,21 @@ object (*internalFunction(char *symbol)) (object) | ||||||
| 		return ((*e)->value.function); | 		return ((*e)->value.function); | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | object referVariable(char *symbol) | ||||||
|  | { | ||||||
|  | 	object result; | ||||||
|  | 	entry **e = findEntry(&root, symbol); | ||||||
|  | 
 | ||||||
|  | 	if (*e == NULL || (*e)->type != variableSymbol) | ||||||
|  | 	{ | ||||||
|  | 		TYPE(result) = errorObject; | ||||||
|  | 		ERR(result) = unrecognizedSymbolError; | ||||||
|  | 	} | ||||||
|  | 	else | ||||||
|  | 	{ | ||||||
|  | 		result = (*e)->value.variable; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return result; | ||||||
|  | } | ||||||
|  |  | ||||||
							
								
								
									
										11
									
								
								symtable.h
									
										
									
									
									
								
							
							
						
						
									
										11
									
								
								symtable.h
									
										
									
									
									
								
							|  | @ -2,16 +2,25 @@ | ||||||
| 
 | 
 | ||||||
| #include "util.h" | #include "util.h" | ||||||
| 
 | 
 | ||||||
|  | typedef enum | ||||||
|  | { | ||||||
|  | 	internalSymbol, | ||||||
|  | 	variableSymbol | ||||||
|  | } symbolType; | ||||||
|  | 
 | ||||||
| int addSymbolInternal(char *symbol, object (*function)()); | int addSymbolInternal(char *symbol, object (*function)()); | ||||||
| int addSymbolDefinition(char *symbol, object definition); | int addSymbolVariable(char *symbol, object variable); | ||||||
| /* служе за различите методе дефинисања нових симбола у језику
 | /* служе за различите методе дефинисања нових симбола у језику
 | ||||||
|  * враћају 1 уколико је нови симбол успешно додат, а 0 уколико није |  * враћају 1 уколико је нови симбол успешно додат, а 0 уколико није | ||||||
|  * (постоји симбол са истим именом) */ |  * (постоји симбол са истим именом) */ | ||||||
| 
 | 
 | ||||||
| int symbolExists(char *symbol); | int symbolExists(char *symbol); | ||||||
| /* враћа 1 уколико симбол постоји и 0 у супротном */ | /* враћа 1 уколико симбол постоји и 0 у супротном */ | ||||||
|  | symbolType typeOf(char *symbol); | ||||||
| 
 | 
 | ||||||
| object (*internalFunction(char *symbol)) (object parameters); | object (*internalFunction(char *symbol)) (object parameters); | ||||||
| /* враћа показивач на функцију уколико је симбол дефинисан као интерна
 | /* враћа показивач на функцију уколико је симбол дефинисан као интерна
 | ||||||
|  * функција, NULL уколико симбол није функција или уколико не постоји |  * функција, NULL уколико симбол није функција или уколико не постоји | ||||||
|  * */ |  * */ | ||||||
|  | object referVariable(char *symbol); | ||||||
|  | /* враћа вредност на коју се односи име симбола у табели */ | ||||||
|  |  | ||||||
							
								
								
									
										21
									
								
								util.c
									
										
									
									
									
								
							
							
						
						
									
										21
									
								
								util.c
									
										
									
									
									
								
							|  | @ -5,6 +5,27 @@ | ||||||
| 
 | 
 | ||||||
| #include "util.h" | #include "util.h" | ||||||
| 
 | 
 | ||||||
|  | #define SPECIALFORMSNUM 2 | ||||||
|  | int isSpecialForm(char *symbol) | ||||||
|  | { | ||||||
|  | 	int result = 0; | ||||||
|  | 	char *specialForms[] = | ||||||
|  | 	{ | ||||||
|  | 		"навод", | ||||||
|  | 		"дефиниши" | ||||||
|  | 	}; | ||||||
|  | 
 | ||||||
|  | 	for (int i = 0; i < SPECIALFORMSNUM; ++i) | ||||||
|  | 	{ | ||||||
|  | 		if (!strcmp(symbol, specialForms[i])) | ||||||
|  | 		{ | ||||||
|  | 			result = 1; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return result; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| int properList(object list) | int properList(object list) | ||||||
| { | { | ||||||
| 	object *current = &list; | 	object *current = &list; | ||||||
|  |  | ||||||
							
								
								
									
										1
									
								
								util.h
									
										
									
									
									
								
							
							
						
						
									
										1
									
								
								util.h
									
										
									
									
									
								
							|  | @ -75,6 +75,7 @@ struct cons | ||||||
| 	object cdr; | 	object cdr; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | int isSpecialForm(char *symbol); | ||||||
| int properList(object list); | int properList(object list); | ||||||
| int listLength(object list); | int listLength(object list); | ||||||
| void deleteObject(object input); | void deleteObject(object input); | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		
		Reference in a new issue
	
	 kappa
						kappa