blob: 914e0c13cefac304fe699fbb909ec6ef5823b3e4 [file] [log] [blame] [edit]
/*
* 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;
}