-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathstarter.c
164 lines (133 loc) · 3.94 KB
/
starter.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
/* this is file which initializes and starts interpreter */
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
#include "reader.h"
#include "evaluator.h"
#include "environment.h"
#define VECTOR_INIT_ALLOCATION 300
#define EXIT_COMMAND "exit\n"
#define HELP_COMMAND "help\n"
#define GARBAGE_COMMAND "gb()\n"
void init_environment();
void start_interpreter();
void dispose_environment();
int notSystemCommand(char * commandResult);
environment *global_env;//where global variables and functions are saved
vector *memory;//where every list node preserves until gb collector deletes them
int main(){
init_environment();
start_interpreter();
dispose_environment();
return 0;
}
/* initializes environment. gets ready memory and envaironment variables
* writes greeting messages */
void init_environment(){
printf("Welcome to scheme interpeter. have a good time! \n");
global_env = malloc(sizeof(environment));
EnvironmentNew(global_env, NULL);
memory = malloc(sizeof(vector));
VectorNew(memory, sizeof(listNode *), freeListNode, VECTOR_INIT_ALLOCATION);
//loadDefaultFunctions();
printf("We are ready to start (type exit() if you want to quit or help()) \n \n \n");
}
/* deleteas all allocated space with memory
* (doing this means we have finished working) with interpreter */
void dispose_environment(){
EnvironmentDispose(global_env);
free(global_env);
VectorDispose(memory);
free(memory);
}
/* starts read/eval/write loop of interpreter */
void start_interpreter(){
char comm[MAX_COMMAND_LENGTH];
strcpy(comm, "");//init comm to nothing
while (strcmp(comm, EXIT_COMMAND)){
readCommand(comm);
if (notSystemCommand(comm)){
listNode * curCommand = parseCommand(comm, memory);
listNode * commandResult = evalCommand(curCommand, global_env, memory);
if (commandResult == NULL)
continue;//error happend during parsing
printf(">: ");
writeResult(commandResult);
printf("\n");
}
}
}
void gb();
/* returns 1 if given command is not system command like help/exit or
* something else returs 0 otherwie */
int notSystemCommand(char * command){
if (!strcmp(command, EXIT_COMMAND)){
//user wants to quit interpreter
return 0;
}else if (!strcmp(command, HELP_COMMAND)){
//user wants to seee help
//displayHelp();
return 0;
}else if (!strcmp(command, GARBAGE_COMMAND)){
//user wants to run garbage collector
gb();
return 0;
}
return 1;
}
/************************************************/
/************garbage collector functions*********/
/************************************************/
/* markes given element as in use */
void mapfn(void *elemAddr, void *auxData){
listNode * elem = *((listNode **)elemAddr);
elem->inUse = 1;
}
/* compares given 2 int numbers */
int compare( const void* a, const void* b)
{
int int_a = * ( (int*) a );
int int_b = * ( (int*) b );
if ( int_a == int_b ) return 0;
else if ( int_a < int_b ) return -1;
else return 1;
}
/* unmarkes nodes which are still in use */
void unMarkGoodNodes(){
HashSetMap(global_env->env, mapfn, NULL);
}
/* marks all nodes as garbage */
void markAllAsGarbage(){
int vecSize = VectorLength(memory);
int i = 0;
for (; i < vecSize; i++){
listNode * elem = *((listNode **)VectorNth(memory, i));
elem->inUse = 0;
}
}
/* deletes nodes which are confirmed as garbage */
void deleteGarbage(){
int vecSize = VectorLength(memory);
int i = 0;
int delNum = 0;
int del[1000000];
for (; i < vecSize; i++){
listNode * elem = *((listNode **)VectorNth(memory, i));
if (elem->inUse == 0){
del[delNum] = i;
delNum++;
}
}
qsort(del, delNum, sizeof(int), compare);
for (i = 0; i < delNum; i++)
VectorDelete(memory, del[i] - i);
printf("GB() finished working. deleted nodes num = %d \n", delNum);
}
/* runs garbage collector */
void gb(){
printf("garbage Collector lunched !! \n");
markAllAsGarbage();
unMarkGoodNodes();
deleteGarbage();
}