Task: Stack

C: #include <stdio.h>
#include <stdlib.h>


#define DECL_STACK_TYPE(type, name)					\
typedef struct stk_##name##_t{type *buf; size_t alloc,len;}*stk_##name;	\
stk_##name stk_##name##_create(size_t init_size) {			\
	stk_##name s; if (!init_size) init_size = 4;			\
	s = malloc(sizeof(struct stk_##name##_t));			\
	if (!s) return 0;						\
	s->buf = malloc(sizeof(type) * init_size);			\
	if (!s->buf) { free(s); return 0; }				\
	s->len = 0, s->alloc = init_size;				\
	return s; }							\
int stk_##name##_push(stk_##name s, type item) {			\
	type *tmp;							\
	if (s->len >= s->alloc) {					\
		tmp = realloc(s->buf, s->alloc*2*sizeof(type));		\
		if (!tmp) return -1; s->buf = tmp;			\
		s->alloc *= 2; }					\
	s->buf[s->len++] = item;					\
	return s->len; }						\
type stk_##name##_pop(stk_##name s) {					\
	type tmp;							\
	if (!s->len) abort();						\
	tmp = s->buf[--s->len];						\
	if (s->len * 2 <= s->alloc && s->alloc >= 8) {			\
		s->alloc /= 2;						\
		s->buf = realloc(s->buf, s->alloc * sizeof(type));}	\
	return tmp; }							\
void stk_##name##_delete(stk_##name s) {				\
	free(s->buf); free(s); }

#define stk_empty(s) (!(s)->len)
#define stk_size(s) ((s)->len)

DECL_STACK_TYPE(int, int)

int main(void)
{
	int i;
	stk_int stk = stk_int_create(0);

	printf("pushing: ");
	for (i = 'a'; i <= 'z'; i++) {
		printf(" %c", i);
		stk_int_push(stk, i);
	}

	printf("\nsize now: %d", stk_size(stk));
	printf("\nstack is%s empty\n", stk_empty(stk) ? "" : " not");

	printf("\npoppoing:");
	while (stk_size(stk))
		printf(" %c", stk_int_pop(stk));
	printf("\nsize now: %d", stk_size(stk));
	printf("\nstack is%s empty\n", stk_empty(stk) ? "" : " not");

	
	stk_int_delete(stk);
	return 0;
}










Fortran: module mod_stack

  implicit none
  type node
    
    real*8, private :: data
    
    type(node), pointer, private :: next
  end type node
  private node

  type stack
    
    type(node), pointer, private :: first
    
    integer, private :: len=0
  contains
    procedure :: pop
    procedure :: push
    procedure :: peek
    procedure :: getSize
    procedure :: clearStack
    procedure :: isEmpty
  end type stack

contains

  function pop(this) result(x)
    class(stack) :: this
    real*8 :: x
    type(node), pointer :: tmp
    if ( this%len == 0 ) then
      print*, "popping from empty stack"
      
    end if
    tmp => this%first
    x = this%first%data
    this%first => this%first%next
    deallocate(tmp)
    this%len = this%len -1
  end function pop

  subroutine push(this, x)
    real*8 :: x
    class(stack), target :: this
    type(node), pointer :: new, tmp
    allocate(new)
    new%data = x
    if (.not. associated(this%first)) then
      this%first => new
    else
      tmp => this%first
      this%first => new
      this%first%next => tmp
    end if
    this%len = this%len + 1
  end subroutine push

  function peek(this) result(x)
    class(stack) :: this
    real*8 :: x
    x = this%first%data
  end function peek

  function getSize(this) result(n)
    class(stack) :: this
    integer :: n
    n = this%len
  end function getSize

  function isEmpty(this) result(empty)
    class(stack) :: this
    logical :: empty
    if ( this%len > 0 ) then
      empty = .FALSE.
    else
      empty = .TRUE.
    end if
  end function isEmpty

  subroutine clearStack(this)
    class(stack) :: this
    type(node), pointer :: tmp
    integer :: i
    if ( this%len == 0 ) then
      return
    end if
    do i = 1, this%len
      tmp => this%first
      if ( .not. associated(tmp)) exit
      this%first => this%first%next
      deallocate(tmp)
    end do
    this%len = 0
  end subroutine clearStack
end module mod_stack

program main
  use mod_stack
  type(stack) :: my_stack
  integer :: i
  real*8 :: dat
  do i = 1, 5, 1
    dat = 1.0 * i
    call my_stack%push(dat)
  end do
  do while ( .not. my_stack%isEmpty() )
    print*, my_stack%pop()
  end do
  call my_stack%clearStack()
end program main