-module(life).

-export([bang/1]).

-define(CHAR_DEAD,   32).  % " "
-define(CHAR_ALIVE, 111).  % "o"
-define(CHAR_BAR,    45).  % "-"

-define(GEN_INTERVAL, 100).

-record(state, {x            :: non_neg_integer()
               ,y            :: non_neg_integer()
               ,n            :: pos_integer()
               ,bar          :: nonempty_string()
               ,board        :: array()
               ,gen_count    :: pos_integer()
               ,gen_duration :: non_neg_integer()
               ,print_time   :: non_neg_integer()
               }).

%% ============================================================================
%% API
%% ============================================================================

bang(Args) ->
    [X, Y] = [atom_to_integer(A) || A <- Args],
    {Time, Board} = timer:tc(fun() -> init_board(X, Y) end),
    State = #state{x            = X
                  ,y            = Y
                  ,n            = X * Y
                  ,bar          = [?CHAR_BAR || _ <- lists:seq(1, X)]
                  ,board        = Board
                  ,gen_count    = 1  % Consider inital state to be generation 1
                  ,gen_duration = Time
                  ,print_time   = 0  % There was no print time yet
    },
    life_loop(State).

%% ============================================================================
%% Internal
%% ============================================================================

life_loop(
    #state{x            = X
          ,y            = Y
          ,n            = N
          ,bar          = Bar
          ,board        = Board
          ,gen_count    = GenCount
          ,gen_duration = Time
          ,print_time   = LastPrintTime
    }=State) ->

    {PrintTime, ok} = timer:tc(
        fun() ->
            do_print_screen(Board, Bar, X, Y, N, GenCount, Time, LastPrintTime)
        end
    ),

    {NewTime, NewBoard} = timer:tc(
        fun() ->
            next_generation(X, Y, Board)
        end
    ),

    NewState = State#state{board        = NewBoard
                          ,gen_count    = GenCount + 1
                          ,gen_duration = NewTime
                          ,print_time   = PrintTime
    },

    NewTimeMil = NewTime / 1000,
    NextGenDelay = at_least_zero(round(?GEN_INTERVAL - NewTimeMil)),
    timer:sleep(NextGenDelay),

    life_loop(NewState).

at_least_zero(Integer) when Integer >= 0 -> Integer;
at_least_zero(_) -> 0.

do_print_screen(Board, Bar, X, Y, N, GenCount, Time, PrintTime) ->
    ok = do_print_status(Bar, X, Y, N, GenCount, Time, PrintTime),
    ok = do_print_board(Board).

do_print_status(Bar, X, Y, N, GenCount, TimeMic, PrintTimeMic) ->
    TimeSec = TimeMic / 1000000,
    PrintTimeSec = PrintTimeMic / 1000000,
    ok = io:format("~s~n", [Bar]),
    ok = io:format(
        "X: ~b Y: ~b CELLS: ~b GENERATION: ~b DURATION: ~f PRINT TIME: ~f~n",
        [X, Y, N, GenCount, TimeSec, PrintTimeSec]
    ),
    ok = io:format("~s~n", [Bar]).

do_print_board(Board) ->
    % It seems that just doing a fold should be faster than map + to_list
    % combo, but, after measuring several times, map + to_list has been
    % consistently (nearly twice) faster than either foldl or foldr.
    RowStrings = array:to_list(
        array:map(
            fun(_, Row) ->
                array:to_list(
                    array:map(
                        fun(_, State) ->
                            state_to_char(State)
                        end,
                        Row
                    )
                )
            end,
            Board
        )
    ),

    ok = lists:foreach(
        fun(RowString) ->
            ok = io:format("~s~n", [RowString])
        end,
        RowStrings
    ).

state_to_char(0) -> ?CHAR_DEAD;
state_to_char(1) -> ?CHAR_ALIVE.

next_generation(W, H, Board) ->
    array:map(
        fun(Y, Row) ->
            array:map(
                fun(X, State) ->
                    Neighbors = filter_offsides(H, W, neighbors(X, Y)),
                    States = neighbor_states(Board, Neighbors),
                    LiveNeighbors = lists:sum(States),
                    new_state(State, LiveNeighbors)
                end,
                Row
            )
        end,
        Board
    ).

new_state(1, LiveNeighbors) when LiveNeighbors  <  2 -> 0;
new_state(1, LiveNeighbors) when LiveNeighbors  <  4 -> 1;
new_state(1, LiveNeighbors) when LiveNeighbors  >  3 -> 0;
new_state(0, LiveNeighbors) when LiveNeighbors =:= 3 -> 1;
new_state(State, _LiveNeighbors) -> State.

neighbor_states(Board, Neighbors) ->
    [array:get(X, array:get(Y, Board)) || {X, Y} <- Neighbors].

filter_offsides(H, W, Coordinates) ->
    [{X, Y} || {X, Y} <- Coordinates, is_onside(X, Y, H, W)].

is_onside(X, Y, H, W) when (X >= 0) and (Y >= 0) and (X < W) and (Y < H) -> true;
is_onside(_, _, _, _) -> false.

neighbors(X, Y) ->
    [{X + OffX, Y + OffY} || {OffX, OffY} <- offsets()].

offsets() ->
    [offset(D) || D <- directions()].

offset('N')  -> { 0, -1};
offset('NE') -> { 1, -1};
offset('E')  -> { 1,  0};
offset('SE') -> { 1,  1};
offset('S')  -> { 0,  1};
offset('SW') -> {-1,  1};
offset('W')  -> {-1,  0};
offset('NW') -> {-1, -1}.

directions() ->
    ['N', 'NE', 'E', 'SE', 'S', 'SW', 'W', 'NW'].

init_board(X, Y) ->
    array:map(fun(_, _) -> init_row(X) end, array:new(Y)).

init_row(X) ->
    array:map(fun(_, _) -> init_cell_state() end, array:new(X)).

init_cell_state() ->
    crypto:rand_uniform(0, 2).

atom_to_integer(Atom) ->
    list_to_integer(atom_to_list(Atom)).


case X of
  {N,M} when N > M -> M;
  {N,M} when N < M -> N;
  _ -> equal
end.


PROGRAM LIFE

!$INTEGER

!$KEY
!for C-64 compatibility

CONST Xmax=38,Ymax=20

DIM x,y,N
DIM WORLD[39,21],NextWORLD[39,21]

BEGIN

! Glider test
!------------------------------------------
WORLD[1,1]=1 WORLD[1,2]=0 WORLD[1,3]=0
WORLD[2,1]=0 WORLD[2,2]=1 WORLD[2,3]=1
WORLD[3,1]=1 WORLD[3,2]=1 WORLD[3,3]=0
!------------------------------------------

PRINT(CHR$(12);"Press any key to interrupt")
LOOP
  PRINT(CHR$(11);) PRINT
  PRINT(STRING$(Xmax+2,"-"))
  !---------- endless world ---------
  FOR y=1 TO Ymax DO
    WORLD[0,y]=WORLD[Xmax,y]
    WORLD[Xmax+1,y]=WORLD[1,y]
  END FOR
  FOR x=1 TO Xmax DO
    WORLD[x,0]=WORLD[x,Ymax]
    WORLD[x,Ymax+1]=WORLD[x,1]
  END FOR
  WORLD[0,0]=WORLD[Xmax,Ymax]
  WORLD[Xmax+1,Ymax+1]=WORLD[1,1]
  WORLD[Xmax+1,0]=WORLD[1,Ymax]
  WORLD[0,Ymax+1]=WORLD[Xmax,1]
  !---------- endless world ---------
  FOR y=1 TO Ymax DO
    PRINT("|";)
    FOR x=1 TO Xmax DO
      PRINT(CHR$(32+WORLD[x,y]*3);)
      N=WORLD[x-1,y-1]+WORLD[x-1,y]+WORLD[x-1,y+1]+WORLD[x,y-1]
      N=N+WORLD[x,y+1]+WORLD[x+1,y-1]+WORLD[x+1,y]+WORLD[x+1,y+1]
      IF (WORLD[x,y]<>0 AND (N=2 OR N=3)) OR (WORLD[x,y]=0 AND N=3) THEN
        NextWORLD[x,y]=1
      ELSE
        NextWORLD[x,y]=0
      END IF
    END FOR
    PRINT("|")
  END FOR
  PRINT(STRING$(Xmax+2,"-"))
  PAUSE(0.1)

  FOR x=0 TO Xmax+1 DO
    FOR y=0 TO Ymax+1 DO
      WORLD[x,y]=NextWORLD[x,y]
      NextWORLD[x,y]=0
    END FOR
  END FOR
  REPEAT
      GET(A$)
  UNTIL A$<>""
  EXIT IF A$=CHR$(27)
END LOOP

PRINT("Press any key to exit")
REPEAT
UNTIL GETKEY$<>""
END PROGRAM


printfn "%s" (if 3<2 then "3 is less than 2" else "3 is not less than 2")


let count (a: _ [,]) x y =
  let m, n = a.GetLength 0, a.GetLength 1
  let mutable c = 0
  for x in x-1..x+1 do
    for y in y-1..y+1 do
      if x>=0 && x<m && y>=0 && y<n && a.[x, y] then
        c <- c + 1
  if a.[x, y] then c-1 else c

let rule (a: _ [,]) x y =
  match a.[x, y], count a x y with
  | true, (2 | 3) | false, 3 -> true
  | _ -> false

open System.Windows
open System.Windows.Media.Imaging

[<System.STAThread>]
do
  let rand = System.Random()
  let n = 256
  let game = Array2D.init n n (fun _ _ -> rand.Next 2 = 0) |> ref
  let image = Controls.Image(Stretch=Media.Stretch.Uniform)
  let format = Media.PixelFormats.Gray8
  let pixel = Array.create (n*n) 0uy
  let update _ =
    game := rule !game |> Array2D.init n n
    for x in 0..n-1 do
      for y in 0..n-1 do
        pixel.[x+y*n] <- if (!game).[x, y] then 255uy else 0uy
    image.Source <-
      BitmapSource.Create(n, n, 1.0, 1.0, format, null, pixel, n)
  Media.CompositionTarget.Rendering.Add update
  Window(Content=image, Title="Game of Life")
  |> (Application()).Run |> ignore


if: (x < y) then: {
  "x < y!" println # will only execute this block if x < y
}


;{Conway's Game of Life in Fermat}
;{square grid with wrap-around boundaries}

size:=50;                         {how big a grid do you want? This fits my screen OK, change this for your own screen}

Array w1[size,size], w2[size,size];      {set up an active world and a 'scratchpad' world}
act:=1;
buf:=2;
%[1]:=[w1];                      {Fermat doesn't have 3D arrays in the normal sense--}
%[2]:=[w2];                      {we need to use the somewhat odd "array of arrays" functionality}

Func Cls = for i = 1 to size do !!; od.;     {"clear screen" by printing a bunch of newlines}

Func Draw =                     {draw the active screen}
    for i = 1 to size do
        for j = 1 to size do
            if %[act][i, j] = 1 then !('# ') else !('. ') fi;
        od;
        !;
    od;
.;

Func Rnd =                                   {randomize the grid with a density of 40% live cells}
    for i = 1 to size do
        for j = 1 to size do
            if Rand|5<2 then %[act][i, j] := 1 else %[act][i, j] := 0 fi;
        od;
    od;
    Cls;
    Draw;
.;

Func Blinker =                               {clears the screen except for a blinker in the top left corner}
    for i = 1 to size do
        for j = 1 to size do
            %[act][i, j] := 0;
        od;
    od;
    %[act][1,2] := 1;
    %[act][2,2] := 1;
    %[act][3,2] := 1;
    Cls;
    Draw;
.;

Func Iter =                                 {do one iteration}
    for i = 1 to size do
        if i = 1 then im := size else im := i - 1 fi;        {handle wrap around}
        if i = size then ip := 1 else ip := i + 1 fi;
        for j = 1 to size do
            if j = 1 then jm := size else jm := j - 1 fi;
            if j = size then jp := 1 else jp := j + 1 fi;
            neigh :=  %[act][im, jm];                        {count neigbours}
            neigh :+ (%[act][im, j ]);
            neigh :+ (%[act][im, jp]);
            neigh :+ (%[act][i , jm]);
            neigh :+ (%[act][i , jp]);
            neigh :+ (%[act][ip, jm]);
            neigh :+ (%[act][ip, j ]);
            neigh :+ (%[act][ip, jp]);
            if neigh < 2 or neigh > 3 then %[buf][i, j] := 0 fi;      {alive and dead rules}
            if neigh = 2 then %[buf][i, j] := %[act][i, j] fi;
            if neigh = 3 then %[buf][i, j] := 1 fi;
        od;
    od;
    Swap(act, buf);     {rather than copying the scratch over into the active, just exchange their identities}
    Cls;
    Draw;
.;

choice := 9;
while choice <> 0 do              {really rough menu, not the point of this exercise}
    ?choice;
    if choice=4 then Cls fi;
    if choice=3 then Blinker fi;
    if choice=2 then Rnd fi;
    if choice=1 then Iter fi;
od;

!!'John Horton Conway (26 December 1937 – 11 April 2020)';


( condition ) IF ( true statements ) THEN
( condition ) IF ( true statements ) ELSE ( false statements ) THEN


if ( a .gt. 20.0 ) then
   q = q + a**2
else if ( a .ge. 0.0 ) then
   q = q + 2*a**3
else
   q = q - a
end if


 \ The fast wrapping requires dimensions that are powers of 2.
 1 6 lshift constant w \ 64
 1 4 lshift constant h \ 16

 : rows    w * 2* ;
 1 rows constant row
 h rows constant size

 create world size allot
 world   value old
 old w + value new

 variable gens
 : clear  world size erase     0 gens ! ;
 : age  new old to new to old  1 gens +! ;

 : col+  1+ ;
 : col-  1- dup w and + ; \ avoid borrow into row
 : row+  row + ;
 : row-  row - ;
 : wrap ( i -- i ) [ size w - 1- ] literal and ;
 : [email protected] ( i -- 0/1 ) wrap old + [email protected] ;
 : w! ( 0/1 i -- ) wrap old + c! ;

 : foreachrow ( xt -- )
   size 0 do  I over execute  row +loop drop ;

 : showrow ( i -- ) cr
   old + w over + swap do I [email protected] if [char] * else bl then emit loop ;
 : show  ['] showrow foreachrow  cr ." Generation " gens @ . ;

 : sum-neighbors ( i -- i n )
   dup  col- row- [email protected]
   over      row- [email protected] +
   over col+ row- [email protected] +
   over col-      [email protected] +
   over col+      [email protected] +
   over col- row+ [email protected] +
   over      row+ [email protected] +
   over col+ row+ [email protected] + ;
 : gencell ( i -- )
   sum-neighbors  over old + [email protected]
   or 3 = 1 and   swap new + c! ;
 : genrow ( i -- )
   w over + swap do I gencell loop ;
 : gen  ['] genrow foreachrow  age ;

 : life  begin gen 0 0 at-xy show key? until ;

 \ patterns
 char | constant '|'
 : pat ( i addr len -- )
   rot dup 2swap  over + swap do
     I [email protected] '|' = if drop row+ dup else
     I [email protected] bl  = 1+ over w!  col+ then
   loop 2drop ;

 : blinker s" ***" pat ;
 : toad s" ***| ***" pat ;
 : pentomino s" **| **| *" pat ;
 : pi s" **| **|**" pat ;
 : glider s"  *|  *|***" pat ;
 : pulsar s" *****|*   *" pat ;
 : ship s"  ****|*   *|    *|   *" pat ;
 : pentadecathalon s" **********" pat ;
 : clock s"  *|  **|**|  *" pat ;

 clear  0 glider show
  *
   *
 ***

 Generation 0  ok
 gen show

 * *
  **
  *
 Generation 1  ok


Dim a As Integer = 1
If a = 1 Then
  sub1
ElseIf a = 2 Then
  sub2
Else
  sub3
End If


set var 'Hello World'
if test $var = 'Hello World'
    echo 'Welcome.'
else if test $var = 'Bye World'
    echo 'Bye.'
else
    echo 'Huh?'
end


 PROGRAM LIFE_2D
   IMPLICIT NONE

   INTEGER, PARAMETER :: gridsize = 10
   LOGICAL :: cells(0:gridsize+1,0:gridsize+1) = .FALSE.
   INTEGER :: i, j, generation=0
   REAL :: rnums(gridsize,gridsize)

 !  Start patterns
 !  **************
 !  cells(2,1:3) = .TRUE.                                                  ! Blinker
 !  cells(3,4:6) = .TRUE. ; cells(4,3:5) = .TRUE.                          ! Toad
 !  cells(1,2) = .TRUE. ; cells(2,3) = .TRUE. ; cells(3,1:3) = .TRUE.      ! Glider
    cells(3:5,3:5) = .TRUE. ; cells(6:8,6:8) = .TRUE.                      ! Figure of Eight
 !  CALL RANDOM_SEED
 !  CALL RANDOM_NUMBER(rnums)
 !  WHERE (rnums>0.6) cells(1:gridsize,1:gridsize) = .TRUE.                ! Random universe

   CALL Drawgen(cells(1:gridsize, 1:gridsize), generation)
   DO generation = 1, 8
      CALL NextgenV2(cells)
      CALL Drawgen(cells(1:gridsize, 1:gridsize), generation)
   END DO

 CONTAINS

   SUBROUTINE Drawgen(cells, gen)
     LOGICAL, INTENT(IN OUT) :: cells(:,:)
     INTEGER, INTENT(IN) :: gen

     WRITE(*, "(A,I0)") "Generation ", gen
     DO i = 1, SIZE(cells,1)
        DO j = 1, SIZE(cells,2)
           IF (cells(i,j)) THEN
              WRITE(*, "(A)", ADVANCE = "NO") "#"
           ELSE
              WRITE(*, "(A)", ADVANCE = "NO") " "
           END IF
        END DO
        WRITE(*,*)
     END DO
     WRITE(*,*)
   END SUBROUTINE Drawgen

  SUBROUTINE Nextgen(cells)
     LOGICAL, INTENT(IN OUT) :: cells(0:,0:)
     LOGICAL :: buffer(0:SIZE(cells, 1)-1, 0:SIZE(cells, 2)-1)
     INTEGER :: neighbours, i, j

     buffer = cells   ! Store current status
     DO j = 1, SIZE(cells, 2)-2
        DO i = 1, SIZE(cells, 1)-2
          if(buffer(i, j)) then
            neighbours = sum(count(buffer(i-1:i+1, j-1:j+1), 1)) - 1
          else
            neighbours = sum(count(buffer(i-1:i+1, j-1:j+1), 1))
          end if

          SELECT CASE(neighbours)
            CASE (0:1, 4:8)
               cells(i,j) = .FALSE.

            CASE (2)
               ! No change

            CASE (3)
               cells(i,j) = .TRUE.
          END SELECT

        END DO
     END DO
  END SUBROUTINE Nextgen

!###########################################################################
!   In this version instead of cycling through all points an integer array
! is used the sum the live neighbors of all points. The sum is done with
! the entire array cycling through the eight positions of the neighbors.
!   Executing a grid size of 10000 in 500 generations this version gave a
! speedup of almost 4 times.
!###########################################################################
  PURE SUBROUTINE NextgenV2(cells)
     LOGICAL, INTENT(IN OUT) :: cells(:,:)
     INTEGER(KIND=1) :: buffer(1:SIZE(cells, 1)-2,1:SIZE(cells, 2)-2)
     INTEGER :: gridsize, i, j

     gridsize=SIZE(cells, 1)
     buffer=0

     DO j=-1, 1
        DO i=-1,1
           IF(i==0 .AND. j==0) CYCLE
           WHERE(cells(i+2:gridsize-i-1,j+2:gridsize-j-1)) buffer=buffer+1
        END DO
     END DO

     WHERE(buffer<2 .or. buffer>3) cells(2:gridsize-1,2:gridsize-1) = .FALSE.
     WHERE(buffer==3) cells(2:gridsize-1,2:gridsize-1) = .TRUE.
  END SUBROUTINE NextgenV2
!###########################################################################
 END PROGRAM LIFE_2D


if <condition> then <truebranch> else <falsebranch>


if <condition> then
    <statements>
elif <condition> then
    <statements>
else
    <statements>
fi;


start = now[]
// Generate a random 10x10 grid with "1" being on and "0" being off
instructions = ["1000100110","0001100010","1000111101","1001111110","0000110011","1111000001","0100001110","1011101001","1001011000","1101110111"]

// Create dictionary of starting positions.
rowCounter = 0
display = new dict
for instructionStr = instructions
{
   rowCounter = rowCounter + 1
   columnCounter = 0
   instructionArr = charList[instructionStr]
   for instruction = instructionArr
   {
      columnCounter = columnCounter + 1
      arr = [rowCounter,columnCounter]
      if instruction == "1"
         [email protected] = 1
      else
         [email protected] = 0
   }
}

// Create toggle dictionary to track changes. It starts off with everything off.
toggle = new dict
multifor[x,y] = [new range[1,10],new range[1,10]]
{
   arr = [x,y]
   [email protected] = 0
}

// Animate the game of life
a = new Animation[3/s]
win = undef

// Loop through 10 changes to the grid. The starting points will tick down to two stable unchanging shapes in 10 steps.
for i = 1 to 12 // 12 steps so animation will pause on final state.
{
   // Graphics item for this frame of the animation.
   g = new graphics
   g.backgroundColor[1,1,1]
   // Add in a transparent shape to prevent the image from jiggle to automatic scaling.
   g.color[0,0,0,0] // Transparent black
   g.fillRectSides[-1, -1, 12, 12] // Set minimum size
   g.clipRectSides[-1, -1, 12, 12] // Set maximum size
   g.color[0,0,0] // Color back to default black
   multifor[x1,y1] = [new range[1,10],new range[1,10]]
   {
      tval = [x1,y1]
      // This is programmed with a hard edge. Points beyond the border aren't considered.
      xmax = min[x1+1,10]
      xmin = max[x1-1,1]
      ymax = min[y1+1,10]
      ymin = max[y1-1,1]
      // Range will be 8 surrounding cells or cells up to border.
      pointx = new range[xmin,xmax]
      pointy = new range[ymin,ymax]
      pointsum = 0
      status = 0
      // Process each surrounded point
      multifor[x2,y2] = [pointx,pointy]
      {
         // Assign the array to a variable so it can be used as a dictionary reference.
         point = [x2,y2]
         if x2 == x1 && y2 == y1
         {
            status = [email protected]
         } else // Calculate the total of surrounding points
         {
            pointsum = pointsum + [email protected]
         }
      }
      // Animate if the point is on.
      if status == 1
      {
         g.color[0,0,0]
         g.fillEllipseCenter[x1,y1,1,1]
      }
      [email protected] = status // This will be overwritten if needed by neighbor check conditions below.
	  // Check if off point has 3 on point neighbors
      if status == 0 && pointsum == 3
      {
         [email protected] = 1
      }
	  // Check if on point has between 2 and 3 on point neighbors
      if status == 1 && (pointsum < 2 || pointsum > 3)
      {
         [email protected] = 0
      }
   }
   // Add the current frame to the animation
   a.add[g]
   // Replace the current display with the toggle values.
   for toggleKeys = keys[toggle]
   {
      val = [email protected]
      [email protected] = val
   }
}

// Write the animation file
a.write["FrinkAnimationGoL.gif",400,400]

end = now[]
println["Program run time: " + ((end - start)*1.0 -> "seconds")]


IF x == 1
   SomeFunc1()
ELSEIF x == 2
   SomeFunc2()
ELSE
   SomeFunc()
ENDIF


import lists.zipWithIndex
import util.Regex

data Rule( birth, survival )

val Mirek = Regex( '([0-8]+)/([0-8]+)' )
val Golly = Regex( 'B([0-8]+)/S([0-8]+)' )

def decode( rule ) =
  def makerule( b, s ) = Rule( [int(d) | d <- b], [int(d) | d <- s] )

  case rule
    Mirek( s, b ) -> makerule( b, s )
    Golly( b, s ) -> makerule( b, s )
    _ -> error( "unrecognized rule: $rule" )

def fate( state, crowding, rule ) = crowding in rule( int(state) )

def crowd( buffer, x, y ) =
  res = 0

  def neighbour( x, y ) =
    if x >= 0 and x < N and y >= 0 and y < N
      res += int( buffer(x, y) )

  for i <- x-1..x+1
    neighbour( i, y - 1 )
    neighbour( i, y + 1 )

  neighbour( x - 1, y )
  neighbour( x + 1, y )
  res

def display( buffer ) =
  for j <- 0:N
    for i <- 0:N
      print( if buffer(i, j) then '*' else '\u00b7' )

    println()

def generation( b1, b2, rule ) =
  for i <- 0:N, j <- 0:N
    b2(i, j) = fate( b1(i, j), crowd(b1, i, j), rule )

def pattern( p, b, x, y ) =
  for (r, j) <- zipWithIndex( list(WrappedString(p).stripMargin().split('\n')).drop(1).dropRight(1) )
    for i <- 0:r.length()
      b(x + i, y + j) = r(i) == '*'

var current = 0
val LIFE = decode( '23/3' )
val N = 4
val buffers = (array( N, N, (_, _) -> false ), array( N, N ))

def reset =
  for i <- 0:N, j <- 0:N
    buffers(0)(i, j) = false

  current = 0

def iteration =
  display( buffers(current) )
  generation( buffers(current), buffers(current = (current + 1)%2), LIFE )
  println( 5'-' )

// two patterns to be tested
blinker = '''
  |
  |***
  '''

glider = '''
  | *
  |  *
  |***
  '''

// load "blinker" pattern and run for three generations
pattern( blinker, buffers(0), 0, 0 )

repeat 3
  iteration()

// clear grid, load "glider" pattern and run for five generations
reset()
pattern( glider, buffers(0), 0, 0 )

repeat 5
  iteration()


fac x = if x==0 then
           1
           else x * fac (x - 1)


IF( a > 5 ) WRITE(Messagebox) a ! single line IF

IF( a >= b ) THEN
    WRITE(Text=some_string) a, b
  ELSEIF(some_string > "?") THEN
    WRITE(ClipBoard) some_string
  ELSEIF( nonzero ) THEN
    WRITE(WINdowhandle=nnn) some_string
  ELSE
    WRITE(StatusBar) a, b, some_string
ENDIF


// Life simulator (game). Console (CLI) version.
// It is a 'cellular automaton', and was invented by Cambridge mathematician John Conway.

// The Rules

// For a space that is 'populated':
//     Each cell with one or no neighbors dies, as if by solitude.
//     Each cell with four or more neighbors dies, as if by overpopulation.
//     Each cell with two or three neighbors survives.
// For a space that is 'empty' or 'unpopulated'
//     Each cell with three neighbors becomes populated.
// -----------------------------------------------------
#g
// Get the terminal-resolution:
terminallines   -- sto tlin
terminalcolumns    sto tcol
// .............................
// Verify the commandline parameters:
argc 3 < { #s ."Usage: " 0 argv print SPACE 1 argv print ." lifeshape-file.txt\n" end }
2 argv 'f !istrue { #s ."The given file ( " 2 argv print ." ) doesn't exist!\n" end }
startingshape 2 argv filetolist // read the file into the list
startingshape maxlinelength sto maxlinlen
neighbour    @tlin @tcol createlist   // Generate the stringarray for the neighbour-calculations
livingspace  @tlin @tcol createlist   // Generate the stringarray for the actual generations
cellscreen   @tlin @tcol createscreen // Generate the stringarray for the visible livingspace
// Calculate offset for the shape ( it must be put to the centre):
@tlin startingshape~ - 2 / sto originlin
@tcol @maxlinlen     - 2 / sto origincol

startingshape {{|
{{}} {{|}} {{-}} [[]] 32 > { 1 }{ 0 } sto emblem
livingspace @originlin {{|}} + @origincol {{-}} + @emblem [[^]]
|}}

cursoroff
// ==================================================================
{... // infinite loop starts
sbr §renderingsbr
topleft cellscreen !printlist
."Generation: " {...} print fflush // print the number of the generations.
neighbour 0 filluplist // fill up the neighbour list with zero value
// Calculate neighbourhoods
neighbour {{|
{{|}} {{-}} sbr §neighbors
{{}} {{|}} {{-}} @n [[^]] // store the neighbournumber
|}}

// Now, kill everybody if the neighbors are less than 2 or more than 3:
neighbour {{|
{{|}} {{-}} sbr §killsbr
|}}

// Generate the newborn cells:
neighbour {{|
{{}} {{|}} {{-}} [[]] 3 == { livingspace {{|}} {{-}} 1 [[^]] }
|}}

50000 usleep
//2 sleep
...} // infinite loop ends
// ==================================================================
end
killsbr:
sto innerindex sto outerindex
neighbour @outerindex @innerindex [[]] 2 < then §kill
neighbour @outerindex @innerindex [[]] 3 > then §kill
rts
kill: livingspace @outerindex @innerindex 0 [[^]] rts
// ==========================================================
neighbors: // This subroutine calculates the quantity of neighborhood
sto y sto x zero n
livingspace @x ? @tlin --                 @y ? @tcol --                  [[]] sum n // upleft    corner
livingspace @x ? @tlin --                 @y                             [[]] sum n // upmid     corner
livingspace @x ? @tlin --                 @y ++ dup  @tcol == { drop 0 } [[]] sum n // upright   corner
livingspace @x                            @y ? @tcol --                  [[]] sum n // midleft   corner
livingspace @x                            @y ++ dup  @tcol == { drop 0 } [[]] sum n // midright  corner
livingspace @x ++ dup @tlin == { drop 0 } @y ? @tcol --                  [[]] sum n // downleft  corner
livingspace @x ++ dup @tlin == { drop 0 } @y                             [[]] sum n // downmid   corner
livingspace @x ++ dup @tlin == { drop 0 } @y ++ dup  @tcol == { drop 0 } [[]] sum n // downright corner
rts
// ==========================================================
renderingsbr:
livingspace {{|
cellscreen   {{|}} {{-}}
{{}} {{|}} {{-}} [[]] { '* }{ 32 } [[^]]
|}}
rts

{ „startingshape” }
{ „livingspace” }
{ „cellscreen” }
{ „innerindex” }
{ „outerindex” }
{ „maxlinlen” }
{ „neighbour” }
{ „originlin” }
{ „origincol” }
{ „emblem” }
{ „tlin” }
{ „tcol” }
{ „x” } { „y” } { „n” }


IF X THEN
	// do if X is not 0
ELSE
	// do if X is 0
END;


//'i' supports if, else, and else if
software {
	a = 3

	if a = 3
		print("a = three")
	else if a = 2
		print("a = two")
	else
		print("a = ", a)
	end
}


fun bint(b: bool): int = if b then 1 else 0
fun intb(x: int): bool = if x == 0 then False else True

fun to_bool_board(board: [][]int): [][]bool =
  map (fn (r: []int): []bool  => map intb r) board

fun to_int_board(board: [][]bool): [][]int =
  map (fn (r: []bool): []int  => map bint r) board

fun cell_neighbors(i: int, j: int, board: [n][m]bool): int =
  unsafe
  let above = (i - 1) % n
  let below = (i + 1) % n
  let right = (j + 1) % m
  let left = (j - 1) % m in
  bint board[above,left] + bint board[above,j]  + bint board[above,right] +
  bint board[i,left] + bint board[i,right] +
  bint board[below,left] + bint board[below,j] + bint board[below,right]

fun all_neighbours(board: [n][m]bool): [n][m]int =
  map (fn (i: int): []int  =>
        map (fn (j: int): int  => cell_neighbors(i,j,board)) (iota m))
      (iota n)

fun iteration(board: [n][m]bool): [n][m]bool =
  let lives = all_neighbours(board) in
  zipWith (fn (lives_r: []int) (board_r: []bool): []bool  =>
            zipWith (fn (neighbors: int) (alive: bool): bool  =>
                      if neighbors < 2
                      then False
                      else if neighbors == 3 then True
                      else if alive && neighbors < 4 then True
                      else False)
                    lives_r board_r)
           lives board

fun main(int_board: [][]int, iterations: int): [][]int =
  -- We accept the board as integers for convenience, and then we
  -- convert to booleans here.
  let board = to_bool_board int_board in
  loop (board) = for i < iterations do
    iteration board in
  to_int_board board


if a eq 5 then print, "a equals five" [else print, "a is something else"]


package main

import (
	"bytes"
	"fmt"
	"math/rand"
	"time"
)

type Field struct {
	s    [][]bool
	w, h int
}

func NewField(w, h int) Field {
	s := make([][]bool, h)
	for i := range s {
		s[i] = make([]bool, w)
	}
	return Field{s: s, w: w, h: h}
}

func (f Field) Set(x, y int, b bool) {
	f.s[y][x] = b
}

func (f Field) Next(x, y int) bool {
	on := 0
	for i := -1; i <= 1; i++ {
		for j := -1; j <= 1; j++ {
			if f.State(x+i, y+j) && !(j == 0 && i == 0) {
				on++
			}
		}
	}
	return on == 3 || on == 2 && f.State(x, y)
}

func (f Field) State(x, y int) bool {
	for y < 0 {
		y += f.h
	}
	for x < 0 {
		x += f.w
	}
	return f.s[y%f.h][x%f.w]
}

type Life struct {
	w, h int
	a, b Field
}

func NewLife(w, h int) *Life {
	a := NewField(w, h)
	for i := 0; i < (w * h / 2); i++ {
		a.Set(rand.Intn(w), rand.Intn(h), true)
	}
	return &Life{
		a: a,
		b: NewField(w, h),
		w: w, h: h,
	}
}

func (l *Life) Step() {
	for y := 0; y < l.h; y++ {
		for x := 0; x < l.w; x++ {
			l.b.Set(x, y, l.a.Next(x, y))
		}
	}
	l.a, l.b = l.b, l.a
}

func (l *Life) String() string {
	var buf bytes.Buffer
	for y := 0; y < l.h; y++ {
		for x := 0; x < l.w; x++ {
			b := byte(' ')
			if l.a.State(x, y) {
				b = '*'
			}
			buf.WriteByte(b)
		}
		buf.WriteByte('\n')
	}
	return buf.String()
}

func main() {
	l := NewLife(80, 15)
	for i := 0; i < 300; i++ {
		l.Step()
		fmt.Print("\x0c")
		fmt.Println(l)
		time.Sleep(time.Second / 30)
	}
}


[short form]
if N is 1, say "one.";
otherwise say "not one.";

[block form]
if N is 1:
	say "one.";
otherwise if N is 2:
	say "two.";
otherwise:
	say "not one or two.";

[short and long forms can be negated with "unless"]
unless N is 1, say "not one."


theory Scratch
  imports Main
begin

text‹if-then-else›
lemma "(if True then 42 else 0) = 42" by simp

text‹case statement with pattern matching, which evaluates to the True-case›
lemma "case [42] of
         Nil  ⇒ False
       | [x]  ⇒ True
       | x#xs ⇒ False" by simp

text‹Loops are implemented via recursive functions›
fun recurse :: "nat ⇒ nat" where
  "recurse 0 = 0"
| "recurse (Suc n) = recurse n"

text‹The function always returns zero.›
lemma "recurse n = 0" by(induction n) simp+

end


class GameOfLife {

	int generations
	int dimensions
	def board

	GameOfLife(generations = 5, dimensions = 5) {
		this.generations = generations
		this.dimensions = dimensions
		this.board = createBlinkerBoard()
	}

	static def createBlinkerBoard() {
		[
			[].withDefault{0},
			[0,0,1].withDefault{0},
			[0,0,1].withDefault{0},
			[0,0,1].withDefault{0}
		].withDefault{[]}
	}

	static def createGliderBoard() {
		[
			[].withDefault{0},
			[0,0,1].withDefault{0},
			[0,0,0,1].withDefault{0},
			[0,1,1,1].withDefault{0}
		].withDefault{[]}
	}

	static def getValue(board, point) {
		def x,y
		(x,y) = point
		if(x < 0 || y < 0) {
			return 0
		}
		board[x][y] ? 1 : 0
	}

	static def countNeighbors(board, point) {
		def x,y
		(x,y) = point
		def neighbors = 0
		neighbors += getValue(board, [x-1,y-1])
		neighbors += getValue(board, [x-1,y])
		neighbors += getValue(board, [x-1,y+1])
		neighbors += getValue(board, [x,y-1])
		neighbors += getValue(board, [x,y+1])
		neighbors += getValue(board, [x+1,y-1])
		neighbors += getValue(board, [x+1,y])
		neighbors += getValue(board, [x+1,y+1])
		neighbors
	}

	static def conwaysRule(currentValue, neighbors) {
		def newValue = 0
		if(neighbors == 3 || (currentValue && neighbors == 2)) {
			newValue = 1
		}
		newValue
	}

	static def createNextGeneration(currentBoard, dimensions) {
		def newBoard = [].withDefault{[].withDefault{0}}
		(0..(dimensions-1)).each { row ->
			(0..(dimensions-1)).each { column ->
				def point = [row, column]
				def currentValue = getValue(currentBoard, point)
				def neighbors = countNeighbors(currentBoard, point)
				newBoard[row][column] = conwaysRule(currentValue, neighbors)
			}
		}
		newBoard
	}

	static def printBoard(generationCount, board, dimensions) {
		println "Generation ${generationCount}"
		println '*' * 80
		(0..(dimensions-1)).each { row ->
			(0..(dimensions-1)).each { column ->
				print board[row][column] ? 'X' : '.'
			}
			print System.getProperty('line.separator')
		}
		println ''
	}

	def start() {
		(1..generations).each { generation ->
			printBoard(generation, this.board, this.dimensions)
			this.board = createNextGeneration(this.board, this.dimensions)
		}
	}

}

// Blinker
def game = new GameOfLife()
game.start()

// Glider
game = new GameOfLife(10, 10)
game.board = game.createGliderBoard()
game.start()


if(s.equals("Hello World"))
{
    foo();
}
else if(s.equals("Bye World"))
    bar();//{}'s optional for one-liners
else
{
    deusEx();
}


import Data.Array.Unboxed

type Grid = UArray (Int,Int) Bool
 -- The grid is indexed by (y, x).

life :: Int -> Int -> Grid -> Grid
{- Returns the given Grid advanced by one generation. -}
life w h old =
    listArray b (map f (range b))
  where b@((y1,x1),(y2,x2)) = bounds old
        f (y, x) = ( c && (n == 2 || n == 3) ) || ( not c && n == 3 )
          where c = get x y
                n = count [get (x + x') (y + y') |
                    x' <- [-1, 0, 1], y' <- [-1, 0, 1],
                    not (x' == 0 && y' == 0)]

        get x y | x < x1 || x > x2 = False
                | y < y1 || y > y2 = False
                | otherwise       = old ! (y, x)

count :: [Bool] -> Int
count = length . filter id


global limit

procedure main(args)
    n := args[1] | 50        # default is a 50x50 grid
    limit := args[2] | &null #  optional limit to number of generations
    write("Enter the starting pattern, end with EOF")
    grid := getInitialGrid(n)
    play(grid)
end

# This procedure reads in the initial pattern, inserting it
#   into an nXn grid of cells.  The nXn grid also gets a
#   new border of empty cells, which just makes the test simpler
#   for determining what do with a cell on each generation.
# It would be better to let the user move the cursor and click
#   on cells to create/delete living cells, but this version
#   assumes a simple ASCII terminal.
procedure getInitialGrid(n)
    static notBlank, allStars
    initial {
        notBlank := ~' '
        allStars := repl("*",*notBlank)
        }

    g := []                # store as an array of strings

    put(g,repl(" ",n))
    while r := read() do {                        # read in rows of grid
        r := left(r,n)                            #   force each to length n
        put(g," "||map(r,notBlank,allStars)||" ") #   and making any life a '*'
        }
    while *g ~= (n+2) do
        put(g,repl(" ",n))

    return g
end

# Simple-minded procedure to 'play' Life from a starting grid.
procedure play(grid)
    while not allDone(grid) do {
        display(grid)
        grid := onePlay(grid)
        }
end

# Display the grid
procedure display(g)
    write(repl("-",*g[1]))
    every write(!g)
    write(repl("-",*g[1]))
end

# Compute one generation of Life from the current one.
procedure onePlay(g)
    ng := []
    every put(ng, !g)        # new generation starts as copy of old
    every ng[r := 2 to *g-1][c := 2 to *g-1] := case sum(g,r,c) of {
                            3:       "*"     # cell lives (or is born)
                            2:       g[r][c] # cell unchanged
                            default: " "     # cell dead
                            }
    return ng
end

# Return the number of living cells surrounding the current cell.
procedure sum(g,r,c)
    cnt := 0
    every (i := -1 to 1, j := -1 to 1) do
        if ((i ~= 0) | (j ~= 0)) & (g[r+i][c+j] == "*") then cnt +:= 1
    return cnt
end

# Check to see if all the cells have died or we've exceeded the
#   number of allowed generations.
procedure allDone(g)
   static count
   initial count := 0
   return ((count +:= 1) > \limit) | (trim(!g) == " ")
end


if( s == "Hello World" ) {
    foo();
} else if( s == "Bye World" ) {
    bar();
} else {
    deusEx();
}


0  :  ok
4  :  warning
8  :  error
12 :  severe error
16 :  terminal error


print(Template("""{% for lang in ["Jinja", "Python", "Swift", "Nim"] %}
                        {{ loop.index }}) {{ lang }}{% if loop.last %}.{% else %},{% endif %}
                  {%- endfor %}""").render())


function test(x, y)
    if x < y
        println("x is less than y")
    elseif x > y
        println("x is greater than y")
    else
        println("x is equal to y")
    end
end

julia> test(1, 2)
x is less than y

julia> test(2, 1)
x is greater than y

julia> test(1, 1)
x is equal to y


if 1;
  $result = "Execute";

if 0;
  $result = "Ignored";

if 1; {
  $result = "Block";
  $result = "Execute";
}

if 0; {
  $result = "Block";
  $result = "Ignored";
}

if 1 == 1;
  $result = "Execute";

if 1 < 2;
  $result = "Execute";

if 1 <= 1;
  $result = "Execute";

if 2 > 1;
  $result = "Execute";

if 1 >= 1;
  $result = "Execute";

if 1 != 2;
  $result = "Execute";

$a = 1;
if $a == 1;
  $result = "Execute";

if $a == kabap.version;
  $result = "Execute";

if 1 == "1";
  $result = "Execute";

if 1 + 1 == 2;
  $result = "Execute";

if 1;
  if 1; {
    if 1;
      if 1; {
        $result = "Execute";
      }
  }


?A>[The letter is larger than a|The letter is smaller than a]


@caversion 1;

dimensions 2;

//using Moore neighborhood
neighborhood moore;

//available states
state DEAD, ALIVE;

/*
 if current state is ALIVE and the
 neighborhood does not contain 2 or
 3 ALIVE states the cell changes to
 DEAD
*/
rule{ALIVE}:!ALIVE{2,3}->DEAD;

/*
 if current state is DEAD and there
 are exactly 3 ALIVE cells in the
 neighborhood the cell changes to
 ALIVE
*/
rule{DEAD}:ALIVE{3}->ALIVE;


// version 1.0.6

fun main(args: Array<String>) {
    // conventional 'if/else if/else' statement
    if (args.isEmpty()) println("No arguments were supplied")
    else if (args.size == 1) println("One argument was supplied")
    else println("${args.size} arguments were supplied")

    print("Enter an integer : ")
    val i = readLine()!!.toInt()

    // 'when' statement (similar to 'switch' in C family languages)
    when (i) {
        0, 1      -> println("0 or 1")
        in 2 .. 9 -> println("Between 2 and 9")
        else      -> println("Out of range")
    }

    // both of these can be used as expressions as well as statements
    val s = if (i < 0) "negative" else "non-negative"
    println("$i is $s")
    val t = when {
        i > 0  -> "positive"
        i == 0 -> "zero"
        else   -> "negative"
    }
    println("$i is $t")
}


public class GameOfLife{
	public static void main(String[] args){
		String[] dish= {
				"_#_",
				"_#_",
				"_#_",};
		int gens= 3;
		for(int i= 0;i < gens;i++){
			System.out.println("Generation " + i + ":");
			print(dish);
			dish= life(dish);
		}
	}

	public static String[] life(String[] dish){
		String[] newGen= new String[dish.length];
		for(int row= 0;row < dish.length;row++){//each row
			newGen[row]= "";
			for(int i= 0;i < dish[row].length();i++){//each char in the row
				String above= "";//neighbors above
				String same= "";//neighbors in the same row
				String below= "";//neighbors below
				if(i == 0){//all the way on the left
					//no one above if on the top row
					//otherwise grab the neighbors from above
					above= (row == 0) ? null : dish[row - 1].substring(i,
									i + 2);
					same= dish[row].substring(i + 1, i + 2);
					//no one below if on the bottom row
					//otherwise grab the neighbors from below
					below= (row == dish.length - 1) ? null : dish[row + 1]
									.substring(i, i + 2);
				}else if(i == dish[row].length() - 1){//right
					//no one above if on the top row
					//otherwise grab the neighbors from above
					above= (row == 0) ? null : dish[row - 1].substring(i - 1,
									i + 1);
					same= dish[row].substring(i - 1, i);
					//no one below if on the bottom row
					//otherwise grab the neighbors from below
					below= (row == dish.length - 1) ? null : dish[row + 1]
									.substring(i - 1, i + 1);
				}else{//anywhere else
					//no one above if on the top row
					//otherwise grab the neighbors from above
					above= (row == 0) ? null : dish[row - 1].substring(i - 1,
									i + 2);
					same= dish[row].substring(i - 1, i)
									+ dish[row].substring(i + 1, i + 2);
					//no one below if on the bottom row
					//otherwise grab the neighbors from below
					below= (row == dish.length - 1) ? null : dish[row + 1]
									.substring(i - 1, i + 2);
				}
				int neighbors= getNeighbors(above, same, below);
				if(neighbors < 2 || neighbors > 3){
					newGen[row]+= "_";//<2 or >3 neighbors -> die
				}else if(neighbors == 3){
					newGen[row]+= "#";//3 neighbors -> spawn/live
				}else{
					newGen[row]+= dish[row].charAt(i);//2 neighbors -> stay
				}
			}
		}
		return newGen;
	}

	public static int getNeighbors(String above, String same, String below){
		int ans= 0;
		if(above != null){//no one above
			for(char x: above.toCharArray()){//each neighbor from above
				if(x == '#') ans++;//count it if someone is here
			}
		}
		for(char x: same.toCharArray()){//two on either side
			if(x == '#') ans++;//count it if someone is here
		}
		if(below != null){//no one below
			for(char x: below.toCharArray()){//each neighbor below
				if(x == '#') ans++;//count it if someone is here
			}
		}
		return ans;
	}

	public static void print(String[] dish){
		for(String s: dish){
			System.out.println(s);
		}
	}
}


{if true then yes else no}
-> yes

{def switch
 {lambda {:n}
  {if {< :n 0}
   then :n is negative
   else {if {> :n 0}
   then :n is positive
   else :n is zero}}}}

{switch -12}
-> -12 is negative
{switch 12}
-> 12 is positive
{switch 0}
-> 0 is zero


function GameOfLife () {

	this.init = function (turns,width,height) {
		this.board = new Array(height);
		for (var x = 0; x < height; x++) {
			this.board[x] = new Array(width);
			for (var y = 0; y < width; y++) {
				this.board[x][y] = Math.round(Math.random());
			}
		}
		this.turns = turns;
	}

	this.nextGen = function() {
		this.boardNext = new Array(this.board.length);
		for (var i = 0; i < this.board.length; i++) {
			this.boardNext[i] = new Array(this.board[i].length);
		}
		for (var x = 0; x < this.board.length; x++) {
			for (var y = 0; y < this.board[x].length; y++) {
				var n = 0;
				for (var dx = -1; dx <= 1; dx++) {
					for (var dy = -1; dy <= 1; dy++) {
						if ( dx == 0 && dy == 0){}
						else if (typeof this.board[x+dx] !== 'undefined'
								&& typeof this.board[x+dx][y+dy] !== 'undefined'
								&& this.board[x+dx][y+dy]) {
							n++;
						}
					}
				}
				var c = this.board[x][y];
				switch (n) {
					case 0:
					case 1:
						c = 0;
						break;
					case 2:
						break;
					case 3:
						c = 1;
						break;
					default:
						c = 0;
				}
				this.boardNext[x][y] = c;
			}
		}
		this.board = this.boardNext.slice();
	}

	this.print = function() {
		for (var x = 0; x < this.board.length; x++) {
			var l = "";
			for (var y = 0; y < this.board[x].length; y++) {
				if (this.board[x][y])
					l += "X";
				else
					l += " ";
			}
			print(l);
		}
	}

	this.start = function() {
		for (var t = 0; t < this.turns; t++) {
			print("---\nTurn "+(t+1));
			this.print();
			this.nextGen()
		}
	}

}

var game = new GameOfLife();

print("---\n3x3 Blinker over three turns.");
game.init(3);
game.board = [
	[0,0,0],
	[1,1,1],
	[0,0,0]];
game.start();

print("---\n10x6 Glider over five turns.");
game.init(5);
game.board = [
	[0,0,0,0,0,0,0,0,0,0],
	[0,0,1,0,0,0,0,0,0,0],
	[0,0,0,1,0,0,0,0,0,0],
	[0,1,1,1,0,0,0,0,0,0],
	[0,0,0,0,0,0,0,0,0,0],
	[0,0,0,0,0,0,0,0,0,0]];
game.start();

print("---\nRandom 5x10");
game.init(5,5,10);
game.start();


# Notes on the implementation:

# 1. For efficiency, the implementation requires that the world
#    has boundaries, as illustrated in the examples.
# 2. For speed, the simulation uses the exploded string.
# 3. The ASCII values of the "alive" and "empty" symbols are
#    hardcoded: "." => 46; " " => 32
# 4. To adjust the refresh rate, adjust the input to "spin".

def lines: split("\n")|length;

def cols: split("\n")[0]|length + 1;  # allow for the newline

# Is there a "." (46) at [x,y] relative to position i,
# assuming the width is w?
# Input is an array; result is 0 or 1 so we can easily count the total.
def isAlive(x; y; i; w): if .[i+ w*y + x] == 46 then 1 else 0 end;

def neighborhood(i;w):
  isAlive(-1; -1; i; w) + isAlive(0; -1; i; w) + isAlive(1; -1; i; w) +
  isAlive(-1;  0; i; w)                        + isAlive(1;  0; i; w) +
  isAlive(-1;  1; i; w) + isAlive(0;  1; i; w) + isAlive(1;  1; i; w) ;

# The basic rules:
def evolve(cell; sum) :
  if   cell == 46 then if sum == 2 or sum == 3 then 46 else 32 end
  elif cell == 32 then if sum == 3 then 46 else 32 end
  else cell
  end ;

# [world, lines, cols] | next(w) => [world, lines, cols]
def next:
  .[0] as $world | .[1] as $lines | .[2] as $w
  | reduce range(0; $world|length) as $i
    ($world;
      .[$i] as $c
      | if $c == 32 or $c == 46 then
           # updates are "simultaneous" i.e. relative to $world, not "."
           ($world | neighborhood($i; $w)) as $sum
           | evolve($c; $sum) as $next
           | if $c == $next then . else .[$i] = $next end
        else .
        end )
  | [., $lines, $w] ;


# using the fact that submatch() returns an empty array for no match ...
# ... and that a decoupling assignment returns a Boolean...

if val .alias, .name = submatch($re/^(\.idregex;)\\s*;\\s*(\.idregex;)/, .row) {
    # success (2 or more values in array returned from submatch function)
    # use .alias and .name here
    ...
} else if .x > 0 {
    val .y = 100
    ...
} else {
    val .y = 70
    ...
}


BR or BRnzp    ; unconditional branch, i.e.
               ; branch if (result < 0 || result == 0 || result > 0)
               ; ^ this is always true

BRn            ; branch if (result < 0)
BRz            ; branch if (result == 0)
BRp            ; branch if (result > 0)

               ; or any combination of these condition codes, e.g.
BRnz           ; branch if (result <= 0)


/* Conway's game of life, in Jsish */
function GameOfLife () {
    this.title = "Conway's Game of Life";
    this.cls = "\u001B[H\u001B[2J";

    this.init = function (turns, width, height) {
        this.board = new Array(height);
        for (var x = 0; x < height; x++) {
            this.board[x] = new Array(width);
            for (var y = 0; y < width; y++) {
                this.board[x][y] = Math.round(Math.random());
            }
        }
        this.turns = turns;
    };

    this.nextGen = function() {
        this.boardNext = new Array(this.board.length);
        for (var i = 0; i < this.board.length; i++) {
            this.boardNext[i] = new Array(this.board[i].length);
        }
        for (var x = 0; x < this.board.length; x++) {
            for (var y = 0; y < this.board[x].length; y++) {
                var n = 0;
                for (var dx = -1; dx <= 1; dx++) {
                    for (var dy = -1; dy <= 1; dy++) {
                        if ( dx == 0 && dy == 0){}
                        else if (typeof this.board[x+dx] !== 'undefined'
                                && typeof this.board[x+dx][y+dy] !== 'undefined'
                                && this.board[x+dx][y+dy]) {
                            n++;
                        }
                    }
                }
                var c = this.board[x][y];
                switch (n) {
                    case 0:
                    case 1:
                        c = 0;
                        break;
                    case 2:
                        break;
                    case 3:
                        c = 1;
                        break;
                    default:
                        c = 0;
                }
                this.boardNext[x][y] = c;
            }
        }
        this.board = this.boardNext.slice(0);
    };

    this.print = function() {
        for (var x = 0; x < this.board.length; x++) {
            var l = "";
            for (var y = 0; y < this.board[x].length; y++) {
                if (this.board[x][y])
                    l += "X";
                else
                    l += " ";
            }
            puts(l);
        }
    };

    this.start = function() {
        for (var t = 0; t < this.turns; t++) {
            sleep(500);
            printf(this.cls);
            puts(this.title + "\n---\nTurn "+(t+1));
            this.print();
            this.nextGen();
        }
    };

}

var game = new GameOfLife();
if (Interp.conf('unitTest')) {
    game.init(3,3,3);
    game.title="---\n3x3 Blinker over three turns.";
    game.board = [
        [0,0,0],
        [1,1,1],
        [0,0,0]];
    game.cls="";
    game.start();
} else {
    game.init(3,3,3);
    game.title="---\n3x3 Blinker over three turns.";
    game.board = [
        [0,0,0],
        [1,1,1],
        [0,0,0]];
    game.start();

    game.init(5,10,6);
    game.title="---\n10x6 Glider over five turns.";
    game.board = [
        [0,0,0,0,0,0,0,0,0,0],
        [0,0,1,0,0,0,0,0,0,0],
        [0,0,0,1,0,0,0,0,0,0],
        [0,1,1,1,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0,0,0]];
    game.start();

    var steps = (console.args[0]) ? parseInt(console.args[0]) || 1  : 50;
    game.init(steps, 32,16);
    game.title="---\nRandom 32x16, " + steps + " step" + ((steps === 1) ? "" : "s");
    game.start();
}

/*
=!EXPECTSTART!=
---
3x3 Blinker over three turns.
---
Turn 1

XXX

---
3x3 Blinker over three turns.
---
Turn 2
 X
 X
 X
---
3x3 Blinker over three turns.
---
Turn 3

XXX

=!EXPECTEND!=
*/


if {$a > 10} {print "code evaluated on true"}
if {$a > 10} {print "again"} {print "code evaluated on false"}


+ n : INTEGER;

n := 3;

(n = 2).if {
  IO.put_string "n is 2\n";
}.elseif {n = 3} then {
  IO.put_string "n is 3\n";
}.elseif {n = 4} then {
  IO.put_string "n is 4\n";
} else {
  IO.put_string "n is none of the above\n";
};


julia> Pkg.add("CellularAutomata")
INFO: Installing CellularAutomata v0.1.2
INFO: Package database updated

julia> using CellularAutomata

julia> gameOfLife{T<:Int}(n::T, m::T, gen::T) = CA2d([3], [2,3], int(randbool(n, m)), gen)
gameOfLife (generic function with 1 method)

julia> gameOfLife(15, 30, 5)
30x15x5 Cellular Automaton


int a = 3;

// if-then-else
if (a == 2) {
    puts ("a is 2");
} else if (a == 3) {
    puts ("a is 3");
} else {
    puts("a is 4");
}

// unless
unless (a == 2) { // equivalent to if (a != 2)
    puts ("a is 2");  // It will print this line
} else if (a == 3) {
    puts ("a is 3");
} else {
    puts("a is 4");
}

// switch
switch (a) {
    case 2:
        puts ("a is 2");
        break;
    case 3:
        puts ("a is 3");
        break;
    case 4:
        puts ("a is 4");
        break;
    default:
        puts("is neither");
}


// version 1.2.0

import java.util.Random

val rand = Random(0) // using a seed to produce same output on each run

enum class Pattern { BLINKER, GLIDER, RANDOM }

class Field(val w: Int, val h: Int) {
    val s = List(h) { BooleanArray(w) }

    operator fun set(x: Int, y: Int, b: Boolean) {
        s[y][x] = b
    }

    fun next(x: Int, y: Int): Boolean {
        var on = 0
        for (i in -1..1) {
            for (j in -1..1) {
                if (state(x + i, y + j) && !(j == 0 && i == 0)) on++
            }
        }
        return on == 3 || (on == 2 && state(x, y))
    }

    fun state(x: Int, y: Int): Boolean {
        if ((x !in 0 until w) || (y !in 0 until h)) return false
        return s[y][x]
    }
}

class Life(val pattern: Pattern) {
    val w: Int
    val h: Int
    var a: Field
    var b: Field

    init {
        when (pattern) {
            Pattern.BLINKER -> {
                w = 3
                h = 3
                a = Field(w, h)
                b = Field(w, h)
                a[0, 1] = true
                a[1, 1] = true
                a[2, 1] = true
            }

            Pattern.GLIDER -> {
                w = 4
                h = 4
                a = Field(w, h)
                b = Field(w, h)
                a[1, 0] = true
                a[2, 1] = true
                for (i in 0..2) a[i, 2] = true
            }

            Pattern.RANDOM -> {
                w = 80
                h = 15
                a = Field(w, h)
                b = Field(w, h)
                for (i in 0 until w * h / 2) {
                    a[rand.nextInt(w), rand.nextInt(h)] = true
                }
            }
        }
    }

    fun step() {
        for (y in 0 until h) {
            for (x in 0 until w) {
                b[x, y] = a.next(x, y)
            }
        }
        val t = a
        a = b
        b = t
    }

    override fun toString(): String {
        val sb = StringBuilder()
        for (y in 0 until h) {
            for (x in 0 until w) {
                val c = if (a.state(x, y)) '#' else '.'
                sb.append(c)
            }
            sb.append('\n')
        }
        return sb.toString()
    }
}

fun main(args: Array<String>) {
    val lives = listOf(
        Triple(Life(Pattern.BLINKER), 3, "BLINKER"),
        Triple(Life(Pattern.GLIDER), 4, "GLIDER"),
        Triple(Life(Pattern.RANDOM), 100, "RANDOM")
    )
    for ((game, gens, title) in lives) {
        println("$title:\n")
        repeat(gens + 1) {
            println("Generation: $it\n$game")
            Thread.sleep(30)
            game.step()
        }
        println()
    }
}


if :x < 0 [make "x 0 - :x]

ifelse emptyp :list [print [empty]] [print :list]


SI A ET B ALORS
    AFFICHER [4X, 'A ET B = .VRAI.',/]
SINON
    AFFICHER [4X, 'A ET B = .FAUX.',/]
FIN SI
SI A ET QUE B ALORS
    AFFICHER [4X, 'A ET QUE B = .VRAI.',/]
SINON
    AFFICHER [4X, 'A ET QUE B = .FAUX.',/]
FIN SI


local function T2D(w,h) local t={} for y=1,h do t[y]={} for x=1,w do t[y][x]=0 end end return t end

local Life = {
  new = function(self,w,h)
    return setmetatable({ w=w, h=h, gen=1, curr=T2D(w,h), next=T2D(w,h)}, {__index=self})
  end,
  set = function(self, coords)
    for i = 1, #coords, 2 do
      self.curr[coords[i+1]][coords[i]] = 1
    end
  end,
  evolve = function(self)
    local curr, next = self.curr, self.next
    local ym1, y, yp1 = self.h-1, self.h, 1
    for i = 1, self.h do
      local xm1, x, xp1 = self.w-1, self.w, 1
      for j = 1, self.w do
        local sum = curr[ym1][xm1] + curr[ym1][x] + curr[ym1][xp1] +
                    curr[y][xm1] + curr[y][xp1] +
                    curr[yp1][xm1] + curr[yp1][x] + curr[yp1][xp1]
        next[y][x] = ((sum==2) and curr[y][x]) or ((sum==3) and 1) or 0
        xm1, x, xp1 = x, xp1, xp1+1
      end
      ym1, y, yp1 = y, yp1, yp1+1
    end
    self.curr, self.next, self.gen = self.next, self.curr, self.gen+1
  end,
  render = function(self)
    print("Generation "..self.gen..":")
    for y = 1, self.h do
      for x = 1, self.w do
        io.write(self.curr[y][x]==0 and "□ " or "■ ")
      end
      print()
    end
  end
}


t : " true"  ,t
f : " false" ,t
true  if t
false ifnot f
true  ifelse t f


--if-then-elseif-then-else
if a then
  b()
elseif c then
  d()
else
  e()
end

for var = start, _end, step do --note: end is a reserved word
  something()
end

for var, var2, etc in iteratorfunction do
  something()
end

while somethingistrue() do
  something()
end

repeat
  something()
until somethingistrue()

cases = {
key1 = dothis,
key2 = dothat,
key3 = dotheother
}

cases[key]() --equivalent to dothis(), dothat(), or dotheother() respectively


#!/bin/ksh
#	# Version AJM 93u+ 2012-08-01

# Conway's Game of Life

#	# Variables:
#
integer RAND_MAX=32767
LIFE="�[07m  �[m"
NULL="  "
typeset -a char=( "$NULL" "$LIFE" )

#	# Input x y or default to 30x30, positive integers only
#
integer h=${1:-30} ; h=$(( h<=0 ? 30 : h ))		# Height (y)
integer w=${2:-30} ; w=$(( w<=0 ? 30 : w ))		# Width  (x)

#	# Functions:
#

#	# Function _display(map, h, w)
#
function _display {
	typeset _dmap ; nameref _dmap="$1"
	typeset _h _w ; integer _h=$2 _w=$3

	typeset _x _y ; integer _x _y

	printf %s "�[H"
	for (( _y=0; _y<_h; _y++ )); do
		for (( _x=0; _x<_w; _x++ )); do
			printf %s "${char[_dmap[_y][_x]]}"
		done
		printf "%s\n"
	done
}

#	# Function _evolve(h, w)
#
_evolve() {
	typeset _h _w ; integer _h=$1 _w=$2

	typeset _x _y _n _y1 _x1 ; integer _x _y _n _y1 _x1
	typeset _new _newdef ; typeset -a _new

	for (( _y=0; _y<_h; _y++ )); do
		for (( _x=0; _x<_w; _x++ )); do
			_n=0
			for (( _y1=_y-1; _y1<=_y+1; _y1++ )); do
				for (( _x1=_x-1; _x1<=_x+1; _x1++ )); do
					(( _map[$(( (_y1 + _h) % _h ))][$(( (_x1 + _w) % _w ))] )) && (( _n++ ))
				done
			done
			(( _map[_y][_x] )) && (( _n-- ))
			_new[_y][_x]=$(( (_n==3) || (_n==2 && _map[_y][_x]) ))
		done
	done

	for (( _y=0; _y<_h; _y++ )); do
		for (( _x=0; _x<_w; _x++ )); do
			_map[_y][_x]=${_new[_y][_x]}
		done
	done
}

#	# Function _game(h, w)
#
function _game {
	typeset _h ; integer _h=$1
	typeset _w ; integer _w=$2

	typeset _x _y ; integer _x _y
	typeset -a _map

	for (( _y=0 ; _y<_h ; _y++ )); do
		for (( _x=0 ; _x<_h ; _x++ )); do
			_map[_x][_y]=$(( RANDOM < RAND_MAX / 10 ? 1 : 0 ))	# seed map
		done
	done

	while : ; do
		_display _map ${_h} ${_w}
		_evolve ${_h} ${_w}
		sleep 0.2
	done
}

 ######
# main #
 ######

 _game ${h} ${w}


if char == "<" then Prepend "<" acc else acc


Module CheckIt {
      Read a
      If a>1 then {
            Print "Top"
      } else.if a>=-4 then {
            Print "Middle"
      } else {
            Print "Bottom"
      }
}
CheckIt 100
CheckIt 0
CheckIt -100

Module CheckIt {
      Read a
      \\ using end if without blocks
      If a>1 then
            Print "Top"
      else.if a>=-4 then
            Print "Middle"
      else
            Print "Bottom"
      End If
}
CheckIt 100
CheckIt 0
CheckIt -100

Module CheckIt {
      Read a
      \\ without use of END IF in one line
      If a>1 then Print "Top" else.if a>=-4 then Print "Middle" else Print "Bottom"
}
CheckIt 100
CheckIt 0
CheckIt -100


Module Life {
	Font "courier new"
	Form 40, 18
	Cls 3,0
	Double
	Report 2,  "Game of Life"
	Normal
	Cls 5, 2
	Const Mx=20, My=10
	Dim A(0 to Mx+1, 0 to My+1)=0
	Flush
REM	Data (2,2),(2,3),(3,3),(4,3),(5,4),(,3,4),(5,3),(6,2),(8,5),(5,8)
	Data (5,3)
	Data (5,4)
	Data (5,5)
	generation=1
	While not empty
		(A, B)=Array
		A(A,B)=1
	End While
	Display()
	Do
		k$=Key$
		If k$=chr$(13) Then exit
		A()[email protected]()
		refresh 500
		Display()
	Until A()#Sum()=0
	K$=Key$
	Cls, 0
	End
	Function GetNext()
		Local B()
		B()=A()  ' copy array
		Local B=B()  ' get a pointer
		B*=0  ' make all element zero
		Local i, j, tot
		For j=1 to My
			For i=1 to Mx
				tot=-A(i,j)
				For k=j-1 to j+1
					For m=i-1 to i+1
						tot+=A(m, k)
					Next
				Next
				If A(i,j)=1 Then
					If tot=2 or tot=3 Then B(i,j)=1
				Else.if tot=3 Then
					B(i,j)=1
				End If
			Next
		Next
		=B()
	End Function
	Sub Display()
		Cursor 0,2
		move !    ' move graphic to character cursor
		Fill scale.x, scale.y-pos.Y, 1, 5
		Print "Generation:";Generation
		Generation++
		Local i, j
		For j=1 to My
			Print @(width div 2-Mx div 2);
			For i=1 to Mx
				Print If$(A(I,J)=1->"■", "□");
			Next
			Print
		Next
		Print
		Report 2, "Press enter to exit or any other key for Next generation"
	End Sub

}
Life


# make -f do.mk C=mycond if
C=0

if:
   [email protected]expr $(C) >/dev/null && make -f do.mk true; exit 0
   [email protected]expr $(C) >/dev/null || make -f do.mk false; exit 0

true:
   @echo "was true."

false:
   @echo "was false."


if x > 0 then
   res := x;
else
   res := -x;
end if;


{ {extern "manool.org.18/std/0.3/all"} in
: let { N = 40; M = 80 } in
: let { G = 99 } in
: let
  { Display =
    { proc { B } as
    : for { I = Range[N]$ } do
    : do Out.WriteLine[] after
    : for { J = Range[M]$ } do
      Out.Write[{if B[I; J] <> 0 then "*" else " "}]
    }
  }
  in
: var { B = {array N of: array M of 0} } in
  -- initialization
  B[19; 41] = 1
  B[20; 40] = 1
  B[21; 40] = 1
  B[22; 40] = 1
  B[22; 41] = 1
  B[22; 42] = 1
  B[22; 43] = 1
  B[19; 44] = 1
  -- end of initialization
  Out.WriteLine["Before:"]; Display[B]
  { var { NextB = B } in
  : repeat G do
  : do {assign B = NextB; NextB = B} after
  : for { I = Range[N]$ } do
  : var { Up = (I - 1).Mod[N]; Down = (I + 1).Mod[N] } in
  : for { J = Range[M]$ } do
  : var { Left = (J - 1).Mod[M]; Right = (J + 1).Mod[M] } in
  : var
    { Count =
      B[Up  ; Left ] +
      B[Up  ; J    ] +
      B[Up  ; Right] +
      B[I   ; Right] +
      B[Down; Right] +
      B[Down; J    ] +
      B[Down; Left ] +
      B[I   ; Left ]
    }
    in
    NextB[I; J] =
    { if Count == 2 then B[I; J] else
    : if Count == 3 then 1 else
      0
    }
  }
  Out.WriteLine["After " G " generations:"]; Display[B]
}


if x == 1
    disp 'x==1';
elseif x > 1
    disp 'x>1';
else
    disp 'x<1';
end


if test1 then (...) elseif test2 then (...) else (...);


if x == 1 then
(
     print "one"
)
else if x == 2 then
(
    print "two"
)
else
(
    print "Neither one or two"
)


INT x;
x:=0;
IF x = 1 THEN
  ! Do something
ELSE
  ! Do something else
ENDIF;


<COND (<==? .X 1> <PRINC "one">)
      (<==? .X 2> <PRINC "two">)
      (T <PRINC "something else">)>


if conditionA:
  % do something
elseif conditionB:
  % do something
% more elseif, if needed...
else:
  % do this
fi;


(true) ("I'm true") ("I'm false") if  ; If first quotation evaluates to true,
                                      ; evaluate second quotation.
                                      ; Otherwise, evaluate the third.

(true) ("I'm true") when              ; If without the false quotation.
(true) ("I'm false") unless           ; If without the true quotation.

2 (                                   ; For each quotation inside the case
   ((3 >) ("Greater than 3" puts!))   ; quotation, evaluate the second
   ((3 <) ("Smaller than 3" puts!))   ; quotation if the first quotation
   ((true) ("Exactly 3" puts!))       ; evaluates to true. Otherwise, move
) case                                ; on to the next one.


// Conway's Game of Life
clear
rows = 64; rowRange = range(0, rows-1)
cols = 96; colRange = range(0, cols-1)
// prepare two tile displays, in display layers 4 and 5
img = Image.create(2, 1); img.setPixel 1, 0, color.white
grids = []
for dispIdx in [4,5]
	display(dispIdx).mode = displayMode.tile
	td = display(dispIdx)
	td.cellSize = 10  // size of cells on screen
	td.extent = [cols, rows]
	td.overlap = -1   // adds a small gap between cells
	td.tileSet = img; td.tileSetTileSize = 1
	td.clear 0
	grids.push td
end for

// initialize to a random state
for x in colRange
	for y in rowRange
		td.setCell x, y, rnd > 0.5
	end for
end for

curIdx = 5
// main loop
while true
	yield
	td = grids[curIdx-4]
	newIdx = 4 + (curIdx == 4)
	newTd = grids[newIdx-4]
	for x in colRange
		for y in rowRange
			// get sum of neighboring states
			sum = 0
			for i in [x-1, x, x+1]
				if i < 0 or i >= cols then continue
				for j in [y-1, y, y+1]
					if j < 0 or j >= rows then continue
					if i==x and j==y then continue
					sum = sum + td.cell(i,j)
				end for
			end for
			// Now, update the cell based on current state
			// and neighboring sum.
			if td.cell(x,y) then
				newTd.setCell x, y, (sum == 2 or sum == 3)
			else
				newTd.setCell x, y, sum == 3
			end if
		end for
	end for
	display(newIdx).mode = displayMode.tile
	display(curIdx).mode = displayMode.off
	curIdx = newIdx
end while


x = 42
if x < 10 then
    print "small"
else if x < 20 then
    print "small-ish"
else if x > 100 then
    print "large"
else
    print "just right"
end if


import os, strutils, random

randomize()
var w, h: int
if paramCount() >= 2:
  w = parseInt(paramStr(1))
  h = parseInt(paramStr(2))
if w <= 0: w = 30
if h <= 0: h = 30

# Initialize
var univ, utmp = newSeq[seq[bool]](h)
for y in 0..<h:
  univ[y].newSeq w
  utmp[y].newSeq w
  for x in 0 ..< w:
    if rand(9) < 1:
      univ[y][x] = true

while true:
  # Show
  stdout.write "\e[H"
  for y in 0..<h:
    for x in 0..<w:
      stdout.write if univ[y][x]: "\e[07m  \e[m" else: "  "
    stdout.write "\e[E"
  stdout.flushFile

  # Evolve
  for y in 0..<h:
    for x in 0..<w:
      var n = 0
      for y1 in y-1..y+1:
        for x1 in x-1..x+1:
          if univ[(y1+h) mod h][(x1 + w) mod w]:
            inc n

      if univ[y][x]: dec n
      utmp[y][x] = n == 3 or (n == 2 and univ[y][x])
  swap(univ,utmp)

  sleep 200


IF i = 1 THEN
  InOut.WriteString('One')
ELSIF i = 2 THEN
  InOut.WriteString('Two')
ELSIF i = 3 THEN
  InOut.WriteString('Three')
ELSE
  InOut.WriteString('Other')
END;


IF Foo = TRUE THEN
  Bar();
ELSE
  Baz();
END;


let get g x y =
  try g.(x).(y)
  with _ -> 0

let neighbourhood g x y =
  (get g (x-1) (y-1)) +
  (get g (x-1) (y  )) +
  (get g (x-1) (y+1)) +
  (get g (x  ) (y-1)) +
  (get g (x  ) (y+1)) +
  (get g (x+1) (y-1)) +
  (get g (x+1) (y  )) +
  (get g (x+1) (y+1))

let next_cell g x y =
  let n = neighbourhood g x y in
  match g.(x).(y), n with
  | 1, 0 | 1, 1                      -> 0  (* lonely *)
  | 1, 4 | 1, 5 | 1, 6 | 1, 7 | 1, 8 -> 0  (* overcrowded *)
  | 1, 2 | 1, 3                      -> 1  (* lives *)
  | 0, 3                             -> 1  (* get birth *)
  | _ (* 0, (0|1|2|4|5|6|7|8) *)     -> 0  (* barren *)

let copy g = Array.map Array.copy g

let next g =
  let width = Array.length g
  and height = Array.length g.(0)
  and new_g = copy g in
  for x = 0 to pred width do
    for y = 0 to pred height do
      new_g.(x).(y) <- (next_cell g x y)
    done
  done;
  (new_g)

let print g =
  let width = Array.length g
  and height = Array.length g.(0) in
  for x = 0 to pred width do
    for y = 0 to pred height do
      if g.(x).(y) = 0
      then print_char '.'
      else print_char 'o'
    done;
    print_newline()
  done


che cosè var?    # switch var
   minore di 0:  # case var < 0
     ...
   maggiore di 0: # case var > 0
     ...
   o tarapia tapioco: # else (none of the previous cases)
     ...
e velocità di esecuzione


if(s == "Hello World")
{
    foo();
}
else if(s == "Bye World")
    bar();
else
{
    baz();
}


clear all
x=55;                 % Size of the Lattice (same as LAWE)

z(1:1:x^2)=0;         % Initialise the binary lattice
z_prime=z;            % prepare the z prime

idx=7*x+2;             % Origin
z(idx+4)=1;            % Populate the binary lattice with the Gosper Glider
z(idx+x+4)=1;
z(idx+1+4)=1;
z(idx+x+1+4)=1;

z(idx+14)=1;
z(idx+14+x)=1;
z(idx+14+x+x)=1;
z(idx+15+x+x+x)=1;
z(idx+15-x)=1;
z(idx+16-x-x)=1;
z(idx+16+x+x+x+x)=1;
z(idx+17-x-x)=1;
z(idx+17+x+x+x+x)=1;

z(idx+18+x)=1;
z(idx+19-x)=1;
z(idx+19+x+x+x)=1;
z(idx+20)=1;
z(idx+20+x)=1;
z(idx+20+x+x)=1;
z(idx+21+x)=1;

z(idx+24)=1;
z(idx+25)=1;
z(idx+24-x)=1;
z(idx+25-x)=1;
z(idx+24-x-x)=1;
z(idx+25-x-x)=1;
z(idx+26-x-x-x)=1;
z(idx+26+x)=1;
z(idx+28-x-x-x)=1;
z(idx+28+x)=1;
z(idx+28-x-x-x-x)=1;
z(idx+28+x+x)=1;

z(idx+38)=1;
z(idx+38-x)=1;
z(idx+39)=1;
z(idx-x+39)=1;

for k=1:1:80;                 % Number of frames
for n=x+2:1:x^2-x-1;          % one time pass

theta=0;                      % Sum the surrounding area (top equation)
for c=n-1:1:n+1;
for m=-1:1:1;
theta=theta+z(m*x+c);
endfor
endfor

z_prime(n)= round(1/5*(z(n)*acos(sin(pi/4*(theta-z(n)-9/2)))  +  (1-z(n)) * acos(sin(pi/4*(theta-z(n) + 3)))));        % bottom equation

endfor

figure(2)
title('GOL','FontWeight','bold');
xlabel("X");
ylabel("Y");
imagesc(reshape(z,x,x)')
z=z_prime;
pause                        % each press advances the algorithm one step
endfor


if x = 0
    foo()
else if x = 1
    bar()
else if x = 2
    baz()
else
    boz()
end


#!/usr/bin/ol
(import (otus random!))

(define MAX 65536)  ; should be power of two
; size of game board (should be less than MAX)
(define WIDTH 170)
(define HEIGHT 96)

; helper function
(define (hash x y)
   (let ((x (mod (+ x WIDTH) WIDTH))
         (y (mod (+ y HEIGHT) HEIGHT)))
   (+ (* y MAX) x)))

; helper function
(define neighbors '(
   (-1 . -1) ( 0 . -1) ( 1 . -1)
   (-1 .  0)           ( 1 .  0)
   (-1 .  1) ( 0 .  1) ( 1 .  1)
))

; dead-or-alive cell test
(define (alive gen x y)
   (case (fold (lambda (f xy)
                     (+ f (get gen (hash (+ x (car xy)) (+ y (cdr xy))) 0)))
               0 neighbors)
      (2
         (get gen (hash x y) #false))
      (3
         #true)))

; ---------------
(import (lib gl2))
(gl:set-window-title "Convey's The game of Life")

(glShadeModel GL_SMOOTH)
(glClearColor 0.11 0.11 0.11 1)
(glOrtho 0 WIDTH 0 HEIGHT 0 1)

(glPointSize (/ 854 WIDTH))

; generate random field
(gl:set-userdata
   (list->ff (map (lambda (i) (let ((x (rand! WIDTH)) (y (rand! HEIGHT)))
                                 (cons (hash x y) 1))) (iota 2000))))
; main game loop
(gl:set-renderer (lambda (mouse)
(let ((generation (gl:get-userdata)))
   (glClear GL_COLOR_BUFFER_BIT)

   ; draw the cells
   (glColor3f 0.2 0.5 0.2)
   (glBegin GL_POINTS)
      (ff-fold (lambda (st key value)
         (glVertex2f (mod key MAX)
                     (div key MAX))
      ) #f generation)
   (glEnd)

   (gl:set-userdata
      ; next cells generation
      (ff-fold (lambda (st key value)
         (let ((x (mod key MAX))
               (y (div key MAX)))
            (fold (lambda (st key)
                     (let ((x (+ x (car key)))
                           (y (+ y (cdr key))))
                        (if (alive generation x y) (put st (hash x y) 1) st)))
               (if (alive generation x y) (put st (hash x y) 1) st) ; the cell
               neighbors)))
         #empty generation)))))


if (the_answer == 42) FindQuestion() else Foo();
when (stock.price < buy_order) stock.Buy();
unless (text < "") Write(text);


-- simple construct
if logicalCondition then conditionWasTrue()
                    else conditionWasFalse()

-- multi-line is ok too
if logicalCondition
then
  conditionWasTrue()
else
  conditionWasFalse()

-- using block stuctures
if logicalCondition then do
  conditionWasTrue()
  ...
  end
else do
  conditionWasFalse()
  ...
  end

-- if/else if...
if logicalCondition1 then do
  condition1WasTrue()
  ...
  end
else if logicalCondition2 then do
  condition2WasTrue()
  ...
  end
else do
  conditionsWereFalse()
  ...
  end


/* REXX ---------------------------------------------------------------
* 07.08.2014 Walter Pachl Conway's Game of life  graphical
* Input is a file containing the initial pattern.
* The compute area is extended when needed
*   (i.e., when cells are born outside the current compute area)
* When computing the pattern sequence is complete, the graphical
* output starts and continues until Cancel is pressed.
* 10.08.2014 WP fixed the output of what.txt
*--------------------------------------------------------------------*/
 Parse Arg what speed
 If what='?' Then Do
   Say 'Create a file containing the pattern to be processed'
   Say 'named somename.in (octagon.in such as this for the octagon):'
   Say '   **   '
   Say '  *  *  '
   Say ' *    * '
   Say '*      *'
   Say '*      *'
   Say ' *    * '
   Say '  *  *  '
   Say '   **   '
   Say 'Run the program by entering "rexx conlife somename [pause]"',
                                                 'on the command line.'
   Say '(pause is the amount of milliseconds between 2 pictures.',
                                                     'default is 1000)'
   Say 'A file somename.lst will be created.'
   Say 'Hereafter you will see the pattern''s development',
                                                     'in a new window.'
   Say 'Press the Cancel button to end the presentation.'
   Exit
   End
 Parse Version interpreter '_' level '('
 If interpreter<>'REXX-ooRexx' Then Do
   Say interpreter  level
   Say 'This program must be run with object Rexx.'
   Exit
   End
 If what='' Then what='octagon'
 If right(what,3)='.in' then
   what=left(what,length(what)-3)
 infile=what'.in'
 If lines(infile)=0 Then Do
   Say 'Input file' infile 'not found.'
   Say 'Enter conlife ? for help.'
   Exit
   End
 If speed='' Then
   speed=1000
 .local~myspeed=speed

 Call tl what
 --'type' what'.lst'

 .local~title=what
 array=.local~myarrayData
 d = .drawDlg~new
 if d~initCode <> 0 then do
    say 'The Draw dialog was not created correctly.  Aborting.'
    return d~initCode
 end
 d~execute("SHOWTOP")
 return 0

::requires "ooDialog.cls"

::class 'drawDlg' subclass UserDialog

::attribute interrupted unguarded

::method init
   expose walterFont

   forward class (super) continue
   -- colornames:
   --  1 dark red      7 light grey   13 red
   --  2 dark green    8 pale green   14 light green
   --  3 dark yellow   9 light blue   15 yellow
   --  4 dark blue    10 white        16 blue
   --  5 purple       11 grey         17 pink
   --  6 blue grey    12 dark grey    18 turquoise

   self~interrupted = .true

   -- Create a font to write the nice big letters and digits
   opts = .directory~new
   opts~weight = 700
   walterFont = self~createFontEx("Arial",14,opts)
   walterFont = self~createFontEx("Courier",18,opts)

   if \self~createcenter(200, 235,"Walter's Clock", , ,"System",14) then
      self~initCode = 1

::method defineDialog

   self~createPushButton(/*IDC_PB_DRAW*/100,  0,  0,240,200,"DISABLED NOTAB")  -- The drawing surface.

   self~createPushButton(IDCANCEL,160,220, 35, 12,,"&Cancel")

::method initDialog unguarded
   expose x y dc myPen change al. fid nn what array
   change = 0
   x = self~factorx
   y = self~factory
   dc = self~getButtonDC(100)
   myPen   = self~createPen(1,'solid',0)
   t    = .TimeSpan~fromMicroSeconds(500000) -- .5 seconds
   msg  = .Message~new(self,'life')
   alrm = .Alarm~new(t, msg)
   array=.local~myArrayData
   Do s=1 to array~items
     al.s=array[s]
     Parse Var al.s ' == ' al.s
     End
   nn=s-2
   --say 'nn'nn
   Call lineout fid

::method interrupt unguarded

   self~interrupted = .true

::method cancel unguarded   -- Stop the drawing program and quit.
   expose x y
   self~hide
   self~interrupted = .true
   return self~cancel:super

::method leaving unguarded  -- Best place to clean up resources
   expose dc myPen walterFont

   self~deleteObject(myPen)
   self~freeButtonDC(/*IDC_PB_DRAW*/100,dc)
   self~deleteFont(walterFont)

::method life unguarded                           /* draw individual pixels */
   expose x y dc myPen change walterFont al. nn what
   mx = trunc(20*x); my = trunc(20*y); size = 400

   curPen = self~objectToDC(dc, myPen)

   -- Select the nice big letters and digits into the device context to use to
   -- to write with:
   curFont = self~fontToDC(dc, walterFont)

   -- Create a white brush and select it into the device to paint with.
   whiteBrush = self~createBrush(10)
   curBrush   = self~objectToDC(dc, whiteBrush)

   -- Paint the drawing area surface with the white brush
   self~rectangle(dc, 1, 1, 500, 600, 'FILL')
   self~writeDirect(dc,  10, 20,'Conway''s Game of Life')
   self~writeDirect(dc,  10, 40,.local~title)
   self~writeDirect(dc,  10,460,'Walter Pachl, 8 Aug 2014')
   dx=.local~dxval
   dy=.local~dyval
   do s=1 By 1 until self~interrupted
     self~transparentText(dc)
     self~interrupted = .false
     sm=s//nn+1
     If s>1 Then Do
       ali=al.sb
       Do While ali<>''
         Parse Var ali x ',' y ali
         zxa=(x+dx)*10
         zya=(y+dy)*10
         self~draw_square(dc,zxa,zya,3,10)
         End
       End
     self~draw_square(dc, 380, 10,100,10)
     self~writeDirect(dc, 340, 20,time())
     self~writeDirect(dc, 340, 40,right(sm,2) 'of' right(nn,2))
     ali=al.sm
     Do While ali<>''
       Parse Var ali x ',' y ali
       zxa=(x+dx)*10
       zya=(y+dy)*10
       self~draw_square(dc,zxa,zya,3,5)
       End
 --    self~interrupted = .true
     sb=sm
     self~objectToDC(dc, curPen)
     self~objectToDC(dc, curBrush)
     call msSleep .local~myspeed
   --self~pause
     End

::method pause
   j = msSleep(10)

::method draw_square
  Use Arg dc, x, y, d, c
  Do zx=x-d to x+d
    Do zy=y-d to y+d
      self~drawPixel(dc, zx, zy, c)
      End
    End

::method quot
  Parse Arg x,y
  If y=0 Then Return '???'
  Else Return x/y

::routine tl
/* REXX ---------------------------------------------------------------
* 02.08.2014 Walter Pachl
* Input is a file containing the initial pattern
* The compute area is extended when needed
*   (cells are born outside the current compute area)
* The program stops when the picture shown is the same as the first
*   or equal to the previous one
*--------------------------------------------------------------------*/
Parse Arg f
If f='' Then f='bipole'
fid=f'.in'
oid=f'.txt'; 'erase' oid
oil=f'.lst'; 'erase' oil
debug=0
If debug Then Do
  dbg=f'.xxx'; 'erase' dbg
  End
ml=0
l.=''
ol.=''
Parse Value '10 10' With xb yb
xc=copies(' ',xb)
Do ri=yb+1 By 1 While lines(fid)>0
  l.ri=xc||linein(fid)
  ml=max(ml,length(strip(l.ri,'T')))
  End
ri=ri-1
ml=ml+xb
ri=ri+yb
yy=ri
a.=' '
b.=' '
m.=''
x.=''
list.=''
Parse Value 1 ml 1 yy With xmi xma ymi yma
Parse Value '-10 30 -10 30' With xmi xma ymi yma
Parse Value '999 -999  999 -999 999 -999 999 -999',
       With xmin xmax ymin ymax xlo xhi  ylo yhi
Do y=1 To yy
  z=yy-y+1
  l=l.z
  Do x=1 By 1 While l<>''
    Parse Var l c +1 l
    If c='*' Then
      a.x.z='*'
    End
  End
Call show
Do step=1 To  60
  Call store
  If step>1 & is_equal(step,1) Then Leave
  If step>1 & is_equal(step,step-1) Then Leave
  Call show_neighbors
  Do y=yma To ymi By -1
    ol=format(x,3)' '
    Do x=xmi To xma
      neighbors=neighbors(x,y)
      If a.x.y=' ' Then Do             /* dead cell                  */
        If neighbors=3 Then Do
          b.x.y='*'                    /*  gets life                 */
          mmo=xmi xma ymi yma
          xmi=min(xmi,x-1)
          xma=max(xma,x+1)
          ymi=min(ymi,y-1)
          yma=max(yma,y+1)
          mm=xmi xma ymi yma
          If mm<>mmo Then
            Call debug mmo '1->' mm
          End
        Else                           /* life cell                  */
          b.x.y=' '                    /*  remains dead              */
        End
      Else Do                          /* life cell                  */
        If neighbors=2 |,
           neighbors=3 Then Do
          b.x.y='*'  /*  remains life              */
          mmo=xmi xma ymi yma
          xmi=min(xmi,x-1)
          xma=max(xma,x+1)
          ymi=min(ymi,y-1)
          yma=max(yma,y+1)
          mm=xmi xma ymi yma
          If mm<>mmo Then
            Call debug mmo '2->' mm
          End
        Else
          b.x.y=' '  /*  dies                      */
        End
      End
    End
  /* b. is the new state and is now copied to a.                     */
  Do y=yma To ymi By -1
    Do x=xmi To xma
      a.x.y=b.x.y
      End
    End
  End
/* Output name and all states                                        */
Call lineout oid,' 'f
st=' +'                                /* top and bottom border      */
sb=' +'                                /* top and bottom border      */
Do s=1 To step
  st=st||'-'right(s,2,'-')||copies('-',xmax-xmin-2)'+'
  sb=sb||copies('-',xmax-xmin+1)'+'
  End
array=.array~new
Do y=ymin To ymax
  Do s=1 To step
    Do x=xmin To xmax
      If substr(m.s.y,x,1)='*' Then Do
        xlo=min(xlo,x)
        xhi=max(xhi,x)
        ylo=min(ylo,y)
        yhi=max(yhi,y)
        End
      End
    End
  End
Do y=ymin To ymax
  ol=''
  Do s=1 To step
    Do x=xmin To xmax
      If substr(m.s.y,x,1)='*' Then Do
        list.s=list.s (x-xlo+1)','||(y-ylo+1)
        End
      End
    array[s]=s '-' words(list.s) '==' list.s
    End
  --Call lineout oid,ol '|'
  .local~myArrayData=array
  End
height=yhi-ylo+1
width=xhi-xlo+1
.local~dxval=(48-width)%2
.local~dyval=(48-height)%2
Call o st                        /* top border                 */
xl.='|'
Do y=ymax To ymin By -1
  Do s=1 To step
    xl.y=xl.y||substr(ol.s.y,xmin,xmax-xmin+1)'|'
    End
  End
Do y=ymax To ymin By -1
  Call o ' 'xl.y
  End
Call o sb                    /* bottom border              */
Call lineout oid
Say 'frames are shown in' oid
If debug Then Do
  Say 'original area' 1 ml '/' 1 yy
  Say 'compute area ' xmi xma '/' ymi yma
  Say 'used area    ' xlo xhi '/' ylo yhi
  End
Do s=1 To step
  call lineout oil,s '==>' words(list.s) '=='  list.s
  End
Return

o: Parse Arg lili
   Call lineout oid,lili
   Return

set: Parse Arg x,y
     a.x.y='*'
     Return

neighbors: Procedure Expose a. debug
  Parse Arg x,y
  neighbors=0
  do xa=x-1 to x+1
    do ya=y-1 to y+1
      If xa<>x | ya<>y then
        If a.xa.ya='*' Then
          neighbors=neighbors+1
      End
    End
  Return neighbors

store:
/* store current state (a.) in lines m.step.*                        */
Do y=yma To ymi By -1
  ol=''
  Do x=xmi To xma
    z=a.x.y
    ol=ol||z
    End
  x.step.y=ol
  If ol<>'' then Do
    ymin=min(ymin,y)
    ymax=max(ymax,y)
    p=pos('*',ol)
    q=length(strip(ol,'T'))
    If p>0 Then
      xmin=min(xmin,p)
    xmax=max(xmax,q)
    End
  m.step.y=ol
  ol.step.y=ol
  --If pos('*',ol)>0 Then Do
  --  Say '====>' right(step,2) right(y,3) '>'ol'<'  xmin xmax
  --  Say '              'copies('1234567890',3)
  --  End
  End
Return

is_equal:
/* test ist state a.b is equal to state a.a                          */
  Parse Arg a,b
  Do y=yy To 1 By -1
    If x.b.y<>x.a.y Then
      Return 0
    End
  Return 1

show: Procedure Expose dbg a. yy ml debug
Do y=-5 To 13
  ol='>'
  Do x=-5 To 13
    ol=ol||a.x.y
    End
  Call debug ol
  End
Return

show_neighbors: Procedure Expose a. xmi xma ymi yma dbg debug
  Do y=yma To ymi By -1
    ol=format(y,3)' '
    Do x=xmi To xma
      ol=ol||neighbors(x,y)
      End
    Call debug ol
    End
  Return

debug:
  If debug Then
    Return lineout(dbg,arg(1))
  Else
    Return


(set 'x 1)
(if (= x 1) (println "is 1"))


if x == 0:
  foo()
elif x == 1:
  bar()
elif x == 2:
  baz()
else:
  boz()


declare
  Rules = [rule(c:1 n:[0 1]             new:0)  %% Lonely
           rule(c:1 n:[4 5 6 7 8]       new:0)  %% Overcrowded
           rule(c:1 n:[2 3]             new:1)  %% Lives
           rule(c:0 n:[3]               new:1)  %% It takes three to give birth!
           rule(c:0 n:[0 1 2 4 5 6 7 8] new:0)  %% Barren
          ]

  Blinker = ["..."
             "###"
             "..."]

  Toad = ["...."
          ".###"
          "###."
          "...."]

  Glider = [".#.........."
            "..#........."
            "###........."
            "............"
            "............"
            "............"
            "............"
            "............"
            "............"
            "............"
            "............"]

  Init = Blinker
  MaxGen = 2

  %% G(i) -> G(i+1)
  fun {Evolve Gi}
     fun {Get X#Y}
        Row = {CondSelect Gi Y unit}
     in
        {CondSelect Row X 0} %% cells beyond boundaries are dead (0)
     end
     fun {GetNeighbors X Y}
        {Map [X-1#Y-1  X#Y-1  X+1#Y-1
              X-1#Y           X+1#Y
              X-1#Y+1  X#Y+1  X+1#Y+1]
         Get}
     end
  in
     {Record.mapInd Gi
      fun {$ Y Row}
         {Record.mapInd Row
          fun {$ X C}
             N = {Sum {GetNeighbors X Y}}
          in
             for Rule in Rules return:Return do
                if C == Rule.c andthen {Member N Rule.n} then
                   {Return Rule.new}
                end
             end
          end}
      end}
  end

  %% For example: [".#"
  %%                "#."] -> grid(1:row(1:0 2:1) 2:row(1:1 2:0))
  fun {ReadG LinesList}
     {List.toTuple grid
      {Map LinesList
       fun {$ Line}
          {List.toTuple row
           {Map Line
            fun {$ C}
               if C == &. then 0
               elseif C == &# then 1
               end
            end}}
       end}}
  end

  %% Inverse to ReadG
  fun {ShowG G}
     {Map {Record.toList G}
      fun {$ Row}
         {Map {Record.toList Row}
          fun {$ C}
             if C == 0 then &.
             elseif C == 1 then &#
             end
          end}
      end}
  end

  %% Helpers
  fun {Sum Xs} {FoldL Xs Number.'+' 0} end
  fun lazy {Iterate F V} V|{Iterate F {F V}} end

  G0 = {ReadG Init}
  Gn = {Iterate Evolve G0}
in
  for
     Gi in Gn
     I in 0..MaxGen
  do
     {System.showInfo "\nGen. "#I}
     {ForAll {ShowG Gi} System.showInfo}
  end


a := GetValue();
if(a < 5) {
  "less than 5"->PrintLine();
}
else if(a > 5) {
  "greater than 5"->PrintLine();
}
else {
  "equal to 5"->PrintLine();
};


let condition = true

if condition then
  1 (* evaluate something *)
else
  2 (* evaluate something *)


program Gol;
// Game of life
{$IFDEF FPC}
   //save as gol.pp/gol.pas
  {$Mode delphi}
{$ELSE}
  //for Delphi save as gol.dpr
  {$Apptype Console}
{$ENDIF}
uses
  crt;

const
  colMax = 76;
  rowMax = 22;
  dr = colMax+2; // element count of one row

  cDelay = 20;  // delay in ms

(*
expand field by one row/column before and after
for easier access no special treatment of torus
*)

type
  tFldElem  = byte;//0..1
  tpFldElem = ^tFldElem;
  tRow = array[0..colMax+1] of tFldElem;
  tpRow = ^tRow;
  tBoard = array[0..rowMax+1] of tRow;
  tpBoard = ^tBoard;
  tpBoards = array[0..1] of tpBoard;

type
  tIntArr = array[0..2*dr+2] of tFldElem;
  tpIntArr = ^tIntArr;

var
  aBoard,bBoard : tBoard;
  pBoards :tpBoards;
  gblActBoard : byte;
  gblUseTorus :boolean;
  gblGenCnt   : integer;

procedure PrintGen;
const
  cChar: array[0..1] of char = (' ','#');
var
  p0 : tpIntArr;
  col,row: integer;
  s : string[colMax];
begin
  setlength(s,colmax);
  gotoxy(1,1);
  writeln(gblGenCnt:10);
  For row := 1 to rowMax do
  begin
    p0 := @pBoards[gblActBoard]^[row,0];;
    For col := 1 to colMax do
      s[col] := cChar[p0[col]];
    writeln(s);
  end;
  delay(cDelay);
end;

procedure Init0(useTorus:boolean);
begin
  gblUseTorus := useTorus;
  gblGenCnt := 0;
  fillchar(aBoard,SizeOf(aBoard),#0);
  pBoards[0] := @aBoard;
  pBoards[1] := @bBoard;
  gblActBoard := 0;

  clrscr;
end;

procedure InitRandom(useTorus:boolean);
var
  col,row : integer;
begin
  Init0(useTorus);
  For row := 1 to rowMax do
    For col := 1 to colMax do
      aBoard[row,col]:= tFldElem(random>0.9);
end;

procedure InitBlinker(useTorus:boolean);
var
  col,row : integer;
begin
  Init0(useTorus);
  For col := 1 to colMax do
  begin
    IF (col+2) mod 4 = 0 then
      begin
      For row := 1 to rowmax do
        IF row mod 4 <> 0 then
          aBoard[row,col]:= 1;
      end;
  end;
end;

procedure Torus;
var
  p0 : tpIntArr;
  row: integer;
begin
  //copy column 1-> colMax+1 and colMax-> 0
  p0 := @pBoards[gblActBoard]^[1,0];
  For row := 1 to rowMax do
    begin
    p0^[0] := p0^[colMax];
    p0^[colmax+1] := p0^[1];
    //next row
    p0 := Pointer(PtrUint(p0)+SizeOf(tRow));
    end;
  //copy row  1-> rowMax+1
  move(pBoards[gblActBoard]^[1,0],pBoards[gblActBoard]^[rowMax+1,0],sizeof(trow));
  //copy row  rowMax-> 0
  move(pBoards[gblActBoard]^[rowMax,0],pBoards[gblActBoard]^[0,0],sizeof(trow));
end;

function Survive(p: tpIntArr):tFldElem;
//p points to actual_board [row-1,col-1]
//calculates the sum of alive around [row,col] aka p^[dr+1]
//really fast using fpc 2.6.4 no element on stack
const
  cSurvives : array[boolean,0..8] of byte =
              //0,1,2,3,4,5,6,7,8     sum of alive neighbours
              ((0,0,0,1,0,0,0,0,0),   {alive =false 1->born}
               (0,0,1,1,0,0,0,0,0));  {alive =true  0->die }
var
  sum : integer;
begin
  // row above
  // sum := byte(aBoard[row-1,col-1])+byte(aBoard[row-1,col])+byte(aBoard[row-1,col+1]);
  sum :=     integer(p^[     0])+integer(p^[     1])+integer(p^[     2]);
  sum := sum+integer(p^[  dr+0])                    +integer(p^[  dr+2]);
  sum := sum+integer(p^[2*dr+0])+integer(p^[2*dr+1])+integer(p^[2*dr+2]);
  survive := cSurvives[boolean(p^[dr+1]),sum];
end;

procedure NextGen;
var
  p0,p1 : tpFldElem;
  row: NativeInt;
  col :NativeInt;
begin
  if gblUseTorus then
    Torus;
  p1 := @pBoards[1-gblActBoard]^[1,1];
  //One row above and one column before because of survive
  p0 := @pBoards[  gblActBoard]^[0,0];
  For row := rowMax-1 downto 0 do
  begin
    For col := colMax-1 downto 0 do
    begin
      p1^ := survive(tpIntArr(p0));
      inc(p0);
      inc(p1);
    end;
    // jump over the borders
    inc(p1,2);
    inc(p0,2);
  end;
  //aBoard := bBoard;
  gblActBoard :=1-gblActBoard;
  inc(gblGenCnt);
end;

begin
  InitBlinker(false);
  repeat
    PrintGen;
    NextGen;
  until keypressed;
  PrintGen;
end.


if (condition)
  % body
endif

if (condition)
  % body
else
  % otherwise body
endif

if (condition1)
  % body
elseif (condition2)
  % body 2
else
  % otherwise body
endif


aBoolean ifTrue: [ ...]
aBoolean ifFalse: [ ... ]
aObject  ifNull: [ ... ]
aObject  ifNotNull: [ ... ]
aObject  ifZero: [ ... ]


life.pl numrows numcols numiterations
life.pl 5 10 15


(if (= (* 2 2) 4) (print "if-then: equal"))
(if (= (* 2 2) 6) (print "if-then: non equal"))
; ==> if-then: equal


if arg~isa(.string) & arg~left(1) == "*" then call processArg arg


--
-- demo\rosetta\Conways_Game_of_Life.exw
-- =====================================
--
with javascript_semantics
include pGUI.e

constant title = "Conway's Game of Life"
Ihandle dlg, canvas
Ihandln hTimer = NULL
cdCanvas cddbuffer

sequence c = {},    -- cells
         cn,        -- new cells
         cl         -- last cells

procedure draw(integer what)
    integer x = floor(length(c)/2)+1,
            y = floor(length(c[1])/2)
    switch what do
        case ' ': c = sq_mul(c,0)                                   -- Clear
        case '+': c[x][y-1..y+1] = repeat(1,3)                      -- Blinker
        case 'G': {                    c[x+1,y+4],
                   c[x+2,y+2],         c[x+2,y+4],
                           c[x+3,y+3], c[x+3,y+4]} = repeat(1,5)    -- Glider
        case 'T': {c[x-1,y+1],c[x,y+1],c[x+1,y+1],
                   c[x  ,y+3],c[x,y+4],c[x  ,y+5]} = repeat(1,6)    -- Thunderbird
        case 'X': for i=0 to min(x,y)-1 do
                    {c[x-i,y+i],c[x+i,y+i],
                     c[x-i,y-i],c[x+i,y-i]} = repeat(1,4)           -- Cross
                  end for
    end switch
end procedure

atom t1 = time()+1
integer fps = 0

function redraw_cb(Ihandle /*ih*/)
    integer {width, height} = IupGetIntInt(canvas, "DRAWSIZE"),
            -- limit to 10K cells (performance target of 10fps)
            -- n here is the cell size in pixels (min of 1x1)
            n = ceil(sqrt(width*height/10000)),
            w = floor(width/n)+2, -- (see cx below)
            h = floor(height/n)+2,
            alive = 0
    -- keep w, h odd for symmetry (plus I suspect the
    --  "Cross" code above may now crash without this)
    w -= even(w)
    h -= even(h)
    if length(c)!=w
    or length(c[1])!=h then
        c = repeat(repeat(0,h),w)
        cn = deep_copy(c)
        cl = deep_copy(c)
        draw('X')
        if hTimer!=NULL then
            IupStoreAttribute(hTimer, "RUN", "YES")
        end if
    end if
    cdCanvasActivate(cddbuffer)
    --
    -- There is a "dead border" of 1 cell all around the edge of c (etc) which
    -- we never display or update. If we have got this right/an exact fit, then
    -- w*n should be exactly 2n too wide, whereas in the worst case there is an
    -- (2n-1) pixel border, which we split between left and right, ditto cy.
    --
    integer cx = n+floor((width-w*n)/2)
    for x=2 to w-1 do
        integer cy = n+floor((height-h*n)/2)
        for y=2 to h-1 do
            integer cxy = c[x,y],
                    clxy = cl[x,y],
                    cnxy = -cxy
            for i=x-1 to x+1 do
                for j=y-1 to y+1 do
                    cnxy += c[i,j]
                end for
            end for
            integer live = iff(cxy?cnxy>=2 and cnxy<=3:cnxy==3),
            colour = iff(live?iff(cxy?iff(clxy?CD_PURPLE    -- adult
                                              :CD_GREEN)    -- newborn
                                     :iff(clxy?CD_RED       -- old
                                              :CD_YELLOW))  -- shortlived
                             :CD_BLACK)
            cn[x,y] = live
            alive += live
            cdCanvasSetForeground(cddbuffer,colour)
            cdCanvasBox(cddbuffer, cx, cx+n-1, cy, cy+n-1)
            cy += n
        end for
        cx += n
    end for
    cdCanvasFlush(cddbuffer)
    if not alive then
        IupStoreAttribute(hTimer, "RUN", "NO")
        IupStoreAttribute(dlg, "TITLE", "died")
    elsif c=cn then
        IupStoreAttribute(hTimer, "RUN", "NO")
        IupStoreAttribute(dlg, "TITLE", "stable")
    else
        cl = c
        c = deep_copy(cn)
        fps += 1
        if time()>=t1 then
            IupSetStrAttribute(dlg,"TITLE","%s (%d FPS)",{title,fps})
            t1 = time()+1
            fps = 0
        end if
    end if
    return IUP_DEFAULT
end function

function map_cb(Ihandle ih)
    cdCanvas cdcanvas = cdCreateCanvas(CD_IUP, ih)
    cddbuffer = cdCreateCanvas(CD_DBUFFER, cdcanvas)
    cdCanvasSetBackground(cddbuffer, CD_WHITE)
    cdCanvasSetForeground(cddbuffer, CD_RED)
    return IUP_DEFAULT
end function

function key_cb(Ihandle /*ih*/, atom c)
    if c=K_ESC then return IUP_CLOSE end if -- (standard practice for me)
    if c=K_F5 then return IUP_DEFAULT end if -- (let browser reload work)
    if    find(c," ")   then draw(' ')  -- Clear
    elsif find(c,"+bB") then draw('+')  -- Blinker
    elsif find(c,"gG")  then draw('G')  -- Glider
    elsif find(c,"tT")  then draw('T')  -- Thunderbird
    elsif find(c,"xX")  then draw('X')  -- Cross
    end if
    IupStoreAttribute(hTimer, "RUN", "YES")
    return IUP_CONTINUE
end function

function timer_cb(Ihandle /*ih*/)
    IupUpdate(canvas)
    return IUP_IGNORE
end function

procedure main()
    IupOpen()
    canvas = IupCanvas("RASTERSIZE=390x390")
    IupSetCallbacks(canvas, {"MAP_CB", Icallback("map_cb"),
                             "ACTION", Icallback("redraw_cb")})
    dlg = IupDialog(canvas,`TITLE="%s", MINSIZE=350x55`, {title})
      -- (above MINSIZE prevents the title from getting squished)
    IupSetCallback(dlg, "KEY_CB", Icallback("key_cb"))
    IupShow(dlg)
    IupSetAttribute(canvas,"RASTERSIZE",NULL)
--  hTimer = IupTimer(Icallback("timer_cb"),40) -- 25fps (maybe)
    hTimer = IupTimer(Icallback("timer_cb"),100) -- 10fps
    if platform()!=JS then
        IupMainLoop()
        IupClose()
    end if
end procedure

main()


if a then b=c else b=d

if a=0
  b=c
elseif a<0
  b=d
else
  b=e
end if

select case a
  case 'A'
  v=21
case 'B'
  v=22
case 1 to 64
  v=a+300
case else
  v=0
end select


proc {PrintParity X}
   if {IsEven X} then
      {Show even}
   elseif {IsOdd X} then
      {Show odd}
   else
      {Show 'should not happen'}
   end
end


go =>
   Rows = 3,
   Cols = 3,
   println(blinker),
   pattern(blinker, Pattern,I,J),
   life(fill(Rows,Cols,Pattern,I,J)),
   nl.

fill(Rows, Cols, Obj) = fill(Rows, Cols, Obj,1,1).
fill(Rows, Cols, Obj,OffsetI,OffsetJ) = Grid =>
   Grid = new_array(Rows,Cols), bind_vars(Grid,0),
   foreach(I in 1..Obj.length, J in 1..Obj[1].length)
     Grid[I+OffsetI-1,J+OffsetJ-1] := Obj[I,J]
   end.

% We stop whenever a fixpoint/cycle is detected
life(S) =>
    Rows = S.length,
    Cols = S[1].length,
    println([rows=Rows, cols=Cols]),
    print_grid(S),
    Seen = new_map(), % detect fixpoint and cycle
    Count = 0,
    while (not Seen.has_key(S))
       Seen.put(S,1),
       T = new_array(Rows,Cols),
       foreach(I in 1..Rows, J in 1..Cols)
           Sum = sum([S[I+A,J+B] : A in -1..1,B in -1..1,
                                   I+A > 0, J+B > 0,
                                   I+A =< Rows, J+B =< Cols]) - S[I,J],
           C = rules(S[I,J], Sum),
           T[I,J] := C
       end,
       print_grid(T),
       S := T,
       Count := Count + 1
    end,
    printf("%d generations\n", Count).

print_grid(G) =>
  foreach(I in 1..G.length)
     foreach(J in 1..G[1].length)
        if G[I,J] == 1 then print("#") else print(".") end
     end,
     nl
  end,
  nl.

% The Rules of Life
rules(This,Sum) = 1, (This == 1, member(Sum,[2,3]); This == 0, Sum == 3) => true.
rules(_This, _Sum) = 0 => true.

%
% The patterns
%   pattern(Name, Pattern, OffsetI, OffsetJ)
% where Offset* is the recommended offsets in a grid.
%

% For the task
pattern(blinker, Pattern,I,J) ?=>
   Pattern = [[0,0,0],
              [1,1,1],
              [0,0,0]],
   I=1,J=1.


(load "@lib/simul.l")

(de life (DX DY . Init)
   (let Grid (grid DX DY)
      (for This Init
         (=: life T) )
      (loop
         (disp Grid NIL
            '((This) (if (: life) "X " "  ")) )
         (wait 1000)
         (for Col Grid
            (for This Col
               (let N  # Count neighbors
                  (cnt
                     '((Dir) (get (Dir This) 'life))
                     (quote
                        west east south north
                        ((X) (south (west X)))
                        ((X) (north (west X)))
                        ((X) (south (east X)))
                        ((X) (north (east X))) ) )
                  (=: next  # Next generation
                     (if (: life)
                        (>= 3 N 2)
                        (= N 3) ) ) ) ) )
         (for Col Grid  # Update
            (for This Col
               (=: life (: next)) ) ) ) ) )

(life 5 5  b3 c3 d3)


IF condition1 THEN
  procedure1
ELSE
  procedure3;

IF condition1 THEN
  BEGIN
    procedure1;
    procedure2
  END
ELSE
  procedure3;

IF condition1 THEN
  BEGIN
    procedure1;
    procedure2
  END
ELSE
  BEGIN
    procedure3;
    procedure4
  END;


(subscriptrange):
Conway: procedure options (main);        /* 20 November 2013 */
   /* A grid of (1:100, 1:100) is desired; the array GRID is defined as (0:101, 0:101), */
   /* to satisfy the requirement that elements off-grid are zero.                       */
   declare n fixed binary; /* grid size) */

   put ('What grid size do you want?');
   get (n);
   put skip list ('Generating a grid of size ' || trim(n) );

begin;
   declare grid (0:n+1,0:n+1) bit(1) initial ((*) '0'b);
   declare new  (0:n+1,0:n+1) bit(1);
   declare cell(3,3) defined grid(1sub-2+i, 2sub-2+j) bit (1);
   declare (i, j, k) fixed binary;

   /* Initialize some cells. */
   grid(2,2) = '1'b; grid(2,3) = '1'b; grid(2,4) = '1'b;

   /* Print the initial state. */
   put list ('Initial pattern:');
   do i = 1 to n;
      put skip;
      do j = 1 to n;
         put edit (grid(i,j)) (b(1));
      end;
   end;

   do k = 1 to 4;
      /* Do one generation of life */
      new = '0'b;
      /* For each C, the center of a 3 x 3 cell matrix. */
      do i = 1 to n;
         do j = 1 to n;
            if grid(i,j) then
               select (sum(cell)-1);
                  when (0,1)       new(i,j) = '0'b;
                  when (4,5,6,7,8) new(i,j) = '0'b;
                  when (2,3)       new(i,j) = '1'b;
               end;
            else
               select (sum(cell));
                  when (3)         new(i,j) = '1'b;
                  otherwise        new(i,j) = '0'b;
               end;
         end;
      end;
      grid = new; /* Update GRID with the new generation. */

      /* Print the generation. */
      put skip(2) list ('Generation ' || trim(k));
      do i = 1 to n;
         put skip;
         do j = 1 to n;
            put edit (grid(i,j)) (b(1));
         end;
      end;
   end;
end;
end Conway;