├── .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; --------------------------------------------------------------------------------