├── .gitignore
├── LICENSE
├── README.md
├── String.c
├── String.h
├── hmap.c
├── hmap.h
├── libs
├── String.c
├── String.h
├── String.n
├── makefile
└── test
├── makefile
├── nymph
├── nymph.c
└── nymph.h
/.gitignore:
--------------------------------------------------------------------------------
1 | experimental
2 | .vscode
3 | tests
4 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 Brandon Barber
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |

2 |
3 | Nymph
4 |
5 | Let's see what we can achieve by reworking C syntax.
6 |
7 | ## Overview
8 |
9 | Nymph is a simple C like programming language.
10 |
11 | Nymph acts as a preprocessor, converting Nymph files (extension \*.n) into C files.
12 |
13 | This project is very much in development... It is not production ready.
14 |
15 | ## What's New
16 |
17 | Nothing right now
18 |
19 | ## Goals
20 |
21 | ### Completed
22 |
23 | * Class-Based OOP
24 |
25 | * Subtyping
26 |
27 | ### In Progress
28 |
29 | * TBD
30 |
31 | ### Pending
32 |
33 | * Destructors?
34 |
35 | * Type Inference?
36 |
37 | * Reflection?
38 |
39 | * Default function arguments?
40 |
41 | * Lambdas?
42 |
43 | ## Example
44 |
45 | mammal.n
46 | ```
47 | #include
48 | #include
49 |
50 | class Mammal {
51 |
52 | + int population = 0; // Class Variable (+)
53 | - int height = 0, weight = 100; // Object Variable (-)
54 |
55 | + Mammal *init(int height, int weight) { // Class Method (+) Constructor
56 | this->height = height;
57 | this->weight = weight;
58 | Mammal->population++;
59 | return this;
60 | }
61 |
62 | - void print() { // Object Method (-)
63 | printf("print instance properties...\n");
64 | }
65 | }
66 | ```
67 |
68 | human.n
69 | ```
70 | #include "mammal.n"
71 | #include
72 | #include
73 |
74 | class Human : Mammal {
75 |
76 | - char *name = NULL; // Object Variable (-)
77 |
78 | + Human *init(char *name, int height, int weight) { // Class Method (+) Constructor
79 | this = super->init(height, weight);
80 | this->name = name;
81 | return this;
82 | }
83 |
84 | - void died() { // Object Method (-) Constructor
85 | free(this->name);
86 | free(this);
87 | Mammal->population--;
88 | }
89 | }
90 |
91 | int main(void) {
92 |
93 | char *name = malloc(5);
94 | memset(name, 0, sizeof(name));
95 | strcpy(name, "Fred");
96 | Human *person1 = Human->init(name, 76, 146); // Class Method Constructor Call
97 | person1->print(); // Object Method Call
98 | person1->died(); // Object Method Call
99 |
100 | return 0;
101 | }
102 | ```
103 |
104 | ```
105 | nymph -r human.n
106 | ```
107 |
--------------------------------------------------------------------------------
/String.c:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelswarm/nymph/5d6088f25933494fb9a722a8fe202ec0280df714/String.c
--------------------------------------------------------------------------------
/String.h:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelswarm/nymph/5d6088f25933494fb9a722a8fe202ec0280df714/String.h
--------------------------------------------------------------------------------
/hmap.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 |
6 | #include "hmap.h"
7 |
8 | struct HMap
9 | {
10 | char *key;
11 | void *value;
12 | HMap *next;
13 | };
14 |
15 | int hash(char *key)
16 | {
17 | int hash = 0;
18 | int len = strlen(key);
19 | for (int i = 0; i < len; i++)
20 | {
21 | hash += ((unsigned int)key[i] * 11);
22 | }
23 | return hash %= 10000;
24 | }
25 |
26 | HMap **create_hm()
27 | {
28 | HMap **hashmap = malloc(10000 * sizeof(HMap *));
29 | for (int i = 0; i < 10000; i++)
30 | {
31 | hashmap[i] = NULL;
32 | }
33 | return hashmap;
34 | }
35 |
36 | void update_hm(HMap **map, char *key, void *value)
37 | {
38 | int idx = hash(key);
39 | HMap *row = map[idx];
40 |
41 | if (row == NULL)
42 | {
43 | row = malloc(sizeof(HMap));
44 | row->key = malloc(1000 * sizeof(char));
45 | row->value = NULL;
46 | row->next = NULL;
47 | strcpy(row->key, key);
48 | row->value = value;
49 | map[idx] = row;
50 | return;
51 | }
52 |
53 | while (row->next != NULL && (strcmp(row->key, key) != 0))
54 | {
55 | row = row->next;
56 | }
57 | if (strcmp(row->key, key) == 0)
58 | {
59 | strcpy(row->key, key);
60 | row->value = value;
61 | }
62 | else
63 | {
64 | HMap *node = malloc(sizeof(HMap));
65 | node->key = malloc(1000 * sizeof(char));
66 | node->next = NULL;
67 | strcpy(node->key, key);
68 | node->value = value;
69 | row->next = node;
70 | }
71 | }
72 |
73 | void *fetch_hm(HMap **map, char *key)
74 | {
75 | int idx = hash(key);
76 | HMap *row = map[idx];
77 | if (row == NULL)
78 | {
79 | return NULL;
80 | }
81 | while (row->next != NULL && (strcmp(row->key, key) != 0))
82 | {
83 | row = row->next;
84 | }
85 | if (strcmp(row->key, key) == 0)
86 | {
87 | return row->value;
88 | }
89 | return NULL;
90 | }
91 |
92 | void remove_hm(HMap **map, char *key)
93 | {
94 | int idx = hash(key);
95 | HMap *row = map[idx];
96 | HMap *prev = NULL;
97 | while (row->next != NULL && (strcmp(row->key, key) != 0))
98 | {
99 | prev = row;
100 | row = row->next;
101 | }
102 | if (prev == NULL)
103 | {
104 | HMap *tmp = row->next;
105 | free(row->key);
106 | free(row);
107 | map[idx] = tmp;
108 | }
109 | else
110 | {
111 | prev->next = row->next;
112 | free(row->key);
113 | free(row);
114 | }
115 | }
116 |
117 | void free_hm(HMap **map)
118 | {
119 | for (int i = 0; i < 10000; i++)
120 | {
121 | HMap *row = map[i];
122 | while (row != NULL)
123 | {
124 | if (row->key != NULL)
125 | {
126 | free(row->key);
127 | }
128 | HMap *tmp = row->next;
129 |
130 | if (row != NULL)
131 | {
132 | free(row);
133 | }
134 | row = tmp;
135 | }
136 | }
137 | free(map);
138 | }
139 |
--------------------------------------------------------------------------------
/hmap.h:
--------------------------------------------------------------------------------
1 | typedef struct HMap HMap;
2 |
3 | HMap **create_hm(void);
4 |
5 | void update_hm(HMap **, char *, void *);
6 |
7 | void *fetch_hm(HMap **, char *);
8 |
9 | void remove_hm(HMap **, char *);
10 |
11 | void free_hm(HMap **);
12 |
--------------------------------------------------------------------------------
/libs/String.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include
6 |
7 | #include "String.h"
8 |
9 | Object_String* initString( char * text);
10 | void reallocString( Object_String *this, int size);
11 | void valueString( Object_String *this, char * text);
12 | void printlnString( Object_String *this);
13 | int indexOfString( Object_String *this, char * text);
14 | int lastIndexOfString( Object_String *this, char * text);
15 | char* sliceString( Object_String *this, int start, int end);
16 | void replaceString( Object_String *this, char * target, char * text);
17 | void toLowerCaseString( Object_String *this);
18 | void toUpperCaseString( Object_String *this);
19 | char* appendString( Object_String *this, char * text);
20 | char* prependString( Object_String *this, char * text);
21 | void trimString( Object_String *this);
22 | Object_String* initString( char * text) {
23 | Object_String *this = malloc(sizeof(Object_String));
24 | this->reallocString = &reallocString;
25 | this->valueString = &valueString;
26 | this->printlnString = &printlnString;
27 | this->indexOfString = &indexOfString;
28 | this->lastIndexOfString = &lastIndexOfString;
29 | this->sliceString = &sliceString;
30 | this->replaceString = &replaceString;
31 | this->toLowerCaseString = &toLowerCaseString;
32 | this->toUpperCaseString = &toUpperCaseString;
33 | this->appendString = &appendString;
34 | this->prependString = &prependString;
35 | this->trimString = &trimString;
36 | this->value = NULL;
37 | this->size = 0;
38 |
39 | this->value=(char*)malloc((sizeof(text)+1)*sizeof(char));
40 | memset(this->value,0,sizeof(this->value));
41 | this->size=sizeof(text);
42 | this->valueString(this,text);
43 | return this;
44 | }
45 | void reallocString( Object_String *this, int size) {
46 |
47 | char*new=(char*)malloc(size);
48 | memset(new,0,sizeof(new));
49 | for(int i=0;isize;++i){
50 | new[i]=this->value[i];
51 | }
52 | this->size=size;
53 | free(this->value);
54 | this->value=new;
55 | }
56 | void valueString( Object_String *this, char * text) {
57 |
58 | if(strlen(text)>=this->size){
59 | this->reallocString(this,strlen(text));
60 | }
61 | strncpy(this->value,text,this->size);
62 | }
63 | void printlnString( Object_String *this) {
64 |
65 | int len=strlen(this->value);
66 | for(int i=0;ivalue[i]);
68 | }
69 | printf("\n");
70 | }
71 | int indexOfString( Object_String *this, char * text) {
72 |
73 | char*p=strstr(this->value,text);
74 | return p<0?-1:(int)(p-this->value);
75 | }
76 | int lastIndexOfString( Object_String *this, char * text) {
77 |
78 | char*tmp=(void*)this->value,*p=0;
79 | while((tmp=strstr(tmp,text))!=NULL){
80 | p=tmp;
81 | ++tmp;
82 | }
83 | return p<0?-1:(int)(p-this->value);
84 | }
85 | char* sliceString( Object_String *this, int start, int end) {
86 |
87 | int len=end-start;
88 | char*r=(char*)malloc((len+1)*sizeof(char));
89 | memset(r,0,sizeof(r));
90 | for(int i=0;ivalue[start+i];
92 | }
93 | return r;
94 | }
95 | void replaceString( Object_String *this, char * target, char * text) {
96 |
97 | int p=this->indexOfString(this,target);
98 | if(p<0){
99 | return;
100 | }
101 | if(strlen(target)reallocString(this,strlen(text)-strlen(target)+this->size);
103 | }
104 | int len=strlen(text);
105 | for(int i=0;ivalue[p+i]=text[i];
107 | }
108 | }
109 | void toLowerCaseString( Object_String *this) {
110 |
111 | for(int i=0;isize;++i){
112 | int val=this->value[i];
113 | if(val>64&&val<91){
114 | this->value[i]=val+32;
115 | }
116 | }
117 | }
118 | void toUpperCaseString( Object_String *this) {
119 |
120 | for(int i=0;isize;++i){
121 | int val=this->value[i];
122 | if(val>96&&val<123){
123 | this->value[i]=val-32;
124 | }
125 | }
126 | }
127 | char* appendString( Object_String *this, char * text) {
128 |
129 | int start=strlen(this->value);
130 | int len=strlen(text);
131 | this->reallocString(this,len+this->size);
132 | for(int i=0;ivalue[start+i]=text[i];
134 | }
135 | }
136 | char* prependString( Object_String *this, char * text) {
137 |
138 | int len=strlen(text);
139 | char*new=(char*)malloc(len+this->size);
140 | memset(new,0,sizeof(new));
141 | for(int i=0;ivalue);++i){
145 | new[i+len]=this->value[i];
146 | }
147 | free(this->value);
148 | this->value=new;
149 | }
150 | void trimString( Object_String *this) {
151 |
152 | char*tmp1=this->value;
153 | while(isspace(tmp1[0])!=0&&tmp1[0]!=0){
154 | ++tmp1;
155 | }
156 | char*tmp2=tmp1+1;
157 | while(isspace(tmp2[0])==0||tmp2[0]==0){
158 | ++tmp2;
159 | }
160 | if(tmp2-tmp1<=0){
161 | return;
162 | }
163 | char*new=(char*)malloc(tmp2-tmp1+1);
164 | strncpy(new,tmp1,(int)(tmp2-tmp1));
165 | free(this->value);
166 | this->value=new;
167 | }
168 | void startString() {
169 | if(Class_String_Instance == NULL) {
170 | Class_String_Instance = malloc(sizeof(Class_String_Instance));
171 | Class_String_Instance->initString = &initString;
172 | }
173 | }
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 | int main (void ){
183 | startString();
184 |
185 |
186 | Object_String*helloWorld =Class_String_Instance->initString("Hello World");
187 | helloWorld->printlnString(helloWorld);
188 | helloWorld->valueString(helloWorld,"This is me!");
189 | helloWorld->printlnString(helloWorld);
190 | printf ("%i\n",helloWorld->indexOfString(helloWorld,"is"));
191 | printf ("%i\n",helloWorld->lastIndexOfString(helloWorld,"is"));
192 | printf ("%s\n",helloWorld->sliceString(helloWorld,2 ,6 ));
193 | helloWorld->replaceString(helloWorld,"me","bladerunner");
194 | helloWorld->printlnString(helloWorld);
195 | helloWorld->toUpperCaseString(helloWorld);
196 | helloWorld->printlnString(helloWorld);
197 | helloWorld->toLowerCaseString(helloWorld);
198 | helloWorld->printlnString(helloWorld);
199 | helloWorld->appendString(helloWorld,"blahblahblah b");
200 | helloWorld->printlnString(helloWorld);
201 | helloWorld->prependString(helloWorld," blahblahblah ");
202 | helloWorld->printlnString(helloWorld);
203 | helloWorld->trimString(helloWorld);
204 | helloWorld->printlnString(helloWorld);
205 |
206 | return 0 ;
207 | }
--------------------------------------------------------------------------------
/libs/String.h:
--------------------------------------------------------------------------------
1 | typedef struct Class_String Class_String;
2 | typedef struct Object_String Object_String;
3 | Class_String *Class_String_Instance;
4 | struct Class_String {
5 | Object_String*(*initString)(char * text);
6 | };
7 | struct Object_String {
8 | char* value;
9 | int size;
10 | void(*reallocString)(Object_String *this, int size);
11 | void(*valueString)(Object_String *this, char * text);
12 | void(*printlnString)(Object_String *this);
13 | int(*indexOfString)(Object_String *this, char * text);
14 | int(*lastIndexOfString)(Object_String *this, char * text);
15 | char*(*sliceString)(Object_String *this, int start, int end);
16 | void(*replaceString)(Object_String *this, char * target, char * text);
17 | void(*toLowerCaseString)(Object_String *this);
18 | void(*toUpperCaseString)(Object_String *this);
19 | char*(*appendString)(Object_String *this, char * text);
20 | char*(*prependString)(Object_String *this, char * text);
21 | void(*trimString)(Object_String *this);
22 | };
23 | void startString();
24 |
--------------------------------------------------------------------------------
/libs/String.n:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include
6 |
7 | class String {
8 |
9 | - char *value = NULL;
10 | - int size = 0;
11 |
12 | + String *init(char *text) {
13 | this->value = (char *)malloc((sizeof(text) + 1) * sizeof(char));
14 | memset(this->value, 0, sizeof(this->value));
15 | this->size = sizeof(text);
16 | this->value(text);
17 | return this;
18 | }
19 |
20 | - void realloc(int size) {
21 | char *new = (char *)malloc(size);
22 | memset(new, 0, sizeof(new));
23 | for(int i = 0; isize; ++i) {
24 | new[i] = this->value[i];
25 | }
26 | this->size = size;
27 | free(this->value);
28 | this->value = new;
29 | }
30 |
31 | - void value(char *text) {
32 | if(strlen(text) >= this->size) {
33 | this->realloc(strlen(text));
34 | }
35 | strncpy(this->value, text, this->size);
36 | }
37 |
38 | - void println() {
39 | int len = strlen(this->value);
40 | for(int i=0; ivalue[i]);
42 | }
43 | printf("\n");
44 | }
45 |
46 | - int indexOf(char *text) {
47 | char *p = strstr(this->value, text);
48 | return p < 0 ? -1 : (int)(p - this->value);
49 | }
50 |
51 | - int lastIndexOf(char *text) {
52 | char *tmp = (void *)this->value, *p = 0;
53 | while((tmp = strstr(tmp, text)) != NULL) {
54 | p = tmp;
55 | ++tmp;
56 | }
57 | return p < 0 ? -1 : (int)(p - this->value);
58 | }
59 |
60 | - char *slice(int start, int end) {
61 | int len = end - start;
62 | char *r = (char *)malloc((len + 1) * sizeof(char));
63 | memset(r, 0, sizeof(r));
64 | for(int i = 0; i < len; ++i) {
65 | r[i] = this->value[start + i];
66 | }
67 | return r;
68 | }
69 |
70 | - void replace(char *target, char *text) {
71 | int p = this->indexOf(target);
72 | if(p < 0) {
73 | return;
74 | }
75 | if(strlen(target) < strlen(text)) {
76 | this->realloc(strlen(text) - strlen(target) + this->size);
77 | }
78 | int len = strlen(text);
79 | for(int i=0; ivalue[p + i] = text[i];
81 | }
82 | }
83 |
84 | - void toLowerCase() {
85 | for(int i=0; isize; ++i) {
86 | int val = this->value[i];
87 | if(val > 64 && val < 91) {
88 | this->value[i] = val + 32;
89 | }
90 | }
91 | }
92 |
93 | - void toUpperCase() {
94 | for(int i=0; isize; ++i) {
95 | int val = this->value[i];
96 | if(val > 96 && val < 123) {
97 | this->value[i] = val - 32;
98 | }
99 | }
100 | }
101 |
102 | - char *append(char *text) {
103 | int start = strlen(this->value);
104 | int len = strlen(text);
105 | this->realloc(len + this->size);
106 | for(int i=0; ivalue[start + i] = text[i];
108 | }
109 | }
110 |
111 | - char *prepend(char *text) {
112 | int len = strlen(text);
113 | char *new = (char *)malloc(len + this->size);
114 | memset(new, 0, sizeof(new));
115 | for(int i = 0; ivalue); ++i) {
119 | new[i + len] = this->value[i];
120 | }
121 | free(this->value);
122 | this->value = new;
123 | }
124 |
125 | - void trim() {
126 | char *tmp1 = this->value;
127 | while(isspace(tmp1[0]) != 0 && tmp1[0] != 0) {
128 | ++tmp1;
129 | }
130 | char *tmp2 = tmp1 + 1;
131 | while(isspace(tmp2[0]) == 0 || tmp2[0] == 0) {
132 | ++tmp2;
133 | }
134 | if(tmp2 - tmp1 <= 0) {
135 | return;
136 | }
137 | char *new = (char *)malloc(tmp2 - tmp1 + 1);
138 | strncpy(new, tmp1, (int)(tmp2 - tmp1));
139 | free(this->value);
140 | this->value = new;
141 | }
142 |
143 | }
144 |
145 | int main(void) {
146 |
147 | String *helloWorld = String->init("Hello World"); // Class Method Constructor Call
148 | helloWorld->println();
149 | helloWorld->value("This is me!");
150 | helloWorld->println();
151 | printf("%i\n", helloWorld->indexOf("is"));
152 | printf("%i\n", helloWorld->lastIndexOf("is"));
153 | printf("%s\n", helloWorld->slice(2, 6));
154 | helloWorld->replace("me", "bladerunner");
155 | helloWorld->println();
156 | helloWorld->toUpperCase();
157 | helloWorld->println();
158 | helloWorld->toLowerCase();
159 | helloWorld->println();
160 | helloWorld->append("blahblahblah b");
161 | helloWorld->println();
162 | helloWorld->prepend(" blahblahblah ");
163 | helloWorld->println();
164 | helloWorld->trim();
165 | helloWorld->println();
166 |
167 | return 0;
168 | }
--------------------------------------------------------------------------------
/libs/makefile:
--------------------------------------------------------------------------------
1 | default:
2 | cd ..; sudo make; cd libs;
3 | nymph -r String.n;
4 | gcc -std=c11 String.c -o test
5 |
--------------------------------------------------------------------------------
/libs/test:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelswarm/nymph/5d6088f25933494fb9a722a8fe202ec0280df714/libs/test
--------------------------------------------------------------------------------
/makefile:
--------------------------------------------------------------------------------
1 | default: nymph.c nymph.h hmap.c hmap.h
2 | gcc -std=c11 -g nymph.c hmap.c -o nymph
3 | cp nymph /usr/local/bin
--------------------------------------------------------------------------------
/nymph:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maelswarm/nymph/5d6088f25933494fb9a722a8fe202ec0280df714/nymph
--------------------------------------------------------------------------------
/nymph.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include "nymph.h"
6 | #include "hmap.h"
7 |
8 | #define PUBLIC_CLASS_FUNC 0
9 | #define PUBLIC_OBJECT_FUNC 1
10 | #define PRIVATE_OBJECT_FUNC 2
11 | #define PUBLIC_FUNC 3
12 | #define PRIVATE_FUNC 4
13 |
14 | #define PUBLIC_CLASS_VAR 0
15 | #define PUBLIC_OBJECT_VAR 1
16 | #define PRIVATE_OBJECT_VAR 2
17 | #define PUBLIC_VAR 3
18 | #define PRIVATE_VAR 4
19 |
20 | void tokenize(char *, NFile *);
21 | void addToken(NFile *, Token *, char);
22 | void appendToken(NFile *, char *, char);
23 |
24 | int isClassInstance(NFile *, char *);
25 |
26 | char rootfilename[100];
27 |
28 | struct NFile
29 | {
30 | char *filename;
31 | FILE *fileN;
32 | FILE *fileC;
33 | FILE *fileH;
34 |
35 | Token *token;
36 | Token *endToken;
37 | Token *tokenC;
38 | Token *tokenH;
39 |
40 | Class **classes;
41 | int classesCnt;
42 | HMap **classes_hmap;
43 | NFile **inheritance;
44 | int inheritanceCnt;
45 | };
46 |
47 | struct Token
48 | {
49 | Token *next;
50 | Token *prev;
51 | char *val;
52 | };
53 |
54 | struct Class
55 | {
56 | char *name;
57 | Class *parent;
58 | Class *next;
59 | Property **properties;
60 | int propertiesCnt;
61 | Function **functions;
62 | int functionsCnt;
63 | HMap **object_hmap;
64 | HMap **class_hmap;
65 | };
66 |
67 | struct Property
68 | {
69 | char *datatype;
70 | char *name;
71 | char *value;
72 | int encapsulation;
73 | };
74 |
75 | struct Function
76 | {
77 | Token *bodyStart;
78 | Token *bodyEnd;
79 | char *datatype;
80 | char *name;
81 | char *overloadedName;
82 | Property **params;
83 | int paramsCnt;
84 | Property **properties;
85 | int propertiesCnt;
86 | int encapsulation;
87 | HMap **hmap;
88 | HMap **return_hmap;
89 | };
90 |
91 | NFile **fileList;
92 | int fileListCnt;
93 |
94 | HMap **classes_hmap;
95 |
96 | Property *createProperty()
97 | {
98 | Property *newProperty = (Property *)malloc(sizeof(Property));
99 | newProperty->datatype = (char *)malloc(10000 * sizeof(char));
100 | newProperty->name = (char *)malloc(10000 * sizeof(char));
101 | newProperty->value = (char *)malloc(10000 * sizeof(char));
102 | memset(newProperty->datatype, 0, sizeof(newProperty->datatype));
103 | memset(newProperty->name, 0, sizeof(newProperty->name));
104 | memset(newProperty->value, 0, sizeof(newProperty->value));
105 | newProperty->encapsulation = -1;
106 | return newProperty;
107 | }
108 |
109 | Function *createFunction()
110 | {
111 | Function *newFunction = (Function *)malloc(sizeof(Function));
112 | newFunction->properties = (Property **)malloc(1000 * sizeof(Property));
113 | newFunction->propertiesCnt = 0;
114 | newFunction->params = (Property **)malloc(1000 * sizeof(Property));
115 | newFunction->paramsCnt = 0;
116 | newFunction->datatype = (char *)malloc(10000 * sizeof(char));
117 | newFunction->name = (char *)malloc(10000 * sizeof(char));
118 | newFunction->overloadedName = (char *)malloc(10000 * sizeof(char));
119 | newFunction->encapsulation = -1;
120 | newFunction->bodyStart = NULL;
121 | newFunction->bodyEnd = NULL;
122 | newFunction->hmap = create_hm();
123 | return newFunction;
124 | }
125 |
126 | Class *createClass()
127 | {
128 | Class *newClass = (Class *)malloc(sizeof(Class));
129 | newClass->properties = (Property **)malloc(1000 * sizeof(Property));
130 | newClass->functions = (Function **)malloc(1000 * sizeof(Function));
131 | newClass->name = NULL;
132 | newClass->parent = NULL;
133 | newClass->next = NULL;
134 | newClass->propertiesCnt = 0;
135 | newClass->functionsCnt = 0;
136 | newClass->object_hmap = create_hm();
137 | newClass->class_hmap = create_hm();
138 | return newClass;
139 | }
140 |
141 | NFile *createNFile(char *filename)
142 | {
143 | int len = strlen(filename);
144 | FILE *fileN = fopen(filename, "r");
145 | filename[len - 1] = 'c';
146 | FILE *fileC = fopen(filename, "w");
147 | filename[len - 1] = 'h';
148 | FILE *fileH = fopen(filename, "w");
149 |
150 | NFile *newFile = (NFile *)malloc(sizeof(NFile));
151 | newFile->classes = (Class **)malloc(1000 * sizeof(Class *));
152 | newFile->classesCnt = 0;
153 | newFile->fileN = fileN;
154 | newFile->fileC = fileC;
155 | newFile->fileH = fileH;
156 | newFile->token = NULL;
157 | newFile->tokenC = NULL;
158 | newFile->tokenH = NULL;
159 | newFile->filename = (char *)malloc((strlen(filename) + 1) * sizeof(char));
160 | memset(newFile->filename, 0, sizeof(newFile->filename));
161 | filename[len - 1] = 'n';
162 | strcpy(newFile->filename, filename);
163 | newFile->inheritance = (NFile **)malloc(1000 * sizeof(NFile *));
164 | ;
165 | newFile->inheritanceCnt = 0;
166 |
167 | return newFile;
168 | }
169 |
170 | Token *endScope(Token *curs)
171 | {
172 | int balance = 1;
173 | while (curs != NULL && strcmp(curs->val, "{") != 0)
174 | {
175 | curs = curs->next;
176 | }
177 | Token *end = curs->next;
178 |
179 | while (end != NULL)
180 | {
181 | if (strcmp(end->val, "{") == 0)
182 | {
183 | ++balance;
184 | }
185 | else if (strcmp(end->val, "}") == 0)
186 | {
187 | --balance;
188 | }
189 | if (balance < 1)
190 | {
191 | return end;
192 | }
193 | end = end->next;
194 | }
195 | printf("UNBALANCED BRACKETS!\n");
196 | exit(10);
197 | }
198 |
199 | Token *createToken(char *content)
200 | {
201 | Token *newToken = (Token *)malloc(sizeof(Token));
202 | newToken->next = NULL;
203 | newToken->prev = NULL;
204 | newToken->val = (char *)malloc((strlen(content) + 1) * sizeof(char));
205 | memset(newToken->val, 0, strlen(content) + 1);
206 | strcpy(newToken->val, content);
207 | return newToken;
208 | }
209 |
210 | void appendToken(NFile *file, char *content, char type)
211 | {
212 | Token *start = NULL;
213 | if (type == 'N')
214 | {
215 | start = file->token;
216 | }
217 | else if (type == 'C')
218 | {
219 | start = file->tokenC;
220 | }
221 | else if (type == 'H')
222 | {
223 | start = file->tokenH;
224 | }
225 | if (start == NULL)
226 | {
227 | if (type == 'N')
228 | {
229 | file->token = createToken(content);
230 | }
231 | else if (type == 'C')
232 | {
233 | file->tokenC = createToken(content);
234 | }
235 | else if (type == 'H')
236 | {
237 | file->tokenH = createToken(content);
238 | }
239 | return;
240 | }
241 | while (start->next != NULL)
242 | {
243 | start = start->next;
244 | }
245 | file->endToken = start->next = createToken(content);
246 | start->next->prev = start;
247 | }
248 |
249 | Token *writeInclude(NFile *file, Token *start, Token *end)
250 | {
251 | char str[1000];
252 | memset(str, 0, sizeof(str));
253 | while (strcmp(end->val, "\n") != 0 && strcmp(end->val, "\0") != 0)
254 | {
255 | end = end->next;
256 | }
257 | strcat(str, start->next->next->next->val);
258 | while (strcmp(start->val, ".") != 0)
259 | {
260 | fwrite(start->val, 1, strlen(start->val), file->fileC);
261 | start = start->next;
262 | }
263 | fwrite(start->val, 1, strlen(start->val), file->fileC);
264 | start = start->next;
265 | if (strcmp(start->val, "n") == 0)
266 | {
267 | strcat(str, ".n");
268 | tokenize(str, file);
269 | fwrite("h\"\n", 1, 3, file->fileC);
270 | }
271 | else
272 | {
273 | fwrite(start->val, 1, strlen(start->val), file->fileC);
274 | }
275 | start = start->next;
276 |
277 | return start;
278 | }
279 |
280 | void parseStatement(Class *class, Token *start, Token *end)
281 | {
282 | char datatype[1000];
283 | memset(datatype, 0, sizeof(datatype));
284 | char name[1000];
285 | memset(name, 0, sizeof(name));
286 | char value[1000];
287 | memset(value, 0, sizeof(value));
288 |
289 | int encapsulation = -1;
290 | if (strcmp(start->val, "+") == 0)
291 | {
292 | encapsulation = PUBLIC_CLASS_VAR;
293 | start = start->next;
294 | }
295 | else if (strcmp(start->val, "-") == 0)
296 | {
297 | encapsulation = PUBLIC_OBJECT_VAR;
298 | start = start->next;
299 | }
300 |
301 | Token *curs = start;
302 | while (strcmp(curs->next->next->val, "=") != 0 && strcmp(curs->next->next->val, ";") != 0)
303 | {
304 | curs = curs->next;
305 | }
306 | curs = curs->next;
307 | while (start != curs)
308 | {
309 | strcat(datatype, start->val);
310 | start = start->next;
311 | }
312 | if (strcmp(curs->next->val, "=") == 0)
313 | {
314 | int catch = 0;
315 | while (strcmp(curs->val, ";") != 0)
316 | {
317 | memset(value, 0, sizeof(value));
318 | Property *prop = createProperty();
319 | strcpy(prop->datatype, datatype);
320 | strcpy(prop->name, curs->val);
321 | prop->encapsulation = encapsulation;
322 |
323 | curs = curs->next->next;
324 |
325 | while ((strcmp(curs->val, ";") != 0 && strcmp(curs->val, ",") != 0 && catch == 0) || catch == 1 || catch == 2)
326 | {
327 | if (strcmp(curs->val, "'") == 0 && (catch == 0 || catch == 2))
328 | {
329 | catch = (catch == 2) ? 0 : 2;
330 | }
331 | else if (strcmp(curs->val, "\"") == 0 && (catch == 0 || catch == 1))
332 | {
333 | catch = (catch == 1) ? 0 : 1;
334 | }
335 | strcat(value, curs->val);
336 | curs = curs->next;
337 | }
338 |
339 | strcpy(prop->value, value);
340 | if (encapsulation == PUBLIC_CLASS_VAR)
341 | {
342 | update_hm(class->class_hmap, prop->name, (void *)prop->datatype);
343 | }
344 | else
345 | {
346 | update_hm(class->object_hmap, prop->name, (void *)prop->datatype);
347 | }
348 | class->properties[class->propertiesCnt++] = prop;
349 |
350 | if (strcmp(curs->val, ",") == 0)
351 | {
352 | curs = curs->next;
353 | }
354 | }
355 | }
356 | else if (strcmp(curs->next->val, ";") == 0)
357 | {
358 | Property *prop = createProperty();
359 | strcpy(prop->datatype, datatype);
360 | strcpy(prop->name, curs->val);
361 | strcpy(prop->value, "");
362 | prop->encapsulation = encapsulation;
363 | if (encapsulation == PUBLIC_CLASS_VAR)
364 | {
365 | update_hm(class->class_hmap, prop->name, (void *)prop->datatype);
366 | }
367 | else
368 | {
369 | update_hm(class->object_hmap, prop->name, (void *)prop->datatype);
370 | }
371 | class->properties[class->propertiesCnt++] = prop;
372 | }
373 | }
374 |
375 | void parseFunction(Class *class, Token *start, Token *end)
376 | {
377 | char datatype[1000];
378 | memset(datatype, 0, sizeof(datatype));
379 | char name[1000];
380 | memset(name, 0, sizeof(name));
381 | char overloadedName[1000];
382 | memset(overloadedName, 0, sizeof(overloadedName));
383 | Function *function = createFunction();
384 | int encapsulation = -1;
385 | if (strcmp(start->val, "+") == 0)
386 | {
387 | encapsulation = PUBLIC_CLASS_FUNC;
388 | start = start->next;
389 | }
390 | else if (strcmp(start->val, "-") == 0)
391 | {
392 | encapsulation = PUBLIC_OBJECT_FUNC;
393 | start = start->next;
394 | }
395 | Token *curs = start;
396 | while (strcmp(curs->next->val, "(") != 0)
397 | {
398 | curs = curs->next;
399 | }
400 | while (start != curs)
401 | {
402 | if (strcmp(start->val, class->name) == 0)
403 | {
404 | strcat(datatype, "Object_");
405 | }
406 | strcat(datatype, start->val);
407 | start = start->next;
408 | }
409 | strcat(name, start->val);
410 | curs = start = start->next->next;
411 | if (strcmp(start->val, ")") == 0)
412 | {
413 | sprintf(overloadedName, "%s%svoid", overloadedName, name);
414 | }
415 | else
416 | {
417 | strcat(overloadedName, name);
418 | while (strcmp(curs->val, ")") != 0)
419 | {
420 | curs = curs->next;
421 | }
422 | Property *param = createProperty();
423 | while (start != curs)
424 | {
425 | if (strcmp(start->val, ",") == 0)
426 | {
427 | update_hm(function->hmap, param->name, (void *)param->datatype);
428 | function->params[function->paramsCnt++] = param;
429 | param = createProperty();
430 | }
431 | else
432 | {
433 | if (strcmp(start->next->val, ",") == 0 || strcmp(start->next->val, ")") == 0)
434 | {
435 | if (strlen(param->datatype) == 0)
436 | {
437 | strcat(overloadedName, start->val);
438 | strcat(param->datatype, start->val);
439 | }
440 | else
441 | {
442 | strcat(param->name, start->val);
443 | }
444 | }
445 | else
446 | {
447 | strcat(param->datatype, start->val);
448 | strcat(param->datatype, " ");
449 | strcat(overloadedName, start->val);
450 | }
451 | }
452 | start = start->next;
453 | }
454 | update_hm(function->hmap, (param->name), (void *)param->datatype);
455 | function->params[function->paramsCnt++] = param;
456 | }
457 | if (encapsulation == PUBLIC_CLASS_FUNC)
458 | {
459 | update_hm(class->class_hmap, overloadedName, (void *)datatype);
460 | }
461 | else if (encapsulation == PUBLIC_OBJECT_FUNC)
462 | {
463 | update_hm(class->object_hmap, overloadedName, (void *)datatype);
464 | }
465 | strcpy(function->overloadedName, overloadedName);
466 | strcpy(function->datatype, datatype);
467 | strcpy(function->name, name);
468 | function->bodyStart = curs->next->next;
469 | function->bodyEnd = end;
470 | function->encapsulation = encapsulation;
471 | class->functions[class->functionsCnt++] = function;
472 | }
473 |
474 | Token *parseClass(NFile *file, Token *start, Token *end)
475 | {
476 | Token *curs = start->next;
477 | Class *class = createClass();
478 | end = endScope(end);
479 |
480 | class->name = start->next->val;
481 | update_hm(classes_hmap, class->name, (void *)class);
482 | start = start->next->next;
483 | if (strcmp(start->val, ":") == 0)
484 | {
485 | start = start->next;
486 | Class *parent = NULL;
487 | if (isClassInstance(file, start->val))
488 | {
489 | for (int i = 0; i < file->inheritanceCnt; ++i)
490 | {
491 | for (int j = 0; j < file->inheritance[i]->classesCnt; ++j)
492 | {
493 | if (strcmp(file->inheritance[i]->classes[j]->name, start->val) == 0)
494 | {
495 | parent = file->inheritance[i]->classes[j];
496 | break;
497 | }
498 | }
499 | }
500 | }
501 | class->parent = parent;
502 | start = start->next;
503 | }
504 |
505 | while (start != end)
506 | {
507 | if (strcmp(start->val, "+") == 0 || strcmp(start->val, "-") == 0)
508 | {
509 | int catch = 0;
510 | curs = start;
511 | while ((strcmp(curs->val, ";") != 0 && strcmp(curs->val, "{") != 0) || catch == 1 || catch == 2)
512 | {
513 | if (strcmp(curs->val, "'") == 0 && (catch == 0 || catch == 2))
514 | {
515 | catch = (catch == 2) ? 0 : 2;
516 | }
517 | else if (strcmp(curs->val, "\"") == 0 && (catch == 0 || catch == 1))
518 | {
519 | catch = (catch == 1) ? 0 : 1;
520 | }
521 | curs = curs->next;
522 | }
523 | if (strcmp(curs->val, ";") == 0)
524 | {
525 |
526 | parseStatement(class, start, curs);
527 | }
528 | else
529 | {
530 | curs = endScope(curs);
531 | parseFunction(class, start, curs);
532 | start = curs->next;
533 | }
534 | }
535 | start = start->next;
536 | }
537 | file->classes[file->classesCnt++] = class;
538 | return start;
539 | }
540 |
541 | void parseLevel0(NFile *file)
542 | {
543 | Token *start = file->token;
544 | Token *eof = file->endToken;
545 | Token *curs = start;
546 | Token *end = start;
547 |
548 | while (curs != eof)
549 | {
550 | if (strcmp(curs->val, "#") == 0 && strcmp(curs->next->next->val, "<") != 0)
551 | {
552 | end = start = curs = writeInclude(file, curs, end);
553 | }
554 | else if (strcmp(curs->val, "#") == 0 && strcmp(curs->next->next->val, "<") == 0)
555 | {
556 | while (curs != NULL && strcmp(curs->val, "\n") != 0)
557 | {
558 | fwrite(curs->val, 1, strlen(curs->val), file->fileC);
559 | curs = curs->next;
560 | }
561 | fwrite("\n", 1, 1, file->fileC);
562 | end = start = curs->next;
563 | }
564 | else if (strcmp(curs->val, "class") == 0)
565 | {
566 | end = start = curs = parseClass(file, curs, end);
567 | }
568 | curs = curs->next;
569 | }
570 | char str[1000];
571 | memset(str, 0, sizeof(str));
572 | sprintf(str, "%s\n#include \"%s", str, file->filename);
573 | str[strlen(str) - 1] = 'h';
574 | strcat(str, "\"\n\n");
575 | fwrite(str, 1, strlen(str), file->fileC);
576 | }
577 |
578 | void constructClassStruct(NFile *file, Class *class)
579 | {
580 | FILE *cFile = file->fileC;
581 | FILE *hFile = file->fileH;
582 |
583 | if (class->parent != NULL)
584 | {
585 | int jLen = class->functionsCnt;
586 | int len = class->parent->functionsCnt;
587 | for (int i = 0; i < len; ++i)
588 | {
589 | int ctc = 1;
590 | for (int j = 0; j < jLen; ++j)
591 | {
592 | if (strcmp(class->parent->functions[i]->name, class->functions[j]->name) == 0)
593 | {
594 | ctc = 0;
595 | break;
596 | }
597 | }
598 | if (strstr(class->parent->functions[i]->name, "init") == class->parent->functions[i]->name)
599 | {
600 | memset(class->parent->functions[i]->datatype, 0, sizeof(class->parent->functions[i]->datatype));
601 | sprintf(class->parent->functions[i]->datatype, "%sObject_%s *", class->parent->functions[i]->datatype, class->name);
602 | strcat(class->parent->functions[i]->name, class->parent->name);
603 | ctc = 1;
604 | }
605 | if (ctc == 1)
606 | {
607 | class->functions[class->functionsCnt++] = class->parent->functions[i];
608 | }
609 | }
610 | jLen = class->propertiesCnt;
611 | len = class->parent->propertiesCnt;
612 | for (int i = 0; i < len; ++i)
613 | {
614 | int ctc = 1;
615 | for (int j = 0; j < jLen; ++j)
616 | {
617 | if (strcmp(class->parent->properties[i]->name, class->properties[j]->name) == 0)
618 | {
619 | ctc = 0;
620 | break;
621 | }
622 | }
623 | if (ctc == 1)
624 | {
625 | class->properties[class->propertiesCnt++] = class->parent->properties[i];
626 | }
627 | }
628 | }
629 |
630 | char str[100000];
631 | memset(str, 0, sizeof(str));
632 | sprintf(str, "%stypedef struct Class_%s Class_%s;\n", str, class->name, class->name);
633 | sprintf(str, "%stypedef struct Object_%s Object_%s;\n", str, class->name, class->name);
634 | sprintf(str, "%sClass_%s *Class_%s_Instance;\n", str, class->name, class->name);
635 | fwrite(str, 1, strlen(str), hFile);
636 |
637 | memset(str, 0, sizeof(str));
638 | sprintf(str, "%sstruct Class_%s {\n", str, class->name);
639 | for (int i = 0; i < class->propertiesCnt; ++i)
640 | {
641 | if (class->properties[i]->encapsulation == PUBLIC_CLASS_VAR)
642 | {
643 | sprintf(str, "%s\t%s %s;\n", str, class->properties[i]->datatype, class->properties[i]->name);
644 | }
645 | }
646 | Class *parent = NULL;
647 | if (class->parent != NULL)
648 | {
649 | parent = class->parent;
650 | }
651 | for (int i = 0; i < class->functionsCnt; ++i)
652 | {
653 | if (class->functions[i]->encapsulation == PUBLIC_CLASS_FUNC && strcmp(class->functions[i]->name, "main") != 0)
654 | {
655 | if (parent != NULL && strstr(class->functions[i]->name, parent->name) != NULL)
656 | {
657 | sprintf(str, "%s\t%s(*%s%s)(Object_%s *this,", str, class->functions[i]->datatype, class->functions[i]->name, class->name, class->name);
658 | }
659 | else
660 | {
661 | sprintf(str, "%s\t%s(*%s%s)(", str, class->functions[i]->datatype, class->functions[i]->name, class->name);
662 | }
663 | for (int j = 0; j < class->functions[i]->paramsCnt; ++j)
664 | {
665 | if (class->functions[i]->params[j]->datatype != NULL)
666 | {
667 | if (strcmp(class->functions[i]->params[j]->datatype, "void") == 0)
668 | {
669 | continue;
670 | }
671 | strcat(str, class->functions[i]->params[j]->datatype);
672 | if (class->functions[i]->params[j]->name != NULL)
673 | {
674 | strcat(str, class->functions[i]->params[j]->name);
675 | if (j + 1 < class->functions[i]->paramsCnt)
676 | {
677 | strcat(str, ",");
678 | }
679 | }
680 | }
681 | }
682 | if (str[strlen(str) - 1] == ',')
683 | {
684 | str[strlen(str) - 1] = '\0';
685 | }
686 | sprintf(str, "%s);\n", str);
687 | }
688 | }
689 | sprintf(str, "%s};\n", str);
690 | fwrite(str, 1, strlen(str), hFile);
691 |
692 | memset(str, 0, sizeof(str));
693 | sprintf(str, "%sstruct Object_%s {\n", str, class->name);
694 | for (int i = 0; i < class->propertiesCnt; ++i)
695 | {
696 | if (class->properties[i]->encapsulation == PUBLIC_OBJECT_VAR)
697 | {
698 | sprintf(str, "%s\t%s %s;\n", str, class->properties[i]->datatype, class->properties[i]->name);
699 | }
700 | }
701 | for (int i = 0; i < class->functionsCnt; ++i)
702 | {
703 | if (class->functions[i]->encapsulation == PUBLIC_OBJECT_FUNC && strcmp(class->functions[i]->name, "main") != 0)
704 | {
705 | sprintf(str, "%s\t%s(*%s%s)(Object_%s *this", str, class->functions[i]->datatype, class->functions[i]->name, class->name, class->name);
706 | for (int j = 0; j < class->functions[i]->paramsCnt; ++j)
707 | {
708 | if (class->functions[i]->params[j]->datatype != NULL)
709 | {
710 | if (strcmp(class->functions[i]->params[j]->datatype, "void") == 0)
711 | {
712 | continue;
713 | }
714 | strcat(str, ", ");
715 | strcat(str, class->functions[i]->params[j]->datatype);
716 | if (class->functions[i]->params[j]->name != NULL)
717 | {
718 | strcat(str, class->functions[i]->params[j]->name);
719 | }
720 | }
721 | }
722 | sprintf(str, "%s);\n", str);
723 | }
724 | }
725 | sprintf(str, "%s};\n", str);
726 | fwrite(str, 1, strlen(str), hFile);
727 | }
728 |
729 | char *preInitContent(NFile *file, Class *class, Function *function)
730 | {
731 | char *str = (char *)malloc(1000000 * sizeof(char));
732 | memset(str, 0, sizeof(str));
733 | sprintf(str, "%s\tObject_%s *this = malloc(sizeof(Object_%s));\n", str, class->name, class->name);
734 | for (int i = 0; i < class->functionsCnt; ++i)
735 | {
736 | if (class->functions[i]->encapsulation == PUBLIC_OBJECT_FUNC && strcmp(class->functions[i]->name, "main") != 0)
737 | {
738 | sprintf(str, "%s\tthis->%s%s = &%s%s;\n", str, class->functions[i]->name, class->name, class->functions[i]->name, class->name);
739 | }
740 | }
741 | for (int i = 0; i < class->propertiesCnt; ++i)
742 | {
743 | if (class->properties[i]->encapsulation == PUBLIC_OBJECT_VAR)
744 | {
745 | if (strlen(class->properties[i]->value) != 0)
746 | {
747 | sprintf(str, "%s\tthis->%s = %s;\n", str, class->properties[i]->name, class->properties[i]->value);
748 | }
749 | }
750 | }
751 | return str;
752 | }
753 |
754 | char *constructClassFunctionsBody(NFile *file, Class *class, Function *function, Token *start, Token *end)
755 | {
756 | char *str = (char *)malloc(1000000 * sizeof(char));
757 | memset(str, 0, sizeof(str));
758 | while (start != end)
759 | {
760 | if (isalnum(start->val[0]) != 0 && strcmp(start->next->val, "-") == 0 && strcmp(start->next->next->val, ">") == 0 && isClassInstance(file, start->val))
761 | {
762 | if (strcmp(start->next->next->next->next->val, "(") == 0)
763 | {
764 | sprintf(str, "%sClass_%s_Instance->%s%s(", str, start->val, start->next->next->next->val, start->val);
765 | start = start->next->next->next->next;
766 | }
767 | else
768 | {
769 | sprintf(str, "%sClass_%s_Instance", str, start->val);
770 | }
771 | start = start->next;
772 | continue;
773 | }
774 | else if (isalnum(start->val[0]) != 0 && strcmp(start->next->val, "-") == 0 && strcmp(start->next->next->val, ">") == 0)
775 | {
776 | char *val = NULL;
777 | if (strcmp(start->val, "super") == 0)
778 | {
779 | sprintf(str, "%sClass_%s_Instance->%s%s%s(this,", str, class->name, function->name, class->parent->name, class->name);
780 | start = start->next->next->next->next->next;
781 | continue;
782 | }
783 | else if (strcmp(start->val, "this") != 0)
784 | {
785 | val = fetch_hm(function->hmap, start->val);
786 | if (val != NULL)
787 | {
788 | if (isClassInstance(file, val))
789 | {
790 | sprintf(str, "%s%s->%s%s", str, start->val, start->next->next->next->val, val);
791 | start = start->next->next->next->next;
792 | continue;
793 | }
794 | }
795 | }
796 | else if (strcmp(start->val, "this") == 0)
797 | {
798 | if (strcmp(start->next->next->next->next->val, "(") == 0)
799 | {
800 | sprintf(str, "%s%s->%s%s(this", str, start->val, start->next->next->next->val, class->name);
801 | for (int i = 0; i < class->functionsCnt; ++i)
802 | {
803 | if (strcmp(class->functions[i]->name, start->next->next->next->val) == 0)
804 | {
805 | if (class->functions[i]->paramsCnt > 0)
806 | {
807 | strcat(str, ",");
808 | }
809 | break;
810 | }
811 | }
812 | start = start->next->next->next->next->next;
813 | continue;
814 | }
815 | }
816 | }
817 | else if (isalnum(start->val[0]) != 0 && isClassInstance(file, start->val))
818 | {
819 | Token *tmp = start->next;
820 | while (isalnum(tmp->val[0]) == 0)
821 | {
822 | tmp = tmp->next;
823 | }
824 | update_hm(function->hmap, tmp->val, start->val);
825 | sprintf(str, "%sObject_%s", str, start->val);
826 | start = start->next;
827 | continue;
828 | }
829 | strcat(str, start->val);
830 | if (isalnum(start->val[0]) != 0 && isalnum(start->next->val[0]) != 0)
831 | {
832 | strcat(str, " ");
833 | }
834 | start = start->next;
835 | }
836 | return str;
837 | }
838 |
839 | void constructClassFunctions(NFile *file, Class *class)
840 | {
841 | FILE *cFile = file->fileC;
842 | FILE *hFile = file->fileH;
843 |
844 | char str[1000000];
845 |
846 | for (int i = 0; i < class->functionsCnt; ++i)
847 | {
848 | memset(str, 0, sizeof(str));
849 | int parentInit = 0;
850 | if (class->parent != NULL)
851 | {
852 | if (strstr(class->functions[i]->name, "init") != NULL && strstr(class->functions[i]->name, class->parent->name) != NULL)
853 | {
854 | parentInit = 1;
855 | }
856 | }
857 | sprintf(str, "%s%s %s%s(", str, class->functions[i]->datatype, class->functions[i]->name, class->name);
858 | if (((class->functions[i]->encapsulation == PUBLIC_OBJECT_FUNC) && strcmp(class->functions[i]->name, "main") != 0) || parentInit)
859 | {
860 | sprintf(str, "%s Object_%s *this", str, class->name);
861 | }
862 | for (int j = 0; j < class->functions[i]->paramsCnt; ++j)
863 | {
864 | if (strcmp(class->functions[i]->params[j]->datatype, "void") == 0)
865 | {
866 | continue;
867 | }
868 | if (j + 1 == class->functions[i]->paramsCnt)
869 | {
870 | if (class->functions[i]->encapsulation == PUBLIC_CLASS_FUNC && !parentInit)
871 | {
872 | sprintf(str, "%s %s %s", str, class->functions[i]->params[j]->datatype, class->functions[i]->params[j]->name);
873 | }
874 | else
875 | {
876 | sprintf(str, "%s, %s %s", str, class->functions[i]->params[j]->datatype, class->functions[i]->params[j]->name);
877 | }
878 | }
879 | else
880 | {
881 | if (class->functions[i]->encapsulation == PUBLIC_CLASS_FUNC && !parentInit)
882 | {
883 | sprintf(str, "%s %s %s,", str, class->functions[i]->params[j]->datatype, class->functions[i]->params[j]->name);
884 | }
885 | else
886 | {
887 | sprintf(str, "%s, %s %s", str, class->functions[i]->params[j]->datatype, class->functions[i]->params[j]->name);
888 | }
889 | }
890 | }
891 | strcat(str, ") {\n");
892 | if (strcmp(class->functions[i]->name, "init") == 0)
893 | {
894 | char *pre = preInitContent(file, class, class->functions[i]);
895 | strcat(str, pre);
896 | free(pre);
897 | Token *start = class->functions[i]->bodyStart;
898 | Token *end = class->functions[i]->bodyEnd;
899 |
900 | strcat(str, constructClassFunctionsBody(file, class, class->functions[i], start, end));
901 | }
902 | else
903 | {
904 | Token *start = class->functions[i]->bodyStart;
905 | Token *end = class->functions[i]->bodyEnd;
906 | strcat(str, constructClassFunctionsBody(file, class, class->functions[i], start, end));
907 | }
908 | strcat(str, "}\n");
909 | fwrite(str, 1, strlen(str), cFile);
910 | }
911 | }
912 |
913 | void constructClassFunctionProtos(NFile *file, Class *class)
914 | {
915 | FILE *cFile = file->fileC;
916 | FILE *hFile = file->fileH;
917 |
918 | char str[100000];
919 |
920 | for (int i = 0; i < class->functionsCnt; ++i)
921 | {
922 | memset(str, 0, sizeof(str));
923 |
924 | int parentInit = 0;
925 | if (class->parent != NULL)
926 | {
927 | if (strstr(class->functions[i]->name, "init") != NULL && strstr(class->functions[i]->name, class->parent->name) != NULL)
928 | {
929 | parentInit = 1;
930 | }
931 | }
932 |
933 | sprintf(str, "%s%s %s%s(", str, class->functions[i]->datatype, class->functions[i]->name, class->name);
934 | if ((class->functions[i]->encapsulation == PUBLIC_OBJECT_FUNC && strcmp(class->functions[i]->name, "main") != 0) || parentInit)
935 | {
936 | sprintf(str, "%s Object_%s *this", str, class->name);
937 | }
938 | for (int j = 0; j < class->functions[i]->paramsCnt; ++j)
939 | {
940 | if (strcmp(class->functions[i]->params[j]->datatype, "void") == 0)
941 | {
942 | continue;
943 | }
944 | if (j + 1 == class->functions[i]->paramsCnt)
945 | {
946 | if (class->functions[i]->encapsulation == PUBLIC_CLASS_FUNC && !parentInit)
947 | {
948 | sprintf(str, "%s %s %s", str, class->functions[i]->params[j]->datatype, class->functions[i]->params[j]->name);
949 | }
950 | else
951 | {
952 | sprintf(str, "%s, %s %s", str, class->functions[i]->params[j]->datatype, class->functions[i]->params[j]->name);
953 | }
954 | }
955 | else
956 | {
957 | if (class->functions[i]->encapsulation == PUBLIC_CLASS_FUNC && !parentInit)
958 | {
959 | sprintf(str, "%s %s %s,", str, class->functions[i]->params[j]->datatype, class->functions[i]->params[j]->name);
960 | }
961 | else
962 | {
963 | sprintf(str, "%s, %s %s", str, class->functions[i]->params[j]->datatype, class->functions[i]->params[j]->name);
964 | }
965 | }
966 | }
967 | strcat(str, ");\n");
968 | fwrite(str, 1, strlen(str), cFile);
969 | }
970 | }
971 |
972 | void constructInitFunction(NFile *file)
973 | {
974 | char hStr[1000000];
975 | char str[1000000];
976 | memset(str, 0, sizeof(str));
977 | for (int i = 0; i < file->classesCnt; ++i)
978 | {
979 | Class *class = file->classes[i];
980 | memset(hStr, 0, sizeof(hStr));
981 | sprintf(hStr, "%svoid start%s();\n", hStr, class->name);
982 | fwrite(hStr, 1, strlen(hStr), file->fileH);
983 |
984 | sprintf(str, "%svoid start%s() {\n", str, class->name);
985 | sprintf(str, "%s\tif(Class_%s_Instance == NULL) {\n\t\tClass_%s_Instance = malloc(sizeof(Class_%s_Instance));\n", str, class->name, class->name, class->name);
986 | for (int i = 0; i < class->propertiesCnt; ++i)
987 | {
988 | if (class->properties[i]->encapsulation == PUBLIC_CLASS_VAR)
989 | {
990 | if (strlen(class->properties[i]->value) != 0)
991 | {
992 | sprintf(str, "%s\t\tClass_%s_Instance->%s = %s;\n", str, class->name, class->properties[i]->name, class->properties[i]->value);
993 | }
994 | }
995 | }
996 | for (int i = 0; i < class->functionsCnt; ++i)
997 | {
998 | if (class->functions[i]->encapsulation == PUBLIC_CLASS_FUNC)
999 | {
1000 | sprintf(str, "%s\t\tClass_%s_Instance->%s%s = &%s%s;\n", str, class->name, class->functions[i]->name, class->name, class->functions[i]->name, class->name);
1001 | }
1002 | }
1003 | strcat(str, "\t}\n");
1004 | if (i + 1 >= file->classesCnt)
1005 | {
1006 | for (int i = 0; i < file->inheritanceCnt; ++i)
1007 | {
1008 | for (int j = 0; j < file->inheritance[i]->classesCnt; ++j)
1009 | {
1010 | sprintf(str, "%s\tstart%s();\n", str, file->inheritance[i]->classes[j]->name);
1011 | }
1012 | }
1013 | }
1014 | strcat(str, "}\n");
1015 | }
1016 | fwrite(str, 1, strlen(str), file->fileC);
1017 | }
1018 |
1019 | int isClassInstance(NFile *file, char *name)
1020 | {
1021 | for (int i = 0; i < file->classesCnt; ++i)
1022 | {
1023 | if (strcmp(name, file->classes[i]->name) == 0)
1024 | {
1025 | return 1;
1026 | }
1027 | }
1028 | for (int i = 0; i < file->inheritanceCnt; ++i)
1029 | {
1030 | for (int j = 0; j < file->inheritance[i]->classesCnt; ++j)
1031 | {
1032 | if (strcmp(name, file->inheritance[i]->classes[j]->name) == 0)
1033 | {
1034 | return 1;
1035 | }
1036 | }
1037 | }
1038 | return 0;
1039 | }
1040 |
1041 | void constructEverythingElse(NFile *file, Token *sstart, Token *eend)
1042 | {
1043 | char str[100000];
1044 | memset(str, 0, sizeof(str));
1045 | Token *eof = eend;
1046 | Token *start = sstart;
1047 | Token *curs = NULL;
1048 | HMap **hmap = create_hm();
1049 | int inString = 0;
1050 | while (start != NULL && start != eof)
1051 | {
1052 | if (curs != NULL)
1053 | {
1054 | if (curs == start)
1055 | {
1056 | curs = NULL;
1057 | }
1058 | }
1059 | memset(str, 0, sizeof(str));
1060 | if (curs == NULL)
1061 | {
1062 | // if(strcmp(start->val, "return") == 0) {
1063 |
1064 | // }
1065 | if (strcmp(start->val, "#") == 0 && strcmp(start->next->val, "include") == 0)
1066 | {
1067 | while (start != NULL && strcmp(start->val, "\n") != 0)
1068 | {
1069 | start = start->next;
1070 | }
1071 | continue;
1072 | }
1073 | if (strcmp(start->val, "class") == 0)
1074 | {
1075 | start = endScope(start);
1076 | start = start->next;
1077 | continue;
1078 | }
1079 | if (strcmp(start->val, "-") == 0)
1080 | {
1081 | int catch = 0;
1082 | curs = start;
1083 | while ((strcmp(curs->val, ";") != 0 && strcmp(curs->val, "{") != 0) || catch == 1 || catch == 2)
1084 | {
1085 | if (strcmp(curs->val, "'") == 0 && (catch == 0 || catch == 2))
1086 | {
1087 | catch = (catch == 2) ? 0 : 2;
1088 | }
1089 | else if (strcmp(curs->val, "\"") == 0 && (catch == 0 || catch == 1))
1090 | {
1091 | catch = (catch == 1) ? 0 : 1;
1092 | }
1093 | curs = curs->next;
1094 | }
1095 | if (strcmp(curs->val, "{") == 0)
1096 | {
1097 | curs = endScope(curs);
1098 | }
1099 | start = start->next;
1100 | continue;
1101 | }
1102 | if (strcmp(start->val, "+") == 0)
1103 | {
1104 | int catch = 0;
1105 | Token *tmpStart;
1106 | tmpStart = curs = start;
1107 | tmpStart = tmpStart->next;
1108 | while ((strcmp(curs->val, ";") != 0 && strcmp(curs->val, "{") != 0) || catch == 1 || catch == 2)
1109 | {
1110 | if (strcmp(curs->val, "'") == 0 && (catch == 0 || catch == 2))
1111 | {
1112 | catch = (catch == 2) ? 0 : 2;
1113 | }
1114 | else if (strcmp(curs->val, "\"") == 0 && (catch == 0 || catch == 1))
1115 | {
1116 | catch = (catch == 1) ? 0 : 1;
1117 | }
1118 | curs = curs->next;
1119 | }
1120 | while (tmpStart != curs)
1121 | {
1122 | if (isClassInstance(file, tmpStart->val))
1123 | {
1124 | sprintf(str, "%sClass_%s_Instance ", str, tmpStart->val);
1125 | fwrite(str, 1, strlen(str), file->fileH);
1126 | }
1127 | else
1128 | {
1129 | fwrite(tmpStart->val, 1, strlen(tmpStart->val), file->fileH);
1130 | if (isalnum(tmpStart->val[0]) != 0)
1131 | {
1132 | fwrite(" ", 1, 1, file->fileH);
1133 | }
1134 | }
1135 | tmpStart = tmpStart->next;
1136 | }
1137 | fwrite(";\n", 1, 2, file->fileH);
1138 | if (strcmp(curs->val, "{") == 0)
1139 | {
1140 | curs = endScope(curs);
1141 | }
1142 | start = start->next;
1143 | continue;
1144 | }
1145 | }
1146 | if (isalnum(start->val[0]) != 0 && strcmp(start->next->val, "-") == 0 && strcmp(start->next->next->val, ">") == 0 && isClassInstance(file, start->val))
1147 | {
1148 | if (strcmp(start->next->next->next->next->val, "(") == 0)
1149 | {
1150 | sprintf(str, "%sClass_%s_Instance->%s%s", str, start->val, start->next->next->next->val, start->val);
1151 | fwrite(str, 1, strlen(str), file->fileC);
1152 | start = start->next->next->next->next;
1153 | }
1154 | else
1155 | {
1156 | sprintf(str, "%sClass_%s_Instance", str, start->val);
1157 | fwrite(str, 1, strlen(str), file->fileC);
1158 | start = start->next;
1159 | }
1160 | continue;
1161 | }
1162 | else if (isalnum(start->val[0]) != 0 && strcmp(start->next->val, "-") == 0 && strcmp(start->next->next->val, ">") == 0 && strcmp(start->next->next->next->next->val, "(") == 0)
1163 | {
1164 | char *val = fetch_hm(hmap, start->val);
1165 | if (val != NULL)
1166 | {
1167 | if (isClassInstance(file, val))
1168 | {
1169 | sprintf(str, "%s%s->%s%s(%s", str, start->val, start->next->next->next->val, val, start->val);
1170 | if (isgraph(start->next->next->next->next->next->val[0]) != 0 && start->next->next->next->next->next->val[0] != '(' && start->next->next->next->next->next->val[0] != ')')
1171 | {
1172 | strcat(str, ",");
1173 | }
1174 | fwrite(str, 1, strlen(str), file->fileC);
1175 | start = start->next->next->next->next->next;
1176 | continue;
1177 | }
1178 | }
1179 | }
1180 | else if (isalnum(start->val[0]) != 0 && strcmp(start->next->val, "-") == 0 && strcmp(start->next->next->val, ">") == 0 && strcmp(start->next->next->next->next->val, "(") != 0)
1181 | {
1182 | char *val = fetch_hm(hmap, start->val);
1183 | if (val != NULL)
1184 | {
1185 | if (isClassInstance(file, val))
1186 | {
1187 | sprintf(str, "%s%s->%s", str, start->val, start->next->next->next->val);
1188 | fwrite(str, 1, strlen(str), file->fileC);
1189 | start = start->next->next->next->next;
1190 | continue;
1191 | }
1192 | }
1193 | }
1194 | else if (isalnum(start->val[0]) != 0 && isClassInstance(file, start->val))
1195 | {
1196 | Token *tmp = start->next;
1197 | while (isalnum(tmp->val[0]) == 0)
1198 | {
1199 | tmp = tmp->next;
1200 | }
1201 | update_hm(hmap, tmp->val, start->val);
1202 | sprintf(str, "%sObject_%s", str, start->val);
1203 | fwrite(str, 1, strlen(str), file->fileC);
1204 | start = start->next;
1205 | continue;
1206 | }
1207 | else if (strcmp(start->val, "main") == 0 && strcmp(start->next->val, "(") == 0)
1208 | {
1209 | while (strcmp(start->val, "{") != 0)
1210 | {
1211 | fwrite(start->val, 1, strlen(start->val), file->fileC);
1212 | if (isalnum(start->val[0]) != 0)
1213 | {
1214 | fwrite(" ", 1, 1, file->fileC);
1215 | }
1216 | start = start->next;
1217 | }
1218 | strcat(str, "{\n");
1219 | for (int i = 0; i < file->classesCnt; ++i)
1220 | {
1221 | sprintf(str, "%s\tstart%s();\n", str, file->classes[i]->name);
1222 | }
1223 | fwrite(str, 1, strlen(str), file->fileC);
1224 | start = start->next;
1225 | continue;
1226 | }
1227 | else
1228 | {
1229 | if (inString == 0 && (start->val[0] == '"' || start->val[0] == '\''))
1230 | {
1231 | inString = start->val[0];
1232 | }
1233 | else if (inString != 0 && (start->val[0] != '"' && start->val[0] != '\''))
1234 | {
1235 | printf("UPSERT %s\n", start->val);
1236 | }
1237 | else if ((inString == '"' && start->val[0] == '"') || (inString == '\'' && start->val[0] == '\''))
1238 | {
1239 | inString = 0;
1240 | }
1241 | fwrite(start->val, 1, strlen(start->val), file->fileC);
1242 | if (isalnum(start->val[0]) != 0 && inString == 0)
1243 | {
1244 | fwrite(" ", 1, 1, file->fileC);
1245 | }
1246 | }
1247 | start = start->next;
1248 | }
1249 | }
1250 |
1251 | void constructFile(NFile *file)
1252 | {
1253 | for (int i = 0; i < file->classesCnt; ++i)
1254 | {
1255 | constructClassStruct(file, file->classes[i]);
1256 | constructClassFunctionProtos(file, file->classes[i]);
1257 | constructClassFunctions(file, file->classes[i]);
1258 | }
1259 | constructInitFunction(file);
1260 | constructEverythingElse(file, file->token, file->endToken);
1261 | }
1262 |
1263 | void tokenize(char *filename, NFile *currFile)
1264 | {
1265 | for (int i = 0; i < fileListCnt; ++i)
1266 | {
1267 | if (strcmp(fileList[i]->filename, filename) == 0)
1268 | {
1269 | return;
1270 | }
1271 | }
1272 |
1273 | NFile *file = NULL;
1274 | fileList[fileListCnt++] = file = createNFile(filename);
1275 |
1276 | if (currFile != NULL)
1277 | {
1278 | currFile->inheritance[currFile->inheritanceCnt++] = file;
1279 | }
1280 |
1281 | FILE *f = file->fileN;
1282 | fseek(f, 0, SEEK_END);
1283 | int len = ftell(f);
1284 | fseek(f, 0, SEEK_SET);
1285 | if (len <= 0)
1286 | {
1287 | return;
1288 | }
1289 | char *buff = malloc(len + 1);
1290 | memset(buff, 0, sizeof(buff));
1291 | fread(buff, 1, len, f);
1292 |
1293 | int i = 0;
1294 | int inComment = 0;
1295 | int tmpI = 0;
1296 | char tmp[1000];
1297 | memset(tmp, 0, sizeof(tmp));
1298 | while (i < len + 1)
1299 | {
1300 | if (buff[i] == '/' && buff[i + 1] == '/' && inComment == 0)
1301 | {
1302 | if (tmpI != 0)
1303 | {
1304 | appendToken(file, tmp, 'N');
1305 | tmpI = 0;
1306 | memset(tmp, 0, sizeof(tmp));
1307 | }
1308 | inComment = 1;
1309 | ++i;
1310 | ++i;
1311 | continue;
1312 | }
1313 | if (buff[i] == '/' && buff[i + 1] == '*' && inComment == 0)
1314 | {
1315 | if (tmpI != 0)
1316 | {
1317 | appendToken(file, tmp, 'N');
1318 | tmpI = 0;
1319 | memset(tmp, 0, sizeof(tmp));
1320 | }
1321 | inComment = 2;
1322 | ++i;
1323 | ++i;
1324 | continue;
1325 | }
1326 | if (inComment > 0)
1327 | {
1328 | if (buff[i] == '\n' && inComment == 1)
1329 | {
1330 | inComment = 0;
1331 | continue;
1332 | }
1333 | else if (buff[i] == '*' && buff[i + 1] == '/' && inComment == 2)
1334 | {
1335 | inComment = 0;
1336 | ++i;
1337 | ++i;
1338 | continue;
1339 | }
1340 | ++i;
1341 | continue;
1342 | }
1343 | else
1344 | {
1345 | if (isalnum(buff[i]) > 0 || buff[i] == '_')
1346 | {
1347 | tmp[tmpI++] = buff[i];
1348 | }
1349 | else if ((isspace(buff[i]) == 0 || buff[i] == '\n') && buff[i] != '"')
1350 | {
1351 | printf("%s b\n", tmp);
1352 | if (tmpI != 0)
1353 | {
1354 | appendToken(file, tmp, 'N');
1355 | tmpI = 0;
1356 | memset(tmp, 0, sizeof(tmp));
1357 | }
1358 | tmp[tmpI++] = buff[i];
1359 | printf("%s b\n", tmp);
1360 | appendToken(file, tmp, 'N');
1361 | tmpI = 0;
1362 | memset(tmp, 0, sizeof(tmp));
1363 | }
1364 | else if (buff[i] == '"')
1365 | {
1366 | printf("%sc\n", tmp);
1367 | if (tmpI != 0)
1368 | {
1369 | appendToken(file, tmp, 'N');
1370 | tmpI = 0;
1371 | memset(tmp, 0, sizeof(tmp));
1372 | }
1373 |
1374 | tmp[tmpI++] = buff[i++];
1375 | if (tmpI != 0)
1376 | {
1377 | appendToken(file, tmp, 'N');
1378 | tmpI = 0;
1379 | memset(tmp, 0, sizeof(tmp));
1380 | }
1381 | while (buff[i + 1] != '"')
1382 | {
1383 | tmp[tmpI++] = buff[i++];
1384 | }
1385 | tmp[tmpI++] = buff[i++];
1386 | printf("%sc\n", tmp);
1387 | if (tmpI != 0)
1388 | {
1389 | appendToken(file, tmp, 'N');
1390 | tmpI = 0;
1391 | memset(tmp, 0, sizeof(tmp));
1392 | }
1393 | tmp[tmpI++] = buff[i];
1394 | printf("%sc\n", tmp);
1395 | if (tmpI != 0)
1396 | {
1397 | appendToken(file, tmp, 'N');
1398 | tmpI = 0;
1399 | memset(tmp, 0, sizeof(tmp));
1400 | }
1401 | }
1402 | else
1403 | {
1404 | printf("%sb\n", tmp);
1405 | if (tmpI != 0)
1406 | {
1407 | appendToken(file, tmp, 'N');
1408 | tmpI = 0;
1409 | memset(tmp, 0, sizeof(tmp));
1410 | }
1411 | }
1412 | }
1413 | ++i;
1414 | }
1415 | parseLevel0(file);
1416 | constructFile(file);
1417 | }
1418 |
1419 | int main(int argc, char **argv)
1420 | {
1421 | memset(rootfilename, 0, sizeof(rootfilename));
1422 | for (int i = 0; i < argc; ++i)
1423 | {
1424 | if (strcmp(argv[i], "-r") == 0)
1425 | {
1426 | ++i;
1427 | strcpy(rootfilename, argv[i]);
1428 | continue;
1429 | }
1430 | }
1431 | if (strlen(rootfilename) == 0)
1432 | {
1433 | printf("Please specify a root .n file\nExample: nymph -r main.n\n");
1434 | return 0;
1435 | }
1436 | classes_hmap = create_hm();
1437 | fileList = (NFile **)malloc(1000 * sizeof(NFile *));
1438 | fileListCnt = 0;
1439 |
1440 | tokenize(rootfilename, NULL);
1441 |
1442 | return 0;
1443 | }
--------------------------------------------------------------------------------
/nymph.h:
--------------------------------------------------------------------------------
1 | typedef struct NFile NFile;
2 |
3 | typedef struct Token Token;
4 |
5 | typedef struct Other Other;
6 | typedef struct Scope Scope;
7 | typedef struct Class Class;
8 | typedef struct Func Func;
9 | typedef struct Var Var;
10 | typedef struct Property Property;
11 | typedef struct Function Function;
--------------------------------------------------------------------------------