| /* |
| * Copyright 2017, NICTA |
| * |
| * This software may be distributed and modified according to the terms of |
| * the GNU General Public License version 2. Note that NO WARRANTY is provided. |
| * See "LICENSE_GPLv2.txt" for details. |
| * |
| * @TAG(NICTA_GPL) |
| */ |
| |
| $esc:(#include <stdio.h>) |
| $esc:(#include <stdlib.h>) |
| |
| typedef void *SysState; |
| |
| #include "generated.c" |
| |
| // add SysState to malloc'ing functions |
| $ty:(RR SysState (List a) Err) $id:list_create($ty:(SysState) arg){ |
| $ty:(RR SysState (List a) Err) ret; |
| |
| $ty:(List a) list; |
| list = malloc(sizeof(*list)); |
| |
| if(list != NULL){ |
| $ty:(Node a) head; |
| head = malloc(sizeof(*head)); |
| if(head != NULL){ |
| //Success |
| head->val = 0; |
| head->next = 0; |
| head->prev = 0; |
| list->head = head; |
| list->length = 0; |
| ret.p2.tag = TAG_ENUM_Success; |
| ret.p2.Success = list; |
| ret.p1 = arg; |
| return ret; |
| } |
| free(list); |
| } |
| |
| // Error |
| ret.p2.tag = TAG_ENUM_Error; |
| ret.p2.Error = 1; |
| ret.p1 = arg; |
| return ret; |
| } |
| |
| $ty:(SysState) $id:list_delete($ty:(((List a), SysState)) arg){ |
| $ty:(List a) list = arg.p1; |
| $ty:(SysState) ex = arg.p2; |
| $ty:(Node a) curr = list->head; |
| while(curr != NULL){ |
| $ty:(Node a) tmp = curr; |
| curr = ($ty:(Node a)) curr->next; |
| free(tmp); |
| } |
| free(list); |
| return ex; |
| } |
| |
| $ty:(RR SysState (List a) (List a)) $id:list_add($ty:((List a, a, U32, SysState)) arg){ |
| $ty:(List a) list = arg.p1; |
| $ty:(a) val = arg.p2; |
| $ty:(U32) index = arg.p3; |
| $ty:(SysState) ex = arg.p4; |
| int i; |
| |
| $ty:(RR SysState (List a) (List a)) ret; |
| ret.p1 = ex; |
| |
| if(index > list->length || index < 0){ |
| ret.p2.tag = TAG_ENUM_Error; |
| ret.p2.Error = list; |
| return ret; |
| } |
| |
| $ty:(Node a) prev = list->head; |
| for(i = 0; i < index; i++){ |
| prev = ($ty:(Node a)) prev->next; |
| } |
| |
| $ty:(Node a) new_node; |
| new_node = malloc(sizeof(*new_node)); |
| if(new_node == NULL){ |
| ret.p2.tag = TAG_ENUM_Error; |
| ret.p2.Error = list; |
| return ret; |
| } |
| |
| new_node->val = val; |
| new_node->next = prev->next; |
| new_node->prev = ($ty:(U64)) prev; |
| $ty:(Node a) next_node = ($ty:(Node a)) prev->next; |
| if(next_node != 0){ |
| next_node->prev = ($ty:(U64)) new_node; |
| } |
| prev->next = ($ty:(U64)) new_node; |
| list->length += 1; |
| |
| ret.p2.tag = TAG_ENUM_Success; |
| ret.p2.Success = list; |
| return ret; |
| } |
| |
| $ty:(R a Err) $id:list_get($ty:((List a, U32)) args){ |
| $ty:(R a Err) ret; |
| $ty:(List a) list = args.p1; |
| $ty:(U32) index = args.p2; |
| int i; |
| if(index >= list->length){ |
| ret.tag = TAG_ENUM_Error; |
| ret.Error = 1; |
| return ret; |
| } else { |
| $ty:(Node a) curr = list->head; |
| for(i = 0; i <= index; i++){ |
| curr = ($ty:(Node a)) curr->next; |
| } |
| ret.tag = TAG_ENUM_Success; |
| ret.Success = curr->val; |
| return ret; |
| } |
| } |
| |
| $ty:(RR SysState (List a) (List a)) $id:list_remove_index($ty:((List a, U32, SysState)) arg){ |
| $ty:(RR SysState (List a) (List a)) ret; |
| $ty:(List a) list = arg.p1; |
| $ty:(U32) index = arg.p2; |
| $ty:(SysState) ex = arg.p3; |
| int i; |
| |
| ret.p1 = ex; |
| if(index >= list->length){ |
| ret.p2.tag = TAG_ENUM_Error; |
| ret.p2.Error = list; |
| return ret; |
| } else { |
| $ty:(Node a) curr = list->head; |
| for(i = 0; i <= index; i++){ |
| curr = ($ty:(Node a)) curr->next; |
| } |
| $ty:(Node a) next_node = ($ty:(Node a)) curr->next; |
| $ty:(Node a) prev_node = ($ty:(Node a)) curr->prev; |
| prev_node->next = ($ty:(U64)) next_node; |
| if(next_node != 0){ |
| next_node->prev = ($ty:(U64)) prev_node; |
| } |
| free(curr); |
| list->length -= 1; |
| ret.p2.tag = TAG_ENUM_Success; |
| ret.p2.Success = list; |
| return ret; |
| } |
| } |
| |
| $ty:(RR SysState (List a) (List a)) $id:list_remove_value($ty:((List a, a, SysState)) arg){ |
| $ty:(List a) list = arg.p1; |
| $ty:(a) val = arg.p2; |
| $ty:(RR SysState (List a) (List a)) ret; |
| $ty:(Node a) node = list->head; |
| if(node->next == 0){ |
| ret.p2.tag = TAG_ENUM_Error; |
| ret.p2.Error = list; |
| return ret; |
| } else { |
| node = ($ty:(Node a)) node->next; |
| while(node!=NULL){ |
| if(node->val == val){ |
| $ty:(Node a) next_node = ($ty:(Node a)) node->next; |
| $ty:(Node a) prev_node = ($ty:(Node a)) node->prev; |
| prev_node->next = ($ty:(U64)) next_node; |
| if(next_node != 0){ |
| next_node->prev = ($ty:(U64)) prev_node; |
| } |
| free(node); |
| list->length -= 1; |
| ret.p2.tag = TAG_ENUM_Success; |
| ret.p2.Success = list; |
| return ret; |
| } |
| node = ($ty:(Node a)) node->next; |
| } |
| ret.p2.tag = TAG_ENUM_Error; |
| ret.p2.Error = list; |
| return ret; |
| } |
| } |
| |
| $ty:(SysState) print_str($ty:((SysState, String)) arg){ |
| $ty:(SysState) ex = arg.p1; |
| char * str = arg.p2; |
| printf("%s", str); |
| return ex; |
| } |
| |
| $ty:(SysState) list_U32_print($ty:((SysState, List U32)) arg){ |
| $ty:(SysState) ex = arg.p1; |
| $ty:(List U32) list = arg.p2; |
| if(list->length == 0){ |
| printf("[]\n"); |
| } else { |
| $ty:(Node U32) node = ($ty:(Node U32))(list->head)->next; |
| printf("["); |
| while(node->next != 0){ |
| printf("%d, ", node->val); |
| node = ($ty:(Node U32)) node->next; |
| } |
| printf("%d]\n", node->val); |
| } |
| return ex; |
| } |
| |
| $ty:(SysState) list_str_print($ty:((SysState, List String)) arg){ |
| $ty:(SysState) ex = arg.p1; |
| $ty:(List String) list = arg.p2; |
| if(list->length == 0){ |
| printf("[]\n"); |
| } else { |
| $ty:(Node String) node = ($ty:(Node String))(list->head)->next; |
| printf("["); |
| while(node->next != 0){ |
| printf("'%s', ", node->val); |
| node = ($ty:(Node String)) node->next; |
| } |
| printf("'%s']\n", node->val); |
| } |
| return ex; |
| } |
| |
| int main(void){ |
| $exp:test(0); |
| return 0; |
| } |