diff options
Diffstat (limited to 'types.c')
| -rw-r--r-- | types.c | 224 |
1 files changed, 224 insertions, 0 deletions
| @@ -1,6 +1,7 @@ | |||
| 1 | #include "types.h" | 1 | #include "types.h" |
| 2 | #include "memory.h" | 2 | #include "memory.h" |
| 3 | #include <stdio.h> | 3 | #include <stdio.h> |
| 4 | #include <string.h> | ||
| 4 | 5 | ||
| 5 | 6 | ||
| 6 | List *list_make(void *ptr) | 7 | List *list_make(void *ptr) |
| @@ -174,6 +175,14 @@ LISP_OBJECT *lisp_object_make_false() | |||
| 174 | return lisp_obj; | 175 | return lisp_obj; |
| 175 | } | 176 | } |
| 176 | 177 | ||
| 178 | LISP_OBJECT *lisp_object_make_func(LISP_OBJECT *(*func)(LISP_OBJECT*)) | ||
| 179 | { | ||
| 180 | LISP_OBJECT *lisp_obj = lisp_object_make(); | ||
| 181 | lisp_obj->type = LISP_TYPE_FUNC; | ||
| 182 | lisp_obj->value.func = func; | ||
| 183 | return lisp_obj; | ||
| 184 | } | ||
| 185 | |||
| 177 | int lisp_object_print(LISP_OBJECT *obj, int indent) | 186 | int lisp_object_print(LISP_OBJECT *obj, int indent) |
| 178 | { | 187 | { |
| 179 | int count = 0; | 188 | int count = 0; |
| @@ -230,3 +239,218 @@ int lisp_object_print(LISP_OBJECT *obj, int indent) | |||
| 230 | } | 239 | } |
| 231 | return count; | 240 | return count; |
| 232 | } | 241 | } |
| 242 | |||
| 243 | int lisp_object_cmp_types(LISP_OBJECT *a, LISP_OBJECT *b) | ||
| 244 | { | ||
| 245 | if(a==NULL && b==NULL) | ||
| 246 | return 1; | ||
| 247 | else if(a==NULL || b==NULL) | ||
| 248 | return 0; | ||
| 249 | else if(a->type != b->type) | ||
| 250 | return 0; | ||
| 251 | else if(a->type == b->type) | ||
| 252 | return 1; | ||
| 253 | return 0; | ||
| 254 | } | ||
| 255 | |||
| 256 | int lisp_object_cmp(LISP_OBJECT *a, LISP_OBJECT *b) | ||
| 257 | { | ||
| 258 | int is_same_type = lisp_object_cmp_types(a, b); | ||
| 259 | if(!is_same_type) | ||
| 260 | return 0; | ||
| 261 | |||
| 262 | switch(a->type) | ||
| 263 | { | ||
| 264 | case LISP_TYPE_LIST: | ||
| 265 | break; | ||
| 266 | case LISP_TYPE_NUMBER: | ||
| 267 | return lisp_object_cmp_numbers(a, b); | ||
| 268 | break; | ||
| 269 | case LISP_TYPE_STRING: | ||
| 270 | lisp_object_cmp_string(a, b); | ||
| 271 | break; | ||
| 272 | case LISP_TYPE_SYMBOL: | ||
| 273 | lisp_object_cmp_symbol(a, b); | ||
| 274 | break; | ||
| 275 | case LISP_TYPE_NIL: | ||
| 276 | case LISP_TYPE_TRUE: | ||
| 277 | case LISP_TYPE_FALSE: | ||
| 278 | case LISP_TYPE_ERROR: | ||
| 279 | return 1; | ||
| 280 | break; | ||
| 281 | } | ||
| 282 | } | ||
| 283 | |||
| 284 | int lisp_object_cmp_numbers(LISP_OBJECT *a, LISP_OBJECT *b) // TODO: make it works | ||
| 285 | { | ||
| 286 | int is_same_type= lisp_object_cmp_types(a, b); | ||
| 287 | if(!is_same_type && a->type == LISP_TYPE_NUMBER) | ||
| 288 | return 0; | ||
| 289 | |||
| 290 | if(a->is_decimal_point && b->is_decimal_point) | ||
| 291 | return *a->value.number_float == *b->value.number_float; | ||
| 292 | else if(a->is_decimal_point && !b->is_decimal_point) | ||
| 293 | return *a->value.number_float == *(double *)b->value.number_natural; | ||
| 294 | else if(!a->is_decimal_point && b->is_decimal_point) | ||
| 295 | return *(double *)a->value.number_natural == *b->value.number_float; | ||
| 296 | else | ||
| 297 | return *a->value.number_natural == *b->value.number_natural; | ||
| 298 | } | ||
| 299 | |||
| 300 | int lisp_object_cmp_symbol(LISP_OBJECT *a, LISP_OBJECT *b) | ||
| 301 | { | ||
| 302 | int is_same_type= lisp_object_cmp_types(a, b); | ||
| 303 | if(!is_same_type && a->type == LISP_TYPE_SYMBOL) | ||
| 304 | return 0; | ||
| 305 | |||
| 306 | return strcmp(a->value.symbol, b->value.symbol) == 0; | ||
| 307 | } | ||
| 308 | |||
| 309 | int lisp_object_cmp_string(LISP_OBJECT *a, LISP_OBJECT *b) | ||
| 310 | { | ||
| 311 | int is_same_type= lisp_object_cmp_types(a, b); | ||
| 312 | if(!is_same_type && a->type == LISP_TYPE_STRING) | ||
| 313 | return 0; | ||
| 314 | |||
| 315 | return strcmp(a->value.string, b->value.string) == 0; | ||
| 316 | } | ||
| 317 | |||
| 318 | HashMap *hash_map_make(char *key, LISP_OBJECT *value) | ||
| 319 | { | ||
| 320 | return hash_map_push(NULL, key, value); | ||
| 321 | } | ||
| 322 | |||
| 323 | HashMap *hash_map_push(HashMap *hash_map, char *key, LISP_OBJECT *value) | ||
| 324 | { | ||
| 325 | HashMap *is_exist = hash_map_find(hash_map, key); | ||
| 326 | |||
| 327 | if(is_exist != NULL) | ||
| 328 | return NULL; | ||
| 329 | |||
| 330 | HashMap *new_hash_map = jadl_malloc(sizeof(HashMap)); | ||
| 331 | |||
| 332 | new_hash_map->key = jadl_malloc(sizeof(char) * strlen(key));; | ||
| 333 | strcpy(new_hash_map->key, key); | ||
| 334 | |||
| 335 | new_hash_map->value = value; | ||
| 336 | new_hash_map->prev = NULL; | ||
| 337 | |||
| 338 | if(hash_map != NULL) | ||
| 339 | hash_map->prev = new_hash_map; | ||
| 340 | new_hash_map->next = hash_map; | ||
| 341 | |||
| 342 | return new_hash_map; | ||
| 343 | } | ||
| 344 | |||
| 345 | HashMap *hash_map_reverse(HashMap *hash_map) | ||
| 346 | { | ||
| 347 | HashMap *current = hash_map; | ||
| 348 | HashMap *next = NULL; | ||
| 349 | HashMap *new_hash_map = NULL; | ||
| 350 | while (current) { | ||
| 351 | next = current->next; | ||
| 352 | |||
| 353 | current->next = new_hash_map; | ||
| 354 | new_hash_map = current; | ||
| 355 | |||
| 356 | current = next; | ||
| 357 | } | ||
| 358 | |||
| 359 | return new_hash_map; | ||
| 360 | } | ||
| 361 | |||
| 362 | |||
| 363 | void hash_map_free(HashMap *hash_map) | ||
| 364 | { | ||
| 365 | HashMap *next = NULL; | ||
| 366 | |||
| 367 | while (hash_map) | ||
| 368 | { | ||
| 369 | next = hash_map->next; | ||
| 370 | |||
| 371 | jadl_free(hash_map->key); | ||
| 372 | lisp_object_free(hash_map->value); | ||
| 373 | jadl_free(hash_map); | ||
| 374 | |||
| 375 | hash_map = next; | ||
| 376 | } | ||
| 377 | } | ||
| 378 | |||
| 379 | HashMap *hash_map_find(HashMap *hash_map, char* key) | ||
| 380 | { | ||
| 381 | if (hash_map == NULL) | ||
| 382 | return NULL; | ||
| 383 | |||
| 384 | while (hash_map) | ||
| 385 | { | ||
| 386 | if(strcmp(hash_map->key, key) == 0) | ||
| 387 | return hash_map; | ||
| 388 | |||
| 389 | hash_map = hash_map->next; | ||
| 390 | } | ||
| 391 | |||
| 392 | return NULL; | ||
| 393 | } | ||
| 394 | |||
| 395 | HashMap *hash_map_delete(HashMap *hash_map, char* key) | ||
| 396 | { | ||
| 397 | HashMap *hash_map_to_free = hash_map_find(hash_map, key); | ||
| 398 | |||
| 399 | if(hash_map_to_free == NULL) | ||
| 400 | return hash_map; | ||
| 401 | |||
| 402 | HashMap *new_hash_map = NULL; | ||
| 403 | |||
| 404 | if(hash_map_to_free->prev == NULL) | ||
| 405 | { | ||
| 406 | new_hash_map = hash_map_to_free->next; | ||
| 407 | new_hash_map->prev = NULL; | ||
| 408 | } else | ||
| 409 | { | ||
| 410 | new_hash_map = hash_map_to_free->prev; | ||
| 411 | new_hash_map->next=hash_map_to_free->next; | ||
| 412 | if(new_hash_map->next) | ||
| 413 | new_hash_map->next->prev = new_hash_map; | ||
| 414 | } | ||
| 415 | |||
| 416 | HashMap *prev = new_hash_map->prev; | ||
| 417 | while(prev) | ||
| 418 | { | ||
| 419 | new_hash_map = prev; | ||
| 420 | prev = prev->prev; | ||
| 421 | } | ||
| 422 | |||
| 423 | hash_map_to_free->next = NULL; | ||
| 424 | hash_map_free(hash_map_to_free); | ||
| 425 | |||
| 426 | return new_hash_map; | ||
| 427 | } | ||
| 428 | |||
| 429 | |||
| 430 | void hash_map_print(HashMap *hash_map) | ||
| 431 | { | ||
| 432 | while (hash_map) | ||
| 433 | { | ||
| 434 | printf("-------------\n"); | ||
| 435 | printf("HashMap->key = %s\n", hash_map->key); | ||
| 436 | printf("HashMap->value: \n"); | ||
| 437 | lisp_object_print(hash_map->value, 0); | ||
| 438 | |||
| 439 | hash_map = hash_map->next; | ||
| 440 | } | ||
| 441 | |||
| 442 | printf("-------------\n"); | ||
| 443 | } | ||
| 444 | |||
| 445 | HashMap *hash_last(HashMap *hash_map) | ||
| 446 | { | ||
| 447 | HashMap *next = NULL; | ||
| 448 | while (hash_map) | ||
| 449 | { | ||
| 450 | next = hash_map->next; | ||
| 451 | if(!next) | ||
| 452 | return hash_map; | ||
| 453 | hash_map = next; | ||
| 454 | } | ||
| 455 | return NULL; | ||
| 456 | } | ||
