// Version 1.2.40

import java.awt.Color
import java.awt.Graphics
import java.awt.image.BufferedImage
import kotlin.math.abs
import java.io.File
import javax.imageio.ImageIO

class Point(var x: Int, var y: Int)

class BasicBitmapStorage(width: Int, height: Int) {
    val image = BufferedImage(width, height, BufferedImage.TYPE_3BYTE_BGR)

    fun fill(c: Color) {
        val g = image.graphics
        g.color = c
        g.fillRect(0, 0, image.width, image.height)
    }

    fun setPixel(x: Int, y: Int, c: Color) = image.setRGB(x, y, c.getRGB())

    fun getPixel(x: Int, y: Int) = Color(image.getRGB(x, y))

    fun drawLine(x0: Int, y0: Int, x1: Int, y1: Int, c: Color) {
        val dx = abs(x1 - x0)
        val dy = abs(y1 - y0)
        val sx = if (x0 < x1) 1 else -1
        val sy = if (y0 < y1) 1 else -1
        var xx = x0
        var yy = y0
        var e1 = (if (dx > dy) dx else -dy) / 2
        var e2: Int
        while (true) {
            setPixel(xx, yy, c)
            if (xx == x1 && yy == y1) break
            e2 = e1
            if (e2 > -dx) { e1 -= dy; xx += sx }
            if (e2 <  dy) { e1 += dx; yy += sy }
        }
    }

    fun cubicBezier(p1: Point, p2: Point, p3: Point, p4: Point, clr: Color, n: Int) {
        val pts = List(n + 1) { Point(0, 0) }
        for (i in 0..n) {
            val t = i.toDouble() / n
            val u = 1.0 - t
            val a = u * u * u
            val b = 3.0 * t * u * u
            val c = 3.0 * t * t * u
            val d = t * t * t
            pts[i].x = (a * p1.x + b * p2.x + c * p3.x + d * p4.x).toInt()
            pts[i].y = (a * p1.y + b * p2.y + c * p3.y + d * p4.y).toInt()
            setPixel(pts[i].x, pts[i].y, clr)
        }
        for (i in 0 until n) {
            val j = i + 1
            drawLine(pts[i].x, pts[i].y, pts[j].x, pts[j].y, clr)
        }
    }
}

fun main(args: Array<String>) {
    val width = 200
    val height = 200
    val bbs = BasicBitmapStorage(width, height)
    with (bbs) {
        fill(Color.cyan)
        val p1 = Point(0, 149)
        val p2 = Point(30, 50)
        val p3 = Point(120, 130)
        val p4 = Point(160, 30)
        cubicBezier(p1, p2, p3, p4, Color.black, 20)
        val cbFile = File("cubic_bezier.jpg")
        ImageIO.write(image, "jpg", cbFile)
    }
}


go =>
  Names = ["North", "North by east", "North-northeast", "Northeast by north",
           "Northeast", "Northeast by east", "East-northeast", "East by north",
           "East", "East by south", "East-southeast", "Southeast by east",
           "Southeast", "Southeast by south","South-southeast", "South by east",
           "South", "South by west", "South-southwest", "Southwest by south",
           "Southwest", "Southwest by west", "West-southwest", "West by south",
           "West", "West by north", "West-northwest", "Northwest by west",
           "Northwest", "Northwest by north", "North-northwest", "North by west", "North"
          ],
  foreach(I in 0..32)
     J = I mod 32,
     D = I * 11.25,
     if I mod 3 == 1 then D := D + 5.62 end,
     if I mod 3 == 2 then D := D - 5.62 end,
     printf("%2d %-20s %6.2f\n", J+1, Names[J+1], D)
  end,
  nl.


(scl 3)

(setq *Compass                      # Build lookup table
   (let H -16.875
      (mapcar
         '((Str)
            (cons
               (inc 'H 11.25)       # Heading in degrees
               (pack                # Compass point
                  (replace (chop Str)
                     "N" "north"
                     "E" "east"
                     "S" "south"
                     "W" "west"
                     "b" " by " ) ) ) )
         '("N" "NbE" "N-NE" "NEbN" "NE" "NEbE" "E-NE" "EbN"
            "E" "EbS" "E-SE" "SEbE" "SE" "SEbS" "S-SE" "SbE"
            "S" "SbW" "S-SW" "SWbS" "SW" "SWbW" "W-SW" "WbS"
            "W" "WbN" "W-NW" "NWbW" "NW" "NWbN" "N-NW" "NbW"
            "N" ) ) ) )

(de heading (Deg)
   (rank (% Deg 360.00) *Compass) )

(for I (range 0 32)
   (let H (* I 11.25)
      (case (% I 3)
         (1 (inc 'H 5.62))
         (2 (dec 'H 5.62)) )
      (tab (3 1 -18 8)
         (inc (% I 32))
         NIL
         (cdr (heading H))
         (round H 2) ) ) )


void bitwise(int a, int b)
{
    write("a and b: %d\n", a & b);
    write("a or b:  %d\n", a | b);
    write("a xor b: %d\n", a ^ b);
    write("not a:   %d\n", ~a);
    write("a << b:  0x%x\n", a << b);
    write("a >> b:  %d\n", a >> b);
    // ints in Pike do not overflow, if a particular size of the int
    // is desired then cap it with an AND operation
    write("a << b & 0xffffffff (32bit cap):  0x%x\n",
          a << b & 0xffffffff);
}

void main()
{
    bitwise(255, 30);
}


Bitmap.cubicbezier = function(self, x1, y1, x2, y2, x3, y3, x4, y4, nseg)
  nseg = nseg or 10
  local prevx, prevy, currx, curry
  for i = 0, nseg do
    local t = i / nseg
    local a, b, c, d = (1-t)^3, 3*t*(1-t)^2, 3*t^2*(1-t), t^3
    prevx, prevy = currx, curry
    currx = math.floor(a * x1 + b * x2 + c * x3 + d * x4 + 0.5)
    curry = math.floor(a * y1 + b * y2 + c * y3 + d * y4 + 0.5)
    if i > 0 then
      self:line(prevx, prevy, currx, curry)
    end
  end
end

local bitmap = Bitmap(61,21)
bitmap:clear()
bitmap:cubicbezier( 1,1, 15,41, 45,-20, 59,19 )
bitmap:render({[0x000000]='.', [0xFFFFFFFF]='X'})


Drawing a cubic bezier curve out of any SVG or CANVAS frame.
1) interpolating 4 points

The Bézier curve is defined as an array of 4 given points,
each defined as an array of 2 numbers.
The bezier function returns the point interpolating the 4 points.

{def bezier
 {def bezier.interpol
  {lambda {:a0 :a1 :a2 :a3 :t :u}
   {round
    {+ {* :a0 :u :u :u 1}
       {* :a1 :u :u :t 3}
       {* :a2 :u :t :t 3}
       {* :a3 :t :t :t 1}}}}}
 {lambda {:bz :t}
  {A.new {bezier.interpol {A.get 0 {A.get 0 :bz}}
                          {A.get 0 {A.get 1 :bz}}
                          {A.get 0 {A.get 2 :bz}}
                          {A.get 0 {A.get 3 :bz}} :t {- 1 :t}}
         {bezier.interpol {A.get 1 {A.get 0 :bz}}
                          {A.get 1 {A.get 1 :bz}}
                          {A.get 1 {A.get 2 :bz}}
                          {A.get 1 {A.get 3 :bz}} :t {- 1 :t}}} }}
-> bezier

2) plotting a dot

We don't draw in any SVG or CANVAS frame, but directly in the HTML page,
using div HTML blocks designed as colored circles.

{def dot
 {lambda {:p :r :col}
  {div {@ style="position:absolute;
                 left:  {- {A.get 0 :p} {/ :r 2}}px;
                 top:   {- {A.get 1 :p} {/ :r 2}}px;
                 width: :rpx; height: :rpx;
                 border-radius: :rpx;
                 border: 1px solid #000;
                 background: :col;"}}}}
-> dot

3) defining 4 control points

{def Q0 {A.new 150 150}} -> Q0
{def Q1 {A.new 500 300}} -> Q1
{def Q2 {A.new 100 500}} -> Q2
{def Q3 {A.new 300 500}} -> Q3

4) defining 2 curves

We use the same control points but in different orders to define two curves

{def BZ1 {A.new {Q0} {Q1} {Q2} {Q3}}}
-> BZ1
{def BZ2 {A.new {Q0} {Q2} {Q1} {Q3}}}
-> BZ2

5) drawing curves and dots

We map the bezier function on a serie of values in a range [start end step]

{S.map {lambda {:t} {dot {bezier {BZ1} :t} 5 red}}
       {S.serie -0.1 1.2 0.02}}
{S.map {lambda {:t} {dot {bezier {BZ2} :t} 5 blue}}
       {S.serie -0.1 1.2 0.02}}

{dot {Q0} 20 cyan}
{dot {Q1} 20 cyan}
{dot {Q2} 20 cyan}
{dot {Q3} 20 cyan}

The result can be seen in http://lambdaway.free.fr/lambdawalks/?view=bezier


/* PL/I can perform bit operations on binary integers. */
k = iand(i,j);
k = ior(i,j);
k = inot(i,j);
k = ieor(i,j);
k = isll(i,n); /* unsigned shifts i left  by n places. */
k = isrl(i,n); /* unsigned shifts i right by n places. */
k = lower2(i, n); /* arithmetic right shift i by n places. */
k = raise2(i, n); /* arithmetic left  shift i by n places. */

/* PL/I can also perform boolean operations on bit strings */
/* of any length: */

declare (s, t, u) bit (*);

u = s & t; /* logical and  */
u = s | t; /* logical or   */
u = ^ s;   /* logical not  */
u = s ^ t; /* exclusive or */

/* Built-in rotate functions are not available. */
/* They can be readily implemented by the user, though: */

u = substr(s, length(s), 1) || substr(s, 1, length(s)-1); /* implements rotate right. */
u = substr(s, 2) || substr(s, 1, 1);                      /* implements rotate left.  */


points= {{0, 0}, {1, 1}, {2, -1}, {3, 0}};
Graphics[{BSplineCurve[points], Green, Line[points], Red, Point[points]}]


function bezierCubic(obj,pixel_0,pixel_1,pixel_2,pixel_3,color,varargin)

    if( isempty(varargin) )
        resolution = 20;
    else
        resolution = varargin{1};
    end

    %Calculate time axis
    time = (0:1/resolution:1)';
    timeMinus = 1-time;

    %The formula for the curve is expanded for clarity, the lack of
    %loops is because its calculation has been vectorized
    curve = (timeMinus).^3*pixel_0; %First term of polynomial
    curve = curve + (3.*time.*timeMinus.^2)*pixel_1; %second term of polynomial
    curve = curve + (3.*timeMinus.*time.^2)*pixel_2; %third term of polynomial
    curve = curve + time.^3*pixel_3; %Fourth term of polynomial

    curve = round(curve); %round each of the points to the nearest integer

    %connect each of the points in the curve with a line using the
    %Bresenham Line algorithm
    for i = (1:length(curve)-1)
        obj.bresenhamLine(curve(i,:),curve(i+1,:),color);
    end

    assignin('caller',inputname(1),obj); %saves the changes to the object

end


import bitmap
import bresenham
import lenientops

proc drawCubicBezier*(
        image: Image; pt1, pt2, pt3, pt4: Point; color: Color; nseg: Positive = 20) =

  var points = newSeq[Point](nseg + 1)

  for i in 0..nseg:
    let t = i / nseg
    let u = (1 - t) * (1 - t)
    let a = (1 - t) * u
    let b = 3 * t * u
    let c = 3 * (t * t) * (1 - t)
    let d = t * t * t

    points[i] = (x: (a * pt1.x + b * pt2.x + c * pt3.x + d * pt4.x).toInt,
                 y: (a * pt1.y + b * pt2.y + c * pt3.y + d * pt4.y).toInt)

  for i in 1..points.high:
    image.drawLine(points[i - 1], points[i], color)

#———————————————————————————————————————————————————————————————————————————————————————————————————

when isMainModule:
  var img = newImage(16, 16)
  img.fill(White)
  img.drawCubicBezier((0, 15), (3, 0), (15, 2), (10, 14), Black)
  img.print


let cubic_bezier ~img ~color
        ~p1:(_x1, _y1)
        ~p2:(_x2, _y2)
        ~p3:(_x3, _y3)
        ~p4:(_x4, _y4) =
  let x1, y1, x2, y2, x3, y3, x4, y4 =
    (float _x1, float _y1,
     float _x2, float _y2,
     float _x3, float _y3,
     float _x4, float _y4)
  in
  let bz t =
    let a = (1.0 -. t) ** 3.0
    and b = 3.0 *. t *. ((1.0 -. t) ** 2.0)
    and c = 3.0 *. (t ** 2.0) *. (1.0 -. t)
    and d = t ** 3.0
    in
    let x = a *. x1 +. b *. x2 +. c *. x3 +. d *. x4
    and y = a *. y1 +. b *. y2 +. c *. y3 +. d *. y4
    in
    (int_of_float x, int_of_float y)
  in
  let rec loop _t acc =
    if _t > 20 then acc else
    begin
      let t = (float _t) /. 20.0 in
      let x, y = bz t in
      loop (succ _t) ((x,y)::acc)
    end
  in
  let pts = loop 0 [] in

  (*
  (* draw only points *)
  List.iter (fun (x, y) -> put_pixel img color x y) pts;
  *)

  (* draw segments *)
  let line = draw_line ~img ~color in
  let by_pair li f =
    ignore (List.fold_left (fun prev x -> f prev x; x) (List.hd li) (List.tl li))
  in
  by_pair pts (fun p0 p1 -> line ~p0 ~p1);
;;


compassangle(1, 'North',n, 0.00).
compassangle(2, 'North by east', nbe, 11.25).
compassangle(3, 'North-northeast', nne,22.50).
compassangle(4, 'Northeast by north', nebn,33.75).
compassangle(5, 'Northeast', ne,45.00).
compassangle(6, 'Norteast by east', nebe,56.25).
compassangle(7, 'East-northeast', ene,67.50).
compassangle(8, 'East by North', ebn,78.75).
compassangle(9, 'East', e,90.00).
compassangle(10, 'East by south', ebs, 101.25).
compassangle(11, 'East-southeast', ese,112.50).
compassangle(12, 'Southeast by east', sebe, 123.75).
compassangle(13, 'Southeast', se, 135.00).
compassangle(14, 'Southeast by south', sebs, 146.25).
compassangle(15, 'South-southeast',sse, 157.50).
compassangle(16, 'South by east', sbe, 168.75).
compassangle(17, 'South', s, 180.00).
compassangle(18, 'South by west', sbw, 191.25).
compassangle(19, 'South-southwest', ssw, 202.50).
compassangle(20, 'Southwest by south', swbs, 213.75).
compassangle(21, 'Southwest', sw, 225.00).
compassangle(22, 'Southwest by west', swbw, 236.25).
compassangle(23, 'West-southwest', wsw, 247.50).
compassangle(24, 'West by south', wbs, 258.75).
compassangle(25, 'West', w, 270.00).
compassangle(26, 'West by north', wbn, 281.25).
compassangle(27, 'West-northwest', wnw, 292.50).
compassangle(28, 'Northwest by west', nwbw, 303.75).
compassangle(29, 'Northwest', nw, 315.00).
compassangle(30, 'Northwest by north', nwbn, 326.25).
compassangle(31, 'North-northwest', nnw, 337.50).
compassangle(32, 'North by west', nbw, 348.75).
compassangle(1, 'North', n, 360.00).
compassangle(Index , Name, Heading, Angle) :- nonvar(Angle), resolveindex(Angle, Index),
                                               compassangle(Index,Name, Heading, _).

resolveindex(Angle, Index) :- N is Angle / 11.25 + 0.5, I is floor(N),Index is (I mod 32) + 1.


define bitwise(a, b);
    printf(a && b, 'a and b = %p\n');
    printf(a || b, 'a or b = %p\n');
    printf(a ||/& b, 'a xor b = %p\n');
    printf(~~ a, 'not a = %p\n');
    printf(a << b, 'left shift of a by b = %p\n');
    printf(a >> b, 'arithmetic right shift of a by b = %p\n');
enddefine;


$X -band $Y
$X -bor  $Y
$X -bxor $Y
-bnot $X


-- demo\rosetta\Bitmap_BezierCubic.exw  (runnable version)
include ppm.e   -- black, green, red, white, new_image(), write_ppm(), bresLine()  -- (covers above requirements)

function cubic_bezier(sequence img, atom x1, y1, x2, y2, x3, y3, x4, y4, integer colour, segments)
    sequence pts = repeat(0,segments*2)
    for i=0 to segments*2-1 by 2 do
        atom t = i/segments,
            t1 = 1-t,
             a = power(t1,3),
             b = 3*t*power(t1,2),
             c = 3*power(t,2)*t1,
             d = power(t,3)
        pts[i+1] = floor(a*x1+b*x2+c*x3+d*x4)
        pts[i+2] = floor(a*y1+b*y2+c*y3+d*y4)
    end for
    for i=1 to segments*2-2 by 2 do
        img = bresLine(img, pts[i], pts[i+1], pts[i+2], pts[i+3], colour)
    end for
    return img
end function

sequence img = new_image(300,200,black)
img = cubic_bezier(img, 0,100, 100,0, 200,200, 300,100, white, 40)
img = bresLine(img,0,100,100,0,green)
img = bresLine(img,100,0,200,200,green)
img = bresLine(img,200,200,300,100,green)
img[1][100] = red
img[100][1] = red
img[200][200] = red
img[300][100] = red
write_ppm("Bezier.ppm",img)


DataSection
  Data.s "N", "north", "E", "east", "W", "west", "S", "south", "b", " by "   ;abbreviations, expansions
  Data.s "N NbE N-NE NEbN NE NEbE E-NE EbN E EbS E-SE SEbE SE SEbS S-SE SbE" ;dirs
  Data.s "S SbW S-SW SWbS SW SWbW W-SW WbS W WbN W-NW NWbW NW NWbN N-NW NbW"
EndDataSection

;initialize data
NewMap dirSubst.s()
Define i, abbr.s, expansion.s
For i = 1 To 5
  Read.s abbr
  Read.s expansion
  dirSubst(abbr) = expansion
Next

Dim dirs.s(32)
Define j, s.s
For j = 0 To 1
  Read.s s.s
  For i = 0 To 15
    abbr.s = StringField(s, i + 1, " ")
    dirs(j * 16 + i) = abbr
  Next
Next

;expand abbreviated compass point and capitalize
Procedure.s abbr2compassPoint(abbr.s)
  Shared dirSubst()
  Protected i, compassPoint.s, key.s

  For i = 1 To Len(abbr)
    key.s = Mid(abbr, i, 1)
    If FindMapElement(dirSubst(), key)
      compassPoint + dirSubst(key)
    Else
      compassPoint + key
    EndIf
  Next
  ProcedureReturn UCase(Left(compassPoint, 1)) + Mid(compassPoint, 2)
EndProcedure

Procedure.s angle2compass(angle.f)
  Shared dirs()
  Static segment.f = 360.0 / 32 ;width of each compass segment
  Protected dir

  ;work out which segment contains the compass angle
  dir = Int((Mod(angle, 360) / segment) + 0.5)

  ;convert to a named direction
  ProcedureReturn abbr2compassPoint(dirs(dir))
EndProcedure

;box the compass
If OpenConsole()

  Define i, heading.f, index
  For i = 0 To 32
    heading = i * 11.25
    If i % 3 = 1
      heading + 5.62
    EndIf
    If i % 3 = 2
      heading - 5.62
    EndIf
    index = i % 32 + 1

    PrintN(RSet(Str(index), 2) + " " + LSet(angle2compass(heading), 18) + RSet(StrF(heading, 2), 7))
  Next

  Print(#CRLF$ + #CRLF$ + "Press ENTER to exit"): Input()
  CloseConsole()
EndIf


Procedure Bitwise(a, b)
  Debug  a & b      ; And
  Debug a | b       ;Or
  Debug a ! b       ; XOr
  Debug ~a          ;Not
  Debug a << b      ; shift left
  Debug a >> b      ; arithmetic shift right
  ; Logical shift right and rotates are not available
  ; You can of use inline ASM to achieve this:
  Define Temp
  ; logical shift right
  !mov edx, dword [p.v_a]
  !mov ecx, dword [p.v_b]
  !shr edx, cl
  !mov dword [p.v_Temp], edx
  Debug Temp
  ; rotate left
  !mov edx, dword [p.v_a]
  !mov ecx, dword [p.v_b]
  !rol edx, cl
  !mov dword [p.v_Temp], edx
  Debug Temp
  ; rotate right
  !mov edx, dword [p.v_a]
  !mov ecx, dword [p.v_b]
  !ror edx, cl
  !mov dword [p.v_Temp], edx
  Debug Temp
EndProcedure


def bitwise_built_ins(width, a, b):
    mask = (1 << width) - 1
    print(f"""\
    AND:     0b{a :0{width}b}
           & 0b{b :0{width}b}
           = 0b{(a & b) & mask :0{width}b}

    OR:      0b{a :0{width}b}
           | 0b{b :0{width}b}
           = 0b{(a | b) & mask :0{width}b}

    XOR:     0b{a :0{width}b}
           ^ 0b{b :0{width}b}
           = 0b{(a ^ b) & mask :0{width}b}

    NOT:   ~ 0b{a :0{width}b}
           = 0b{(~a) & mask :0{width}b}

    SHIFTS

      RIGHT:   0b{a :0{width}b} >> 1
             = 0b{(a >> 1) & mask :0{width}b}

      LEFT:    0b{a :0{width}b} << 1
             = 0b{(a << 1) & mask :0{width}b}
""")

def rotr(width, a, n):
    "Rotate a, n times to the right"
    if n < 0:
        return rotl(width, a, -n)
    elif n == 0:
        return a
    else:
        mask = (1 << width) - 1
        a, n = a & mask, n % width
        return ((a >> n)    # top moved down
                | ((a & ((1 << n) - 1))   # Bottom masked...
                   << (width - n)))  # ... then moved up

def rotl(width, a, n):
    "Rotate a, n times to the left"
    if n < 0:
        return rotr(width, a, -n)
    elif n == 0:
        return a
    else:
        mask = (1 << width) - 1
        a, n = a & mask, n % width
        return (((a << n) & mask)      # bottom shifted up and masked
                | (a >> (width - n)))  # Top moved down

def asr(width, a, n):
    "Arithmetic shift a, n times to the right. (sign preserving)."
    mask, top_bit_mask = ((1 << width) - 1), 1 << (width - 1)
    if n < 0:
        return  (a << -n) & mask
    elif n == 0:
        return a
    elif n >= width:
        return mask if a & top_bit_mask else 0
    else:
        a = a & mask
        if a & top_bit_mask:    # Sign bit set?
            signs = (1 << n) - 1
            return a >> n | (signs << width - n)
        else:
            return a >> n

def helper_funcs(width, a):
    mask, top_bit_mask = ((1 << width) - 1), 1 << (width - 1)
    aa = a | top_bit_mask  # a with top bit set
    print(f"""\
    ROTATIONS

      RIGHT:   rotr({width}, 0b{a :0{width}b}, 1)
               =       0b{rotr(width, a, 1) :0{width}b}
               rotr({width}, 0b{a :0{width}b}, 2)
               =       0b{rotr(width, a, 2) :0{width}b}
               rotr({width}, 0b{a :0{width}b}, 4)
               =       0b{rotr(width, a, 4) :0{width}b}

      LEFT:    rotl({width}, 0b{a :0{width}b}, 1)
               =       0b{rotl(width, a, 1) :0{width}b}
               rotl({width}, 0b{a :0{width}b}, 2)
               =       0b{rotl(width, a, 2) :0{width}b}
               rotl({width}, 0b{a :0{width}b}, 4)
               =       0b{rotl(width, a, 4) :0{width}b}

    SIGN-EXTENDING ARITHMETIC SHIFT RIGHT

               asr({width}, 0b{a :0{width}b}, 1)
               =      0b{asr(width, a, 1) :0{width}b}
               asr({width}, 0b{aa :0{width}b}, 1)
               =      0b{asr(width, aa, 1) :0{width}b}
               asr({width}, 0b{a :0{width}b}, 2)
               =      0b{asr(width, a, 2) :0{width}b}
               asr({width}, 0b{aa :0{width}b}, 2)
               =      0b{asr(width, aa, 2) :0{width}b}
               asr({width}, 0b{a :0{width}b}, 4)
               =      0b{asr(width, a, 4) :0{width}b}
               asr({width}, 0b{aa :0{width}b}, 4)
               =      0b{asr(width, aa, 4) :0{width}b}
""")

if __name__ == '__main__':
    bitwise_built_ins(8, 27, 125)
    helper_funcs(8, 27)


Procedure cubic_bezier(img, p1x, p1y, p2x, p2y, p3x, p3y, p4x, p4y, Color, n_seg)
  Protected i
  Protected.f t, t1, a, b, c, d
  Dim pts.POINT(n_seg)

  For i = 0 To n_seg
    t = i / n_seg
    t1 = 1.0 - t
    a = Pow(t1, 3)
    b = 3.0 * t * Pow(t1, 2)
    c = 3.0 * Pow(t, 2) * t1
    d = Pow(t, 3)
    pts(i)\x = a * p1x + b * p2x + c * p3x + d * p4x
    pts(i)\y = a * p1y + b * p2y + c * p3y + d * p4y
  Next

  StartDrawing(ImageOutput(img))
    FrontColor(Color)
    For i = 0 To n_seg - 1
      BresenhamLine(pts(i)\x, pts(i)\y, pts(i + 1)\x, pts(i + 1)\y) ;this calls the implementation of a draw_line routine
    Next
  StopDrawing()
EndProcedure

Define w, h, img
w = 200: h = 200: img = 1
CreateImage(img, w, h) ;img is internal id of the image

OpenWindow(0, 0, 0, w, h,"Bezier curve, cubic", #PB_Window_SystemMenu)
cubic_bezier(1, 160,10, 10,40, 30,160, 150,110, RGB(255, 255, 255), 20)
ImageGadget(0, 0, 0, w, h, ImageID(1))

Define event
Repeat
  event = WaitWindowEvent()
Until event = #PB_Event_CloseWindow


majors   = 'north east south west'.split()
majors   *= 2 # no need for modulo later
quarter1 = 'N,N by E,N-NE,NE by N,NE,NE by E,E-NE,E by N'.split(',')
quarter2 = [p.replace('NE','EN') for p in quarter1]

def degrees2compasspoint(d):
    d = (d % 360) + 360/64
    majorindex, minor = divmod(d, 90.)
    majorindex = int(majorindex)
    minorindex  = int( (minor*4) // 45 )
    p1, p2 = majors[majorindex: majorindex+2]
    if p1 in {'north', 'south'}:
        q = quarter1
    else:
        q = quarter2
    return q[minorindex].replace('N', p1).replace('E', p2).capitalize()

if __name__ == '__main__':
    for i in range(33):
        d = i * 11.25
        m = i % 3
        if   m == 1: d += 5.62
        elif m == 2: d -= 5.62
        n = i % 32 + 1
        print( '%2i %-18s %7.2f°' % (n, degrees2compasspoint(d), d) )


' no rotations and shift aritmetic are available in QB64
' Bitwise operator in Qbasic and QB64
'AND (operator) the bit is set when both bits are set.
'EQV (operator) the bit is set when both are set or both are not set.
'IMP (operator) the bit is set when both are set or both are unset or the second condition bit is set.
'OR (operator) the bit is set when either bit is set.
'NOT (operator) the bit is set when a bit is not set and not set when a bit is set.
'XOR (operator) the bit is set when just one of the bits are set.
Print "Qbasic and QB64 operators"
Print " Operator        1 vs 1   1 vs 0   0 vs 0"

Print "AND", 1 And 1, 1 And 0, 0 And 0
Print " OR", 1 Or 1, 1 Or 0, 0 Or 0
Print "XOR", 1 Xor 1, 1 Xor 0, 0 Xor 0
Print "EQV", 1 Eqv 1, 1 Eqv 0, 0 Eqv 0
Print "IMP", 1 Imp 1, 1 Imp 0, 0 Imp 0
Print "NOT", Not 1, Not 0, Not -1, Not -2

Print "QB64 operators"
Dim As _Byte a, b, c
a = 1: b = 1: c = 1
For i = 1 To 4
    Print a, b, c
    Print _SHL(a, i), _SHL(b, i * 2), _SHL(c, i * 3)
Next
a = 16: b = 32: c = 8
For i = 1 To 4
    Print a, b, c
    Print _SHR(a, i), _SHR(b, i * 2), _SHR(c, i * 3)
Next


  [ [] swap
    64 times
      [ 2 /mod
        number$ rot join swap ]
    drop
    echo$ cr ]                                   is echobin (   n -->   )

  [ 64 swap - rot64 ]                            is rrot64  (   n --> n )

  [ say "first integer:   " over       echobin
    say "second integer:  " dup        echobin
    say "bitwise AND:     " 2dup &     echobin
    say "bitwise OR:      " 2dup |     echobin
    say "bitwise XOR:     " 2dup ^     echobin
    say "bitwise NOT:     " over ~     echobin
    say "bitwise LSHIFT:  " 2dup <<    echobin
    say "bitwise RSHIFT:  " 2dup >>    echobin
    say "bitwise LROTATE: " 2dup rot64 echobin
    say "bitwise RROTATE: "     rrot64 echobin ] is task    ( n n -->   )

hex FFFFF hex F task


def cubicbezier(self, x0, y0, x1, y1, x2, y2, x3, y3, n=20):
    pts = []
    for i in range(n+1):
        t = i / n
        a = (1. - t)**3
        b = 3. * t * (1. - t)**2
        c = 3.0 * t**2 * (1.0 - t)
        d = t**3

        x = int(a * x0 + b * x1 + c * x2 + d * x3)
        y = int(a * y0 + b * y1 + c * y2 + d * y3)
        pts.append( (x, y) )
    for i in range(n):
        self.line(pts[i][0], pts[i][1], pts[i+1][0], pts[i+1][1])
Bitmap.cubicbezier = cubicbezier

bitmap = Bitmap(17,17)
bitmap.cubicbezier(16,1, 1,4, 3,16, 15,11)
bitmap.chardisplay()

'''
The origin, 0,0; is the lower left, with x increasing to the right,
and Y increasing upwards.

The chardisplay above produces the following output :
+-----------------+
|                 |
|                 |
|                 |
|                 |
|         @@@@    |
|      @@@    @@@ |
|     @           |
|     @           |
|     @           |
|     @           |
|      @          |
|      @          |
|       @         |
|        @        |
|         @@@@    |
|             @@@@|
|                 |
+-----------------+
'''


# x, y: the x and y coordinates of the hull points
# n: the number of points in the curve.
bezierCurve <- function(x, y, n=10)
	{
	outx <- NULL
	outy <- NULL

	i <- 1
	for (t in seq(0, 1, length.out=n))
		{
		b <- bez(x, y, t)
		outx[i] <- b$x
		outy[i] <- b$y

		i <- i+1
		}

	return (list(x=outx, y=outy))
	}

bez <- function(x, y, t)
	{
	outx <- 0
	outy <- 0
	n <- length(x)-1
	for (i in 0:n)
		{
		outx <- outx + choose(n, i)*((1-t)^(n-i))*t^i*x[i+1]
		outy <- outy + choose(n, i)*((1-t)^(n-i))*t^i*y[i+1]
		}

	return (list(x=outx, y=outy))
	}

# Example usage
x <- c(4,6,4,5,6,7)
y <- 1:6
plot(x, y, "o", pch=20)
points(bezierCurve(x,y,20), type="l", col="red")


#lang racket
(require racket/draw)

(define (draw-line dc p q)
  (match* (p q) [((list x y) (list s t)) (send dc draw-line x y s t)]))

(define (draw-lines dc ps)
  (void
   (for/fold ([p0 (first ps)]) ([p (rest ps)])
     (draw-line dc p0 p)
     p)))

(define (int t p q)
  (define ((int1 t) x0 x1) (+ (* (- 1 t) x0) (* t x1)))
  (map (int1 t) p q))

(define (bezier-points p0 p1 p2 p3)
  (for/list ([t (in-range 0.0 1.0 (/ 1.0 20))])
    (int t (int t p0 p1) (int t p2 p3))))

(define bm (make-object bitmap% 17 17))
(define dc (new bitmap-dc% [bitmap bm]))
(send dc set-smoothing 'unsmoothed)
(send dc set-pen "red" 1 'solid)
(draw-lines dc (bezier-points '(16 1) '(1 4) '(3 16) '(15 11)))
bm


class Pixel { has UInt ($.R, $.G, $.B) }
class Bitmap {
    has UInt ($.width, $.height);
    has Pixel @!data;

    method fill(Pixel $p) {
        @!data = $p.clone xx ($!width*$!height)
    }
    method pixel(
	  $i where ^$!width,
	  $j where ^$!height
	  --> Pixel
    ) is rw { @!data[$i + $j * $!width] }

    method set-pixel ($i, $j, Pixel $p) {
        self.pixel($i, $j) = $p.clone;
    }
    method get-pixel ($i, $j) returns Pixel {
	    self.pixel($i, $j);
    }

    method line(($x0 is copy, $y0 is copy), ($x1 is copy, $y1 is copy), $pix) {
        my $steep = abs($y1 - $y0) > abs($x1 - $x0);
        if $steep {
            ($x0, $y0) = ($y0, $x0);
            ($x1, $y1) = ($y1, $x1);
        }
        if $x0 > $x1 {
            ($x0, $x1) = ($x1, $x0);
            ($y0, $y1) = ($y1, $y0);
        }
        my $Δx = $x1 - $x0;
        my $Δy = abs($y1 - $y0);
        my $error = 0;
        my $Δerror = $Δy / $Δx;
        my $y-step = $y0 < $y1 ?? 1 !! -1;
        my $y = $y0;
        for $x0 .. $x1 -> $x {
            if $steep {
                self.set-pixel($y, $x, $pix);
            } else {
                self.set-pixel($x, $y, $pix);
            }
            $error += $Δerror;
            if $error >= 0.5 {
                $y += $y-step;
                $error -= 1.0;
            }
        }
    }

    method dot (($px, $py), $pix, $radius = 2) {
        for $px - $radius .. $px + $radius -> $x {
            for $py - $radius .. $py + $radius -> $y {
                self.set-pixel($x, $y, $pix) if ( $px - $x + ($py - $y) * i ).abs <= $radius;
            }
        }
    }

    method cubic ( ($x1, $y1), ($x2, $y2), ($x3, $y3), ($x4, $y4), $pix, $segments = 30 ) {
        my @line-segments = map -> $t {
            my \a = (1-$t)³;
            my \b = $t  * (1-$t)² * 3;
            my \c = $t² * (1-$t)  * 3;
            my \d = $t³;
            (a*$x1 + b*$x2 + c*$x3 + d*$x4).round(1),(a*$y1 + b*$y2 + c*$y3 + d*$y4).round(1)
        }, (0, 1/$segments, 2/$segments ... 1);
        for @line-segments.rotor(2=>-1) -> ($p1, $p2) { self.line( $p1, $p2, $pix) };
    }

    method data { @!data }
}

role PPM {
    method P6 returns Blob {
	"P6\n{self.width} {self.height}\n255\n".encode('ascii')
	~ Blob.new: flat map { .R, .G, .B }, self.data
    }
}

sub color( $r, $g, $b) { Pixel.new(R => $r, G => $g, B => $b) }

my Bitmap $b = Bitmap.new( width => 600, height => 400) but PPM;

$b.fill( color(2,2,2) );

my @points = (85,390), (5,5), (580,370), (270,10);

my %seen;
my $c = 0;
for @points.permutations -> @this {
    %seen{@this.reverse.join.Str}++;
    next if %seen{@this.join.Str};
    $b.cubic( |@this, color(255-$c,127,$c+=22) );
}

@points.map: { $b.dot( $_, color(255,0,0), 3 )}

$*OUT.write: $b.P6;


DECLARE FUNCTION compasspoint$ (h!)

DIM SHARED POINT$(32)

FOR i = 1 TO 32
    READ d$: POINT$(i) = d$
NEXT i

FOR i = 0 TO 32
    heading = i * 11.25
    IF (i MOD 3) = 1 THEN
        heading = heading + 5.62
    ELSE
        IF (i MOD 3) = 2 THEN heading = heading - 5.62
    END IF
    ind = i MOD 32 + 1
    PRINT ind, compasspoint$(heading), heading
NEXT i
END

DATA  "North             ", "North by east     ", "North-northeast   ", "Northeast by north"
DATA  "Northeast         ", "Northeast by east ", "East-northeast    ", "East by north     "
DATA  "East              ", "East by south     ", "East-southeast    ", "Southeast by east "
DATA  "Southeast         ", "Southeast by south", "South-southeast   ", "South by east     "
DATA  "South             ", "South by west     ", "South-southwest   ", "Southwest by south"
DATA  "Southwest         ", "Southwest by west ", "West-southwest    ", "West by south     "
DATA  "West              ", "West by north     ", "West-northwest    ", "Northwest by west "
DATA  "Northwest         ", "Northwest by north", "North-northwest   ", "North by west     "

FUNCTION compasspoint$ (h)
    x = h / 11.25 + 1.5
    IF (x >= 33!) THEN x = x - 32!
    compasspoint$ = POINT$(INT(x))
END FUNCTION


# Since R 3.0.0, the base package provides bitwise operators, see ?bitwAnd

a <- 35
b <- 42
bitwAnd(a, b)
bitwOr(a, b)
bitwXor(a, b)
bitwNot(a)
bitwShiftL(a, 2)
bitwShiftR(a, 2)


#lang racket
(define a 255)
(define b 5)
(list (bitwise-and a b)
      (bitwise-ior a b)
      (bitwise-xor a b)
      (bitwise-not a)
      (arithmetic-shift a b)      ; left shift
      (arithmetic-shift a (- b))) ; right shift


class Pixmap
  def draw_bezier_curve(points, colour)
    # ensure the points are increasing along the x-axis
    points = points.sort_by {|p| [p.x, p.y]}
    xmin = points[0].x
    xmax = points[-1].x
    increment = 2
    prev = points[0]
    ((xmin + increment) .. xmax).step(increment) do |x|
      t = 1.0 * (x - xmin) / (xmax - xmin)
      p = Pixel[x, bezier(t, points).round]
      draw_line(prev, p, colour)
      prev = p
    end
  end
end

# the generalized n-degree Bezier summation
def bezier(t, points)
  n = points.length - 1
  points.each_with_index.inject(0.0) do |sum, (point, i)|
    sum += n.choose(i) * (1-t)**(n - i) * t**i * point.y
  end
end

class Fixnum
  def choose(k)
    self.factorial / (k.factorial * (self - k).factorial)
  end
  def factorial
    (2 .. self).reduce(1, :*)
  end
end

bitmap = Pixmap.new(400, 400)
points = [
  Pixel[40,100], Pixel[100,350], Pixel[150,50],
  Pixel[150,150], Pixel[350,250], Pixel[250,250]
]
points.each {|p| bitmap.draw_circle(p, 3, RGBColour::RED)}
bitmap.draw_bezier_curve(points, RGBColour::BLUE)


package require Tcl 8.5
package require Tk

proc drawBezier {img colour args} {
    # ensure the points are increasing along the x-axis
    set points [lsort -real -index 0 $args]

    set xmin [x [lindex $points 0]]
    set xmax [x [lindex $points end]]
    set prev [lindex $points 0]
    set increment 2
    for {set x [expr {$xmin + $increment}]} {$x <= $xmax} {incr x $increment} {
        set t [expr {1.0 * ($x - $xmin) / ($xmax - $xmin)}]
        set this [list $x [::tcl::mathfunc::round [bezier $t $points]]]
        drawLine $img $colour $prev $this
        set prev $this
    }
}

# the generalized n-degree Bezier summation
proc bezier {t points} {
    set n [expr {[llength $points] - 1}]
    for {set i 0; set sum 0.0} {$i <= $n} {incr i} {
        set sum [expr {$sum + [C $n $i] * (1-$t)**($n - $i) * $t**$i * [y [lindex $points $i]]}]
    }
    return $sum
}

proc C {n i} {expr {[ifact $n] / ([ifact $i] * [ifact [expr {$n - $i}]])}}
proc ifact n {
    for {set i $n; set sum 1} {$i >= 2} {incr i -1} {
        set sum [expr {$sum * $i}]
    }
    return $sum
}

proc x p {lindex $p 0}
proc y p {lindex $p 1}

proc newbezier {n w} {
    set size 400
    set bezier [newImage $size $size]
    fill $bezier white
    for {set i 1} {$i <= $n} {incr i} {
        set point [list [expr {int($size*rand())}] [expr {int($size*rand())}]]
        lappend points $point
        drawCircle $bezier red $point 3
    }
    puts $points

    drawBezier $bezier blue {*}$points

    $w configure -image $bezier
}

set degree 4 ;# cubic bezier -- for quadratic, use 3
label .img
button .new -command [list newbezier $degree .img] -text New
button .exit -command exit -text Exit
pack .new .img .exit -side top


#lang racket

;;; Generate the headings and boxes
(define (i->heading/box i)
  (values (let ((heading (* i #e11.25)))
            (case (modulo i 3)
             ((1) (+ heading #e5.62))
             ((2) (- heading #e5.62))
             (else heading)))
   (add1 (modulo i 32))))
(define-values (headings-list box-list)
  (for/lists (h-lst i-lst) ((i (in-range 0 (add1 32))))
             (i->heading/box i)))

(define box-names
  (list "North" "North by east" "North-northeast"
        "Northeast by north" "Northeast" "Northeast by east"
        "East-northeast" "East by north" "East" "East by south" "East-southeast"
        "Southeast by east" "Southeast" "Southeast by south" "South-southeast"
        "South by east" "South" "South by west" "South-southwest"
        "Southwest by south" "Southwest" "Southwest by west"
        "West-southwest" "West by south" "West" "West by north" "West-northwest"
        "Northwest by west" "Northwest" "Northwest by north" "North-northwest"
        "North by west"))

(define (heading->box h)
 (let* ((n-boxes (length box-names))
        (box-width (/ 360 n-boxes)))
  (add1 (modulo (ceiling (- (/ h box-width) 1/2)) n-boxes))))

;;; displays a single row of the table, can also be used for titles
(define (display-row b a p)
  (printf "~a | ~a | ~a~%"
          (~a b #:width 2 #:align 'right)
          (~a a #:width 6 #:align 'right)
          (~a p)))

;;; display the table
(display-row "#" "Angle" "Point")
(displayln "---+--------+-------------------")
(for ((heading headings-list))
     (let* ((box-number (heading->box heading)))
       ;; by coincidence, default value of the second argument to
       ;; real->decimal-string "decimal-digits" is 2,... just what we want!
       (display-row box-number
                    (real->decimal-string heading)
                    (list-ref box-names (sub1 box-number)))))

(module+ test
 (require rackunit)
 ;;; unit test heading->box (the business end of the implementation)
 (check-= (heading->box 354.38) 1 0)
 (check-= (heading->box 5.62) 1 0)
 (check-= (heading->box 5.63) 2 0)
 (check-= (heading->box 16.87) 2 0))


constant MAXINT = uint.Range.max;
constant BITS = MAXINT.base(2).chars;

# define rotate ops for the fun of it
multi sub infix:<⥁>(Int:D \a, Int:D \b) { :2[(a +& MAXINT).polymod(2 xx BITS-1).list.rotate(b).reverse] }
multi sub infix:<⥀>(Int:D \a, Int:D \b) { :2[(a +& MAXINT).polymod(2 xx BITS-1).reverse.list.rotate(b)] }

sub int-bits (Int $a, Int $b) {
    say '';
    say_bit "$a", $a;
    say '';
    say_bit "2's complement $a", +^$a;
    say_bit "$a and $b", $a +& $b;
    say_bit "$a or $b",  $a +| $b;
    say_bit "$a xor $b", $a +^ $b;
    say_bit "$a unsigned shift right $b", ($a +& MAXINT) +> $b;
    say_bit "$a signed shift right $b", $a +> $b;
    say_bit "$a rotate right $b", $a ⥁ $b;
    say_bit "$a shift left $b", $a +< $b;
    say_bit "$a rotate left $b", $a ⥀ $b;
}

int-bits(7,2);
int-bits(-65432,31);

sub say_bit ($message, $value) {
    printf("%30s: %{'0' ~ BITS}b\n", $message, $value +& MAXINT);
}


Define cubic(p1,p2,p3,p4,segs) = Prgm
  Local i,t,u,prev,pt
  0 → pt
  For i,1,segs+1
    (i-1.0)/segs → t   © Decimal to avoid slow exact arithetic
    (1-t) → u
    pt → prev
    u^3*p1 + 3t*u^2*p2 + 3t^2*u*p3 + t^3*p4 → pt
    If i>1 Then
      PxlLine floor(prev[1,1]), floor(prev[1,2]), floor(pt[1,1]), floor(pt[1,2])
    EndIf
  EndFor
EndPrgm


import "graphics" for Canvas, ImageData, Color, Point
import "dome" for Window

class Game {
    static bmpCreate(name, w, h) { ImageData.create(name, w, h) }

    static bmpFill(name, col) {
        var image = ImageData[name]
        for (x in 0...image.width) {
            for (y in 0...image.height) image.pset(x, y, col)
        }
    }

    static bmpPset(name, x, y, col) { ImageData[name].pset(x, y, col) }

    static bmpPget(name, x, y) { ImageData[name].pget(x, y) }

    static bmpLine(name, x0, y0, x1, y1, col) {
        var dx = (x1 - x0).abs
        var dy = (y1 - y0).abs
        var sx = (x0 < x1) ? 1 : -1
        var sy = (y0 < y1) ? 1 : -1
        var err = ((dx > dy ? dx : - dy) / 2).floor
        while (true) {
            bmpPset(name, x0, y0, col)
            if (x0 == x1 && y0 == y1) break
            var e2 = err
            if (e2 > -dx) {
                err = err - dy
                x0 = x0 + sx
            }
            if (e2 < dy) {
                err = err + dx
                y0 = y0 + sy
            }
        }
    }

    static bmpCubicBezier(name, p1, p2, p3, p4, col, n) {
        var pts = List.filled(n+1, null)
        for (i in 0..n) {
            var t = i / n
            var u = 1 - t
            var a = u * u * u
            var b = 3 * t * u * u
            var c = 3 * t * t * u
            var d = t * t * t
            var px = (a * p1.x + b * p2.x + c * p3.x + d * p4.x).truncate
            var py = (a * p1.y + b * p2.y + c * p3.y + d * p4.y).truncate
            pts[i] = Point.new(px, py, col)
        }
        for (i in 0...n) {
            var j = i + 1
            bmpLine(name, pts[i].x, pts[i].y, pts[j].x, pts[j].y, col)
        }
    }

    static init() {
        Window.title = "Cubic Bézier curve"
        var size = 200
        Window.resize(size, size)
        Canvas.resize(size, size)
        var name = "cubic"
        var bmp = bmpCreate(name, size, size)
        bmpFill(name, Color.white)
        var p1 = Point.new(160,  10)
        var p2 = Point.new( 10,  40)
        var p3 = Point.new( 30, 160)
        var p4 = Point.new(150, 110)
        bmpCubicBezier(name, p1, p2, p3, p4, Color.darkblue, 20)
        bmp.draw(0, 0)
    }

    static update() {}

    static draw(alpha) {}
}


Red []

d:  charset [#"N"  #"E" #"S" #"W"]                                                ;; main directions
hm: #()                                                                           ;; hm = hashmap - key= heading, value = [box , compass point]

compass-points: [N NbE NNE NEbN NE NEbE ENE EbN E EbS ESE SEbE SE SEbS SSE
 SbE S SbW SSW SWbS SW SWbW WSW WbS W WbN WNW NWbW NW NWbN NNW NbW N ]

expand: func [cp repl][                                                         ;; expand compass point to words
  parse cp [ copy a thru d ahead 2 d insert "-" ]                               ;; insert "-" after first direction, if followed by 2 more
  foreach [src dst ] repl  [ replace/all cp to-string src to-string dst ]       ;; N -> north ...
  uppercase/part cp 1                                                           ;; convert first letter to uppercase
]

print-line: does [ print [pad/left hm/:heading/1 3   pad  hm/:heading/2 20  heading ] ]

forall compass-points [
 i: (index? compass-points) - 1                                                       ;; so i = 0..33
 heading: i * 11.25 + either 1 = rem: i % 3  [ 5.62]                                  ;; rem = remainder
                                             [ either  rem = 2 [-5.62] [0.0] ]
  hm/:heading:  reduce [ (i % 32 + 1 ) expand to-string compass-points/1 [N north b " by " S south E east W west] ]
  print-line heading
]


Red [Source: https://github.com/vazub/rosetta-red]

a: 10
b: 2

print [
	pad "a =" 10 a newline
	pad "b =" 10 b newline
	pad "a AND b:" 10 a and b newline
	pad "a OR b:" 10 a or b newline
	pad "a XOR b:" 10 a xor b newline
	pad "NOT a:" 10 complement a newline
	pad "a >>> b:" 10 a >>> b newline
	pad "a >> b:" 10 a >> b newline
	pad "a << b:" 10 a << b newline
	; there are no circular shift operators in Red
]


: bitwise ( ab- )
  cr
  over     "a = %d\n" puts
  dup      "b = %d\n" puts
  2over and "a and b = %d\n" puts
  2over or  "a or b = %d\n" puts
  2over xor "a xor b = %d\n" puts
  over not "not a = %d\n" puts
  2over <<  "a << b = %d\n" puts
  2over >>  "a >> b = %d\n" puts
  2drop ;


include c:\cxpl\codes;          \intrinsic 'code' declarations

proc Bezier(P0, P1, P2, P3);    \Draw cubic Bezier curve
real P0, P1, P2, P3;
def  Segments = 8;
int  I;
real S1, T, T2, T3, U, U2, U3, B, C, X, Y;
[Move(fix(P0(0)), fix(P0(1)));
S1:= 1./float(Segments);
T:= 0.;
for I:= 1 to Segments-1 do
        [T:= T+S1;
        T2:= T*T;
        T3:= T2*T;
        U:= 1.-T;
        U2:= U*U;
        U3:= U2*U;
        B:= 3.*T*U2;
        C:= 3.*T2*U;
        X:= U3*P0(0) + B*P1(0) + C*P2(0) + T3*P3(0);
        Y:= U3*P0(1) + B*P1(1) + C*P2(1) + T3*P3(1);
        Line(fix(X), fix(Y), $00FFFF);          \cyan line segments
        ];
 Line(fix(P3(0)), fix(P3(1)), $00FFFF);
Point(fix(P0(0)), fix(P0(1)), $FF0000);         \red control points
Point(fix(P1(0)), fix(P1(1)), $FF0000);
Point(fix(P2(0)), fix(P2(1)), $FF0000);
Point(fix(P3(0)), fix(P3(1)), $FF0000);
];

[SetVid($112);          \set 640x480x24 video graphics
Bezier([0., 0.], [30., 100.], [120., 20.], [160., 120.]);
if ChIn(1) then [];     \wait for keystroke
SetVid(3);              \restore normal text display
]


/*REXX program  "boxes the compass"   [from degree (º) headings  ───►  a 32 point set]. */
parse arg $                                      /*allow   º   headings to be specified.*/
if $=''  then $= 0 16.87 16.88 33.75 50.62 50.63 67.5 84.37 84.38 101.25 118.12 118.13   ,
                 135 151.87 151.88 168.75 185.62 185.63 202.5 219.37 219.38 236.25       ,
                 253.12 253.13 270 286.87 286.88 303.75 320.62 320.63 337.5 354.37 354.38
                                                 /* [↑]  use default, they're in degrees*/
@pts= 'n nbe n-ne nebn ne nebe e-ne ebn e ebs e-se sebe se sebs s-se sbe',
      "s sbw s-sw swbs sw swbw w-sw wbs w wbn w-nw nwbw nw nwbn n-nw nbw"

#= words(@pts) + 1                               /*#:  used for integer ÷ remainder (//)*/
dirs= 'north south east west'                    /*define cardinal compass directions.  */
                                                 /* [↓]  choose a glyph for degree  (°).*/
if 4=='f4'x  then degSym= "a1"x                  /*is this system an  EBCDIC  system?   */
             else degSym= "a7"x                  /*'f8'x  is the degree symbol: °  vs º */
                                                 /*──────────────────────────── f8 vs a7*/
say right(degSym'heading', 30)     center("compass heading", 20)
say right(     '════════', 30)     copies(              "═", 20)
pad= ' '                                         /*used to interject a blank for output.*/
         do j=1  for words($);   x= word($, j)   /*obtain one of the degree headings.   */
         say right( format(x, , 2)degSym, 30-1)          pad         boxHeading(x)
         end   /*j*/
exit                                             /*stick a fork in it,  we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
boxHeading: y= arg(1)//360; if y<0  then y=360-y /*normalize heading within unit circle.*/
            z= word(@pts, trunc(max(1, (y/11.25 +1.5) // #))) /*convert degrees─►heading*/
                                               do k=1  for words(dirs);   d= word(dirs, k)
                                               z= changestr( left(d, 1),  z,  d)
                                               end   /*k*/    /* [↑]  old, haystack, new*/
            return changestr('b',  z,  " by ")                /*expand  "b" ───► " by ".*/


 ╔═══════════════════════════════════════════════════════════════════════════════════════╗
 ║ Since REXX stores numbers  (indeed, all values)  as characters, it makes no sense to  ║
 ║ "rotate"  a value,  since there aren't any boundaries for the value.    I.E.:  there  ║
 ║ isn't any 32─bit word  "container"  or  "cell"  (for instance)  to store an integer.  ║
 ║                                                                                ║
 ║ Furthermore, since REXX numbers can be arbitrary precision,  the concept of rotating  ║
 ║ a number has no meaning.                                                              ║
 ╚═══════════════════════════════════════════════════════════════════════════════════════╝


x = 8
y = 2

see "x & y - Binary AND : " + (x & y) + nl
see "x | y - Binary OR : " + (x | y) + nl
see "x ^ y - Binary XOR : " + (x ^ y) +nl
see "~x - Binary Ones Complement : " + (~x) + nl
see "x << y - Binary Left Shift : " + (x << y) + nl
see "x >> y - Binary Right Shift : " + (x >> y) + nl


# Project : Box the compass

names = ["North", "North by east", "North-northeast",
               "Northeast by north", "Northeast", "Northeast by east", "East-northeast",
               "East by north", "East", "East by south", "East-southeast",
               "Southeast by east", "Southeast", "Southeast by south", "South-southeast",
               "South by east", "South", "South by west", "South-southwest",
               "Southwest by south", "Southwest", "Southwest by west", "West-southwest",
               "West by south", "West", "West by north", "West-northwest",
               "Northwest by west", "Northwest", "Northwest by north", "North-northwest",
               "North by west", "North"]

degrees = [0, 16.87, 16.88, 33.75, 50.62, 50.63,
                67.5, 84.37, 84.38, 101.25, 118.12, 118.13, 135, 151.87, 151.88, 168.75,
                185.62, 185.63, 202.5, 219.37, 219.38, 236.25, 253.12, 253.13, 270,
                286.87, 286.88, 303.75, 320.62, 320.63, 337.5, 354.37, 354.38]

for i = 1 to len(degrees)
     j = floor((degrees[i] + 5.625) / 11.25)
    if j > 31
       j = j - 32
    ok
    see "" + degrees[i] + " " + j + " "
    if j != 0
       see "" + names[j+1] + nl
    else
       see "" + names[len(names)] + nl
    ok
next


Headings = %w(north east south west north).each_cons(2).flat_map do |a, b|
  [a,
  "#{a} by #{b}",
  "#{a}-#{a}#{b}",
  "#{a}#{b} by #{a}",
  "#{a}#{b}",
  "#{a}#{b} by #{b}",
  "#{b}-#{a}#{b}",
  "#{b} by #{a}"]
end
Headings.prepend nil

def heading(degrees)
  i = degrees.quo(360).*(32).round.%(32).+(1)
  [i, Headings[i]]
end

# an array of angles, in degrees
angles = (0..32).map { |i| i * 11.25 + [0, 5.62, -5.62][i % 3] }

angles.each do |degrees|
  index, name = heading degrees
  printf "%2d %20s %6.2f\n", index, name.center(20), degrees
end


>> x = int(3);
>> y = int(1);
>> z = x && y; printf("0x%08x\n",z); // logical 'and'
0x00000001
>> z = x || y; printf("0x%08x\n",z); // logical 'or'
0x00000003
>> z = !x; printf("0x%08x\n",z);     // logical 'not'
0xfffffffc
>> i2 = int(2);
>> z = x * i2; printf("0x%08x\n",z);  // left-shift is multiplication by 2 where both arguments are integers
0x00000006
>> z = x / i2; printf("0x%08x\n",z);  // right-shift is division by 2 where both arguments are integers
0x00000001


input string "First value"
set "local1" to "input"
input string "Second value"
set "local2" to "input"

. ">>> is an arithmetic shift; >> is a logical shift"
[ "a AND b = ('local1' a 'local2')"
[ "a OR b = ('local1' o 'local2')"
[ "a XOR b = ('local1' x 'local2')"
[ "NOT a = (~'local1')"
[ "a << b = ('local1' << 'local2')"
[ "a >> b = ('local1' >> 'local2')"
[ "a >>> b = ('local1' >>> 'local2')"
end
. "Bitwise rotation is not natively supported"


global direct$
dim direct$(22)
direct$(1)  = "y"      'by
direct$(4)  = "ast"    'East
direct$(13) = "orth"   'North
direct$(18) = "outh"   'Soutn
direct$(22) = "est"    'West

dim point$(32)
for i =1 to 32: read point$(i) :next i

html "
"
for i = 0 to 32
    hdng = i * 11.25
    if (i mod 3) = 1 then
        hdng = hdng +5.62
    else
        if (i mod 3) = 2 then hdng = hdng -5.62
    end if
    pointer = i mod 32 + 1
    html "
";pointer;"	";compas$(hdng);"	";hdng;"
"
next i
html "
"
end

function compas$(hd)
x = hd /11.25 + 1.5
if (x >=33.0) then x =x -32.0
  p$ = point$(int(x))
  for i = 1 to len(p$)
    compas$ = compas$ + mid$(p$,i,1) + direct$(max(asc(upper$(mid$(p$,i,1)))-65,0))
  next i
end function

data "N","N b e","N-ne","Ne b n","Ne","Ne b e","E-ne","E b n","E","E b s","E-se"
data "Se b e","Se","Se b s","S-se","S b e","S","S b w","S-sw","Sw b s","Sw","Sw b w"
data "W-sw","W b s","W","W b n","W-nw","Nw b w","Nw","Nw b n","N-nw","N b w"


fn expand(cp: &str) -> String {
    let mut out = String::new();
    for c in cp.chars() {
        out.push_str(match c {
            'N' => "north",
            'E' => "east",
            'S' => "south",
            'W' => "west",
            'b' => " by ",
            _ => "-",
        });
    }
    out
}

fn main() {
    let cp = [
        "N", "NbE", "N-NE", "NEbN", "NE", "NEbE", "E-NE", "EbN",
        "E", "EbS", "E-SE", "SEbE", "SE", "SEbS", "S-SE", "SbE",
        "S", "SbW", "S-SW", "SWbS", "SW", "SWbW", "W-SW", "WbS",
        "W", "WbN", "W-NW", "NWbW", "NW", "NWbN", "N-NW", "NbW"
    ];
    println!("Index  Degrees  Compass point");
    println!("-----  -------  -------------");
    for i in 0..=32 {
        let index = i % 32;
        let heading = i as f32 * 11.25
            + match i % 3 {
                1 => 5.62,
                2 => -5.62,
                _ => 0.0,
            };
        println!(
            "{:2}     {:6.2}   {}",
            index + 1,
            heading,
            expand(cp[index])
        );
    }
}


def bitwise(a, b)
  form = "%1$7s:%2$6d  %2$016b"
  puts form % ["a", a]
  puts form % ["b", b]
  puts form % ["a and b", a & b]
  puts form % ["a or b ", a | b]
  puts form % ["a xor b", a ^ b]
  puts form % ["not a  ", ~a]
  puts form % ["a << b ", a << b]  # left shift
  puts form % ["a >> b ", a >> b]  # arithmetic right shift
end

bitwise(14,3)


object BoxingTheCompass extends App {
  val cardinal = List("north", "east", "south", "west")
  val pointDesc = List("1", "1 by 2", "1-C", "C by 1", "C", "C by 2", "2-C", "2 by 1")

  val pointDeg: Int => Double = i => {
	val fswitch: Int => Int = i => i match {case 1 => 1; case 2 => -1; case _ => 0}
	i*11.25+fswitch(i%3)*5.62
  }

  val deg2ind: Double => Int = deg => (deg*32/360+.5).toInt%32+1

  val pointName: Int => String = ind => {
    val i = ind - 1
    val str1 = cardinal(i%32/8)
    val str2 = cardinal((i%32/8+1)%4)
    val strC = if ((str1 == "north") || (str1 == "south")) str1+str2 else str2+str1
    pointDesc(i%32%8).replace("1", str1).replace("2", str2).replace("C", strC).capitalize
  }

  (0 to 32).map(i=>Triple(pointDeg(i),deg2ind(pointDeg(i)),pointName(deg2ind(pointDeg(i)))))
      .map{t=>(printf("%s\t%18s\t%s°\n",t._2,t._3,t._1))}
}


/* rotations are not available, but are easy to implement with the other bitwise operators */
data _null_;
   a=105;
   b=91;
   c=bxor(a,b);
   d=band(a,b);
   e=bor(a,b);
   f=bnot(a); /* on 32 bits */
   g=blshift(a,1);
   h=brshift(a,1);
   put _all_;
run;


def bitwise(a: Int, b: Int) {
  println("a and b: " + (a & b))
  println("a or b: " + (a | b))
  println("a xor b: " + (a ^ b))
  println("not a: " + (~a))
  println("a << b: " + (a << b)) // left shift
  println("a >> b: " + (a >> b)) // arithmetic right shift
  println("a >>> b: " + (a >>> b)) // unsigned right shift
  println("a rot b: " + Integer.rotateLeft(a, b)) // Rotate Left
  println("a rol b: " + Integer.rotateRight(a, b)) // Rotate Right
}


$ include "seed7_05.s7i";
  include "float.s7i";

const array string: names is [] ("North", "North by east", "North-northeast", "Northeast by north",
   "Northeast", "Northeast by east", "East-northeast", "East by north", "East", "East by south",
   "East-southeast", "Southeast by east", "Southeast", "Southeast by south", "South-southeast",
   "South by east", "South", "South by west", "South-southwest", "Southwest by south", "Southwest",
   "Southwest by west", "West-southwest", "West by south", "West", "West by north", "West-northwest",
   "Northwest by west", "Northwest", "Northwest by north", "North-northwest", "North by west", "North");

const proc: main is func
  local
    const array float: degrees is [] (0.0, 16.87, 16.88, 33.75, 50.62, 50.63, 67.5, 84.37, 84.38,
        101.25, 118.12, 118.13, 135.0, 151.87, 151.88, 168.75, 185.62, 185.63, 202.5, 219.37, 219.38,
        236.25, 253.12, 253.13, 270.0, 286.87, 286.88, 303.75, 320.62, 320.63, 337.5, 354.37, 354.38);
    var integer: index is 0;
    var integer: nameIndex is 0;
  begin
    for key index range degrees do
      nameIndex := round(degrees[index] * 32.0 / 360.0);
      writeln(succ(pred(index) rem 32) lpad 2 <& "  " <& names[succ(nameIndex rem 32)] rpad 22 <&
          degrees[index] digits 2 lpad 6);
    end for;
  end func;


(import (rnrs arithmetic bitwise (6)))

(define (bitwise a b)
  (display (bitwise-and a b))
  (newline)
  (display (bitwise-ior a b))
  (newline)
  (display (bitwise-xor a b))
  (newline)
  (display (bitwise-not a))
  (newline)
  (display (bitwise-arithmetic-shift-right a b))
  (newline))

(bitwise 255 5)


$ include "seed7_05.s7i";
  include "bin32.s7i";

const proc: bitwise (in integer: a, in integer: b) is func
  begin
    writeln("a:        " <& a  radix 2 lpad0 32);
    writeln("b:        " <& b  radix 2 lpad0 32);
    writeln("integer operations:");
    writeln("a << b:   " <& a << b  radix 2 lpad0 32); # left shift
    writeln("a >> b:   " <& a >> b  radix 2 lpad0 32); # arithmetic right shift
  end func;

const proc: bitwise (in bin32: a, in bin32: b) is func
  begin
    writeln("bin32 operations:");
    writeln("a and b:  " <& a & b  radix 2 lpad0 32);
    writeln("a or b:   " <& a | b  radix 2 lpad0 32);
    writeln("a xor b:  " <& a >< b  radix 2 lpad0 32);
    writeln("not a:    " <& ~a  radix 2 lpad0 32);
    writeln("a << b:   " <& a << ord(b)  radix 2 lpad0 32);  # left shift
    writeln("a >> b:   " <& a >> ord(b)  radix 2 lpad0 32);  # logical right shift
    writeln("a rotL b: " <& rotLeft(a, ord(b))  radix 2 lpad0 32);  # Rotate Left
    writeln("a rolR b: " <& rotRight(a, ord(b))  radix 2 lpad0 32); # Rotate Right
  end func;

const proc: main is func
  begin
    bitwise(65076, 6);
    bitwise(bin32(65076), bin32(6));
  end func;


proc angle2compass {angle} {
    set dirs {
	N NbE N-NE NEbN NE NEbE E-NE EbN E EbS E-SE SEbE SE SEbS S-SE SbE
	S SbW S-SW SWbS SW SWbW W-SW WbS W WbN W-NW NWbW NW NWbN N-NW NbW
    }
    set unpack {N "north" E "east" W "west" S "south" b " by "}

    # Compute the width of each compass segment
    set sep [expr {360.0 / [llength $dirs]}]

    # Work out which segment contains the compass angle
    set dir [expr {round((fmod($angle + $sep/2, 360) - $sep/2) / $sep)}]

    # Convert to a named direction, capitalized as in the wikipedia article
    return [string totitle [string map $unpack [lindex $dirs $dir]]]
}

# Box the compass, using the variable generation algorithm described
for {set i 0} {$i < 33} {incr i} {
    set heading [expr {$i * 11.25}]
    if {$i % 3 == 1} {set heading [expr {$heading + 5.62}]}
    if {$i % 3 == 2} {set heading [expr {$heading - 5.62}]}
    set index [expr {$i % 32 + 1}]

    # Pretty-print the results of converting an angle to a compass heading
    puts [format "%2i %-18s %7.2f°" $index [angle2compass $heading] $heading]
}


func bitwise(a, b) {
   say ('a and b : ',  a & b)
   say ('a or b  : ',  a | b)
   say ('a xor b : ',  a ^ b)
   say ('not a   : ',     ~a)
   say ('a << b  : ', a << b)  # left shift
   say ('a >> b  : ', a >> b)  # arithmetic right shift
}

bitwise(14,3)


BEGIN
   COMMENT TO MY KNOWLEDGE SIMULA DOES NOT SUPPORT BITWISE OPERATIONS SO WE MUST WRITE PROCEDURES FOR THE JOB ;
   INTEGER WORDSIZE;
   WORDSIZE := 32;
   BEGIN

      PROCEDURE TOBITS(N,B); INTEGER N; BOOLEAN ARRAY B;
      BEGIN
         INTEGER I,BITN;
         FOR I := WORDSIZE-1 STEP -1 UNTIL 0 DO BEGIN
            BITN := MOD(N,2); B(I) := BITN<>0; N := N // 2;
         END;
      END TOBITS;

      INTEGER PROCEDURE FROMBITS(B); BOOLEAN ARRAY B;
      BEGIN
         INTEGER I, RESULT;
         FOR I := 0 STEP 1 UNTIL WORDSIZE-1 DO
             RESULT := 2 * RESULT + (IF B(I) THEN 1 ELSE 0);
         FROMBITS := RESULT;
      END FROMBITS;

      INTEGER PROCEDURE BITOP(A,B,F);
         INTEGER A,B;
         PROCEDURE F IS BOOLEAN PROCEDURE F(A,B); BOOLEAN A,B;;
      BEGIN
         INTEGER I;
         BOOLEAN ARRAY BA(0:WORDSIZE-1);
         BOOLEAN ARRAY BB(0:WORDSIZE-1);
         TOBITS(A,BA);
         TOBITS(B,BB);
         FOR I := 0 STEP 1 UNTIL WORDSIZE-1 DO BA(I) := F(BA(I),BB(I));
         BITOP := FROMBITS(BA);
      END BITOP;

      INTEGER PROCEDURE BITUOP(A,F);
         INTEGER A;
         PROCEDURE F IS BOOLEAN PROCEDURE F(A); BOOLEAN A;;
      BEGIN
         INTEGER I;
         BOOLEAN ARRAY BA(0:WORDSIZE-1);
         TOBITS(A,BA);
         FOR I := 0 STEP 1 UNTIL WORDSIZE-1 DO BA(I) := F(BA(I));
         BITUOP := FROMBITS(BA);
      END BITUOP;

      BOOLEAN PROCEDURE OPAND(A,B); BOOLEAN A,B; OPAND := A AND B;
      INTEGER PROCEDURE BITAND(A,B); INTEGER A,B; BITAND := BITOP(A,B,OPAND);

      BOOLEAN PROCEDURE OPOR(A,B); BOOLEAN A,B; OPOR := A OR B;
      INTEGER PROCEDURE BITOR(A,B); INTEGER A,B; BITOR := BITOP(A,B,OPOR);

      BOOLEAN PROCEDURE OPXOR(A,B); BOOLEAN A,B; OPXOR := (A AND NOT B) OR (NOT A AND B);
      INTEGER PROCEDURE BITXOR(A,B); INTEGER A,B; BITXOR := BITOP(A,B,OPXOR);

      BOOLEAN PROCEDURE OPNOT(A); BOOLEAN A; OPNOT := NOT A;
      INTEGER PROCEDURE BITNOT(A); INTEGER A; BITNOT := BITUOP(A,OPNOT);

      INTEGER PROCEDURE BITSHL(A,B); INTEGER A,B;
      BEGIN
          IF B < 0 THEN A := BITSHR(A,-B)
          ELSE WHILE B > 0 DO BEGIN A := 2 * A; B := B-1; END;
          BITSHL := A;
      END BITSHL;

      INTEGER PROCEDURE BITSHR(A,B); INTEGER A,B;
      BEGIN
          IF B < 0 THEN A := BITSHL(A,-B)
          ELSE WHILE B > 0 DO BEGIN A := A // 2; B := B-1; END;
          BITSHR := A;
      END BITSHR;

      INTEGER PROCEDURE BITROTR(A,B); INTEGER A,B;
      BEGIN
         INTEGER I,J;
         BOOLEAN ARRAY BA(0:WORDSIZE-1);
         BOOLEAN ARRAY BB(0:WORDSIZE-1);
         TOBITS(A,BA);
         FOR I := 0 STEP 1 UNTIL WORDSIZE-1 DO BEGIN
            J := MOD(I + B, WORDSIZE); BB(J) := BA(I);
         END;
         BITROTR := FROMBITS(BB);
      END BITROTR;

      INTEGER PROCEDURE BITROTL(A,B); INTEGER A,B;
         BITROTL := BITROTR(A,-B);

      PROCEDURE BITWISE(A,B); INTEGER A,B;
      BEGIN
        OUTTEXT("A AND B   : "); OUTINT(BITAND(A,B),0); OUTIMAGE;
        OUTTEXT("A OR B    : "); OUTINT(BITOR (A,B),0); OUTIMAGE;
        OUTTEXT("A XOR B   : "); OUTINT(BITXOR(A,B),0); OUTIMAGE;
        OUTTEXT("NOT A     : "); OUTINT(BITNOT(A),  0); OUTIMAGE;
        OUTTEXT("A << B    : "); OUTINT(BITSHL(A,B),0); OUTIMAGE;  ! LEFT SHIFT ;
        OUTTEXT("A >> B    : "); OUTINT(BITSHR(A,B),0); OUTIMAGE;  ! ARITHMETIC RIGHT SHIFT ;
        OUTTEXT("A ROTL B  : "); OUTINT(BITROTL(A,B),0); OUTIMAGE;  ! ROTATE LEFT ;
        OUTTEXT("A ROTR B  : "); OUTINT(BITROTR(A,B),0); OUTIMAGE;  ! ROTATE RIGHT ;
      END BITWISE;

      BITWISE(14,3);
   END;
END


DIM POINT$(32)

FUNCTION compasspoint$ (h)
    LET x = h / 11.25 + 1.5
    IF (x >= 33) THEN LET x = x - 32
    LET compasspoint$ = POINT$(INT(x))
END FUNCTION

RESTORE
DATA  "North             ", "North by east     ", "North-northeast   ", "Northeast by north"
DATA  "Northeast         ", "Northeast by east ", "East-northeast    ", "East by north     "
DATA  "East              ", "East by south     ", "East-southeast    ", "Southeast by east "
DATA  "Southeast         ", "Southeast by south", "South-southeast   ", "South by east     "
DATA  "South             ", "South by west     ", "South-southwest   ", "Southwest by south"
DATA  "Southwest         ", "Southwest by west ", "West-southwest    ", "West by south     "
DATA  "West              ", "West by north     ", "West-northwest    ", "Northwest by west "
DATA  "Northwest         ", "Northwest by north", "North-northwest   ", "North by west     "

FOR i = 1 TO 32
    READ d$
    LET POINT$(i) = d$
NEXT i

FOR i = 0 TO 32
    LET heading = i * 11.25
    IF REMAINDER(i, 3) = 1 THEN
       LET heading = heading + 5.62
    ELSE
       IF REMAINDER(i, 3) = 2 THEN LET heading = heading - 5.62
    END IF
    LET ind = REMAINDER(i, 32) + 1
    PRINT ind, compasspoint$(heading), heading
NEXT i
END


[ |:a :b |

 inform: (a bitAnd: b) printString.
 inform: (a bitOr: b) printString.
 inform: (a bitXor: b) printString.
 inform: (a bitNot) printString.
 inform: (a << b) printString.
 inform: (a >> b) printString.

] applyTo: {8. 12}.


| testBitFunc |
testBitFunc := [ :a :b |
     ('%1 and %2 is %3' % { a. b. (a bitAnd: b) }) displayNl.
     ('%1 or %2 is %3' % { a. b. (a bitOr: b) }) displayNl.
     ('%1 xor %2 is %3' % { a. b. (a bitXor: b) }) displayNl.
     ('not %1 is %2' % { a. (a bitInvert) }) displayNl.
     ('%1 left shift %2 is %3' % { a. b. (a bitShift: b) }) displayNl.
     ('%1 right shift %2 is %3' % { a. b. (a bitShift: (b negated)) }) displayNl.
 ].
testBitFunc value: 16r7F value: 4 .


Push 0, 1687, 1688, 3375, 5062, 5063, 6750, 8437, 8438, 10125, 11812, 11813
Push 13500, 15187, 15188, 16875, 18562, 18563, 20250, 21937, 21938, 23625
Push 25312, 25313, 27000, 28687, 28688, 30375, 32062, 32063, 33750, 35437
Push 35438                             ' Use the stack as a DATA statement

For x = 32 To 0 Step -1                ' Now read the values, but reverse
  @(x) = Pop()                         ' Since the last value is on top
Next                                   ' of the data stack

For x = 0 To 32                        ' Here comes the payload

  j = ((@(x) * 32 / 3600) + 5) / 10    ' Scale by ten, then correct

  Print Using "_#";(j % 32) + 1;"  ";  ' Print heading
  GoSub 100 + ((j % 32) * 10)          ' Now get the compass point
  Print Using "__#.##"; @(x)           ' Finally, print the angle
                                       ' which is scaled by 100
Next

End
                                       ' All compass points
100 Print "North                 "; : Return
110 Print "North by east         "; : Return
120 Print "North-northeast       "; : Return
130 Print "Northeast by north    "; : Return
140 Print "Northeast             "; : Return
150 Print "Northeast by east     "; : Return
160 Print "East-northeast        "; : Return
170 Print "East by north         "; : Return
180 Print "East                  "; : Return
190 Print "East by south         "; : Return
200 Print "East-southeast        "; : Return
210 Print "Southeast by east     "; : Return
220 Print "Southeast             "; : Return
230 Print "Southeast by south    "; : Return
240 Print "South-southeast       "; : Return
250 Print "South by east         "; : Return
260 Print "South                 "; : Return
270 Print "South by west         "; : Return
280 Print "South-southwest       "; : Return
290 Print "Southwest by south    "; : Return
300 Print "Southwest             "; : Return
310 Print "Southwest by west     "; : Return
320 Print "West-southwest        "; : Return
330 Print "West by south         "; : Return
340 Print "West                  "; : Return
350 Print "West by north         "; : Return
360 Print "West-northwest        "; : Return
370 Print "Northwest by west     "; : Return
380 Print "Northwest             "; : Return
390 Print "Northwest by north    "; : Return
400 Print "North-northwest       "; : Return
410 Print "North by west         "; : Return
420 Print "North                 "; : Return


# List of abbreviated compass point labels
compass_points=( N NbE N-NE NEbN NE NEbE E-NE EbN
                 E EbS E-SE SEbE SE SEbS S-SE SbE
                 S SbW S-SW SWbS SW SWbW W-SW WbS
                 W WbN W-NW NWbW NW NWbN N-NW NbW )

# List of angles to test
test_angles=(  0.00  16.87  16.88  33.75  50.62  50.63  67.50
              84.37  84.38 101.25 118.12 118.13 135.00 151.87
             151.88 168.75 185.62 185.63 202.50 219.37 219.38
             236.25 253.12 253.13 270.00 286.87 286.88 303.75
             320.62 320.63 337.50 354.37 354.38 )

capitalize() {
  printf '%s%s\n' "$(tr a-z A-Z <<<"${1:0:1}")" "${1:1}"
}

# convert compass point abbreviation to full text of label
function expand_point {
  local label=$1
  set -- N north E east S south W west b " by "
  while (( $# )); do
    label=${label//$1/$2}
    shift 2
  done
  capitalize "$label"
}

# modulus function that returns 1..N instead of 0..N-1
function amod {
  echo $(( ($1 - 1) % $2 + 1 ))
}

# convert a compass angle from degrees into a box index (1..32)
function compass_point {
  # use bc or dc depending on what's on the system
  #amod $(dc <<<"$1 5.625 + 11.25 / 1 + p") 32
  amod $(bc <<<"($1 + 5.625) / 11.25 + 1") 32
}

#  Now output the table of test data
header_format="%-7s | %-18s | %s\n"
row_format="%7.2f | %-18s | %2d\n"
printf "$header_format" "Degrees" "Closest Point" "Index"
for angle in ${test_angles[@]}; do
  let index=$(compass_point $angle)
  abbr=${compass_points[index-1]}
  label="$(expand_point $abbr)"
  printf "$row_format" $angle "$label" $index
done


fun bitwise_ints (a, b) = (
  print ("a and b: " ^ IntInf.toString (IntInf.andb (IntInf.fromInt a, IntInf.fromInt b)) ^ "\n");
  print ("a or b: "  ^ IntInf.toString (IntInf.orb  (IntInf.fromInt a, IntInf.fromInt b)) ^ "\n");
  print ("a xor b: " ^ IntInf.toString (IntInf.xorb (IntInf.fromInt a, IntInf.fromInt b)) ^ "\n");
  print ("not a: "   ^ IntInf.toString (IntInf.notb (IntInf.fromInt a                  )) ^ "\n");
  print ("a lsl b: " ^ IntInf.toString (IntInf.<<   (IntInf.fromInt a, Word.fromInt b  )) ^ "\n");  (* left shift *)
  print ("a asr b: " ^ IntInf.toString (IntInf.~>>  (IntInf.fromInt a, Word.fromInt b  )) ^ "\n")   (* arithmetic right shift *)
)


func bitwise(a: Int, b: Int) {
  // All bitwise operations (including shifts)
  // require both operands to be the same type
  println("a AND b: \(a & b)")
  println("a OR b: \(a | b)")
  println("a XOR b: \(a ^ b)")
  println("NOT a: \(~a)")
  println("a << b: \(a << b)") // left shift
  // for right shifts, if the operands are unsigned, Swift performs
  // a logical shift; if signed, an arithmetic shift.
  println("a >> b: \(a >> b)") // arithmetic right shift
  println("a lsr b: \(Int(bitPattern: UInt(bitPattern: a) >> UInt(bitPattern: b)))") // logical right shift
}

bitwise(-15,3)


Public Sub box_the_compass()
    Dim compass_point As Integer
    Dim compass_points_all As New Collection
    Dim test_points_all As New Collection
    Dim compass_points(8) As Variant
    Dim test_points(3) As Variant
    compass_points(1) = [{ "North",        "North by east",        "North-northeast",      "Northeast by north"}]
    compass_points(2) = [{ "Northeast",    "Northeast by east",    "East-northeast",       "East by north"}]
    compass_points(3) = [{ "East",         "East by south",        "East-southeast",       "Southeast by east"}]
    compass_points(4) = [{ "Southeast",    "Southeast by south",   "South-southeast",      "South by east"}]
    compass_points(5) = [{ "South",        "South by west",        "South-southwest",      "Southwest by south"}]
    compass_points(6) = [{ "Southwest",    "Southwest by west",    "West-southwest",       "West by south"}]
    compass_points(7) = [{ "West",         "West by north",        "West-northwest",       "Northwest by west"}]
    compass_points(8) = [{ "Northwest",    "Northwest by north",   "North-northwest",      "North by west"}]
    test_points(1) = [{ 0.0,  16.87,  16.88,  33.75,  50.62,  50.63,  67.5,   84.37,  84.38, 101.25, 118.12}]
    test_points(2) = [{ 118.13, 135.0,  151.87, 151.88, 168.75, 185.62, 185.63, 202.5,  219.37, 219.38, 236.25}]
    test_points(3) = [{ 253.12, 253.13, 270.0,  286.87, 286.88, 303.75, 320.62, 320.63, 337.5,  354.37, 354.38}]
    For i = 1 To 3
        For Each t In test_points(i)
            test_points_all.Add t
        Next t
    Next i
    For i = 1 To 8
        For Each c In compass_points(i)
            compass_points_all.Add c
        Next c
    Next i
    For i = 1 To test_points_all.Count
        compass_point = (WorksheetFunction.Floor(test_points_all(i) * 32 / 360 + 0.5, 1) Mod 32) + 1
        Debug.Print Format(compass_point, "@@"); "  "; compass_points_all(compass_point);
        Debug.Print String$(20 - Len(compass_points_all(compass_point)), " ");
        Debug.Print test_points_all(i)
    Next i
End Sub


Module BoxingTheCompass
    Dim _points(32) As String

    Sub Main()
        BuildPoints()

        Dim heading As Double = 0D

        For i As Integer = 0 To 32
            heading = i * 11.25
            Select Case i Mod 3
                Case 1
                    heading += 5.62
                Case 2
                    heading -= 5.62
            End Select

            Console.WriteLine("{0,2}: {1,-18} {2,6:F2}°", (i Mod 32) + 1, InitialUpper(GetPoint(heading)), heading)
        Next
    End Sub

    Private Sub BuildPoints()
        Dim cardinal As String() = New String() {"north", "east", "south", "west"}
        Dim pointDesc As String() = New String() {"1", "1 by 2", "1-C", "C by 1", "C", "C by 2", "2-C", "2 by 1"}

        Dim str1, str2, strC As String

        For i As Integer = 0 To 3
            str1 = cardinal(i)
            str2 = cardinal((i + 1) Mod 4)
            strC = IIf(str1 = "north" Or str1 = "south", str1 & str2, str2 & str1)
            For j As Integer = 0 To 7
                _points(i * 8 + j) = pointDesc(j).Replace("1", str1).Replace("2", str2).Replace("C", strC)
            Next
        Next
    End Sub

    Private Function InitialUpper(ByVal s As String) As String
        Return s.Substring(0, 1).ToUpper() & s.Substring(1)
    End Function

    Private Function GetPoint(ByVal Degrees As Double) As String
        Dim testD As Double = (Degrees / 11.25) + 0.5
        Return _points(CInt(Math.Floor(testD Mod 32)))
    End Function
End Module


def a: [x f075 x];
def b: [x 81 x];

($a and $b) -> '$a; and $b; is $;$#10;' -> !OUT::write
($a or $b) -> '$a; or $b; is $;$#10;' -> !OUT::write
($a xor $b) -> '$a; xor $b; is $;$#10;' -> !OUT::write
$a::inverse -> 'not $a; is $;$#10;' -> !OUT::write
$a::shift&{left: 3, fill: [x 00 x]} -> '$a; shifted left 3 bits is $;$#10;' -> !OUT::write
$a::shift&{left: -3, fill: [x 00 x]} -> '$a; shifted right 3 bits is $;$#10;' -> !OUT::write
$a::shift&{left: -3, fill: $a(0)} -> '$a; arithmetically shifted right 3 bits is $;$#10;' -> !OUT::write
$a::shift&{left: 3, fill: $a} -> '$a; rotated left 3 bits is $;$#10;' -> !OUT::write
$a::shift&{left: -3, fill: $a} -> '$a; rotated right 3 bits is $;$#10;' -> !OUT::write


proc bitwise {a b} {
    puts [format "a and b: %#08x" [expr {$a & $b}]]
    puts [format "a or b: %#08x"  [expr {$a | $b}]]
    puts [format "a xor b: %#08x" [expr {$a ^ $b}]]
    puts [format "not a: %#08x"   [expr {~$a}]]
    puts [format "a << b: %#08x"  [expr {$a << $b}]]
    puts [format "a >> b: %#08x"  [expr {$a >> $b}]]
}


INCLUDE "H6:RGBCIRCL.ACT" ;from task Midpoint circle algorithm

RGB black,white,yellow,blue

DEFINE PTR="CARD"
TYPE PointB=[BYTE px,py]
TYPE Queue=[PTR qfront,qrear,qdata INT capacity]

PROC QueueInit(Queue POINTER q)
  DEFINE MAXSIZE="500"
  CARD ARRAY a(MAXSIZE)

  q.qfront=0
  q.qrear=0
  q.capacity=MAXSIZE
  q.qdata=a
RETURN

BYTE FUNC IsQueueEmpty(Queue POINTER q)
  IF q.qfront=q.qrear THEN
    RETURN (1)
  FI
RETURN (0)

PROC QueuePush(Queue POINTER q PointB POINTER p)
  PTR rear
  PointB POINTER tmp

  rear=q.qrear+1
  IF rear=q.capacity THEN
    rear=0
  FI
  IF rear=q.qfront THEN
    Break()
  FI
  tmp=q.qdata+q.qrear*2
  tmp.px=p.px
  tmp.py=p.py
  q.qrear=rear
RETURN

PROC QueuePop(Queue POINTER q PointB POINTER p)
  PointB POINTER tmp

  IF IsQueueEmpty(q) THEN
    Break()
  FI
  tmp=q.qdata+q.qfront*2
  p.px=tmp.px
  p.py=tmp.py
  q.qfront==+1
  IF q.qfront=q.capacity THEN
    q.qfront=0
  FI
RETURN

PROC DrawImage(RgbImage POINTER img BYTE x,y)
  RGB POINTER p
  BYTE i,j

  p=img.data
  FOR j=0 TO img.h-1
  DO
    FOR i=0 TO img.w-1
    DO
      IF RgbEqual(p,yellow) THEN
        Color=1
      ELSEIF RgbEqual(p,white) THEN
        Color=2
      ELSEIF RgbEqual(p,blue) THEN
        Color=3
      ELSE
        Color=0
      FI
      Plot(x+i,y+j)
      p==+RGBSIZE
    OD
  OD
RETURN

PROC FloodFill(RgbImage POINTER img BYTE x0,y0 RGB POINTER col)
  Queue q
  RGB c,tmp
  PointB p

  GetRgbPixel(img,x0,y0,c)
  IF RgbEqual(c,col) THEN
    RETURN
  FI
  p.px=x0 p.py=y0
  QueueInit(q)
  QueuePush(q,p)
  WHILE IsQueueEmpty(q)=0
  DO
    QueuePop(q,p)
    x0=p.px y0=p.py

    GetRgbPixel(img,x0,y0,tmp)
    IF RgbEqual(tmp,c) THEN
      SetRgbPixel(img,x0,y0,col)

      IF x0>0 THEN
        GetRgbPixel(img,x0-1,y0,tmp)
        IF RgbEqual(tmp,c) THEN
          p.px=x0-1 p.py=y0
          QueuePush(q,p)
        FI
      FI
      IF x0<img.w-1 THEN
        GetRgbPixel(img,x0+1,y0,tmp)
        IF RgbEqual(tmp,c) THEN
          p.px=x0+1 p.py=y0
          QueuePush(q,p)
        FI
      FI
      IF y0>0 THEN
        GetRgbPixel(img,x0,y0-1,tmp)
        IF RgbEqual(tmp,c) THEN
          p.px=x0 p.py=y0-1
          QueuePush(q,p)
        FI
      FI
      IF y0<img.h-1 THEN
        GetRgbPixel(img,x0,y0+1,tmp)
        IF RgbEqual(tmp,c) THEN
          p.px=x0 p.py=y0+1
          QueuePush(q,p)
        FI
      FI
    FI
  OD
RETURN

PROC Main()
  RgbImage img
  BYTE CH=$02FC,size=[40]
  BYTE ARRAY p(4800)
  BYTE n
  INT x,y
  RGB POINTER col

  Graphics(7+16)
  SetColor(0,13,12) ;yellow
  SetColor(1,0,14)  ;white
  SetColor(2,8,6)   ;blue
  SetColor(4,0,0)   ;black

  RgbBlack(black)
  RgbYellow(yellow)
  RgbWhite(white)
  RgbBlue(blue)

  InitRgbImage(img,size,size,p)
  FillRgbImage(img,black)

  RgbCircle(img,size/2,size/2,size/2-1,white)
  RgbCircle(img,2*size/5,2*size/5,size/5,white)
  DrawImage(img,0,(96-size)/2)

  FloodFill(img,3*size/5,3*size/5,white)
  DrawImage(img,size,(96-size)/2)

  FloodFill(img,2*size/5,2*size/5,blue)
  DrawImage(img,2*size,(96-size)/2)

  FloodFill(img,3*size/5,3*size/5,yellow)
  DrawImage(img,3*size,(96-size)/2)

  DO UNTIL CH#$FF OD
  CH=$FF
RETURN


import "/fmt" for Fmt

// 'cpx' returns integer index from 0 to 31 corresponding to compass point.
// Input heading h is in degrees.  Note this index is a zero-based index
// suitable for indexing into the table of printable compass points,
// and is not the same as the index specified to be printed in the output.
var cpx = Fn.new { |h|
    var x = (h/11.25+0.5).floor % 32
    if (x < 0) x = x + 32
    return x
}

// printable compass points
var compassPoint = [
    "North",
    "North by east",
    "North-northeast",
    "Northeast by north",
    "Northeast",
    "Northeast by east",
    "East-northeast",
    "East by north",
    "East",
    "East by south",
    "East-southeast",
    "Southeast by east",
    "Southeast",
    "Southeast by south",
    "South-southeast",
    "South by east",
    "South",
    "South by west",
    "South-southwest",
    "Southwest by south",
    "Southwest",
    "Southwest by west",
    "West-southwest",
    "West by south",
    "West",
    "West by north",
    "West-northwest",
    "Northwest by west",
    "Northwest",
    "Northwest by north",
    "North-northwest",
    "North by west"
]

// function required by task
var degreesToCompassPoint = Fn.new { |h| compassPoint[cpx.call(h)] }

var r = [
    0.0, 16.87, 16.88, 33.75, 50.62, 50.63, 67.5,
    84.37, 84.38, 101.25, 118.12, 118.13, 135.0, 151.87, 151.88, 168.75,
    185.62, 185.63, 202.5, 219.37, 219.38, 236.25, 253.12, 253.13, 270.0,
    286.87, 286.88, 303.75, 320.62, 320.63, 337.5, 354.37, 354.38
]

System.print("Index  Compass point         Degree")
var i = 0
for (h in r) {
    var index = i%32 + 1  // printable index computed per pseudocode
    var d = degreesToCompassPoint.call(h)
    System.print("%(Fmt.d(4, index))   %(Fmt.s(-19, d)) %(Fmt.f(7, h, 2))°")
    i = i + 1
}


bitwise(a,b)
Prgm
  Local show, oldbase
  Define show(label, x)=Prgm
    Local r
    setMode("Base","DEC")
    string(x) → r
    setMode("Base","HEX")
    Disp label & r & " " & string(x)
  EndPrgm
  getMode("Base") → oldbase
  show("", {a, b})
  show("And ", a and b)
  show("Or  ", a or b)
  show("Xor ", a xor b)
  show("Not ", not a)
  Pause "[Press ENTER]"
  show("LSh ", shift(a,b))
  show("RSh ", shift(a,–b))
  show("LRo ", rotate(a,b))
  show("RRo ", rotate(a,–b))
  setMode("Base",oldbase)
EndPrgm


void testbit(int a, int b) {
  print(@"input: a = $a, b = $b\n");
  print(@"AND:  $a  & $b = $(a & b)\n");
  print(@"OR:   $a  | $b = $(a | b)\n");
  print(@"XOR:  $a  ^ $b = $(a ^ b)\n");
  print(@"LSH:  $a << $b = $(a << b)\n");
  print(@"RSH:  $a >> $b = $(a >> b)\n");
  print(@"NOT:  ~$a = $(~a)\n");
  /* there are no rotation operators in vala, but you could define your own
     function to do what is required. */
}

void main() {
  int a = 255;
  int b = 2;
  testbit(a,b);
}


procedure Flood_Fill
          (  Picture  : in out Image;
             From     : Point;
             Fill     : Pixel;
             Replace  : Pixel;
             Distance : Luminance := 20
          )  is
   function Diff (A, B : Luminance) return Luminance is
      pragma Inline (Diff);
   begin
      if A > B then
         return A - B;
      else
         return B - A;
      end if;
   end Diff;

   function "-" (A, B : Pixel) return Luminance is
      pragma Inline ("-");
   begin
      return Luminance'Max (Luminance'Max (Diff (A.R, B.R), Diff (A.G, B.G)), Diff (A.B, B.B));
   end "-";
   procedure Column (From : Point);
   procedure Row (From : Point);

   Visited : array (Picture'Range (1), Picture'Range (2)) of Boolean :=
      (others => (others => False));

   procedure Column (From : Point) is
      X1 : Positive := From.X;
      X2 : Positive := From.X;
   begin
      Visited (From.X, From.Y) := True;
      for X in reverse Picture'First (1)..From.X - 1 loop
         exit when Visited (X, From.Y);
         declare
            Color : Pixel renames Picture (X, From.Y);
         begin
            Visited (X, From.Y) := True;
            exit when Color - Replace > Distance;
            Color := Fill;
            X1    := X;
         end;
      end loop;
      for X in From.X + 1..Picture'Last (1) loop
         exit when Visited (X, From.Y);
         declare
            Color : Pixel renames Picture (X, From.Y);
         begin
            Visited (X, From.Y) := True;
            exit when Color - Replace > Distance;
            Color := Fill;
            X2    := X;
         end;
      end loop;
      for X in X1..From.X - 1 loop
         Row ((X, From.Y));
      end loop;
      for X in From.X + 1..X2 loop
         Row ((X, From.Y));
      end loop;
   end Column;

   procedure Row (From : Point) is
      Y1 : Positive := From.Y;
      Y2 : Positive := From.Y;
   begin
      Visited (From.X, From.Y) := True;
      for Y in reverse Picture'First (2)..From.Y - 1 loop
         exit when Visited (From.X, Y);
         declare
            Color : Pixel renames Picture (From.X, Y);
         begin
            Visited (From.X, Y) := True;
            exit when Color - Replace > Distance;
            Color := Fill;
            Y1    := Y;
         end;
      end loop;
      for Y in From.Y + 1..Picture'Last (2) loop
         exit when Visited (From.X, Y);
         declare
            Color : Pixel renames Picture (From.X, Y);
         begin
            Visited (From.X, Y) := True;
            exit when Color - Replace > Distance;
            Color := Fill;
            Y2    := Y;
         end;
      end loop;
      for Y in Y1..From.Y - 1 loop
         Column ((From.X, Y));
      end loop;
      for Y in From.Y + 1..Y2 loop
         Column ((From.X, Y));
      end loop;
   end Row;

   Color : Pixel renames Picture (From.X, From.Y);
begin
   if Color - Replace <= Distance then
      Visited (From.X, From.Y) := True;
      Color := Fill;
      Column (From);
   end if;
end Flood_Fill;


dim point$(32)

for i =1 to 32
    read point$(i)
next i

print "Index\tClosest Point\t\tDegrees"
print "=====\t=============\t\t======="
for i = 0 to 32
    heading = i *11.25
    resto=mod(i,3)
    if resto=1 then
        heading = heading +5.62
    elseif resto=2 then
    	heading = heading -5.62
    end if
    ind = mod(i,32)+1
    print ind,"\t",compasspoint$( heading),"\t",heading
next i

end

sub compasspoint$(h)
    x = h / 11.25 + 1.5
    if (x >= 33.0)  x = x - 32.0
    return point$(int(x))
end sub

10 data  "North             ", "North by east     ", "North-northeast   "
20 data  "Northeast by north", "Northeast         ", "Northeast by east ", "East-northeast    "
30 data  "East by north     ", "East              ", "East by south     ", "East-southeast    "
40 data  "Southeast by east ", "Southeast         ", "Southeast by south", "South-southeast   "
50 data  "South by east     ", "South             ", "South by west     ", "South-southwest   "
60 data  "Southwest by south", "Southwest         ", "Southwest by west ", "West-southwest    "
70 data  "West by south     ", "West              ", "West by north     ", "West-northwest    "
80 data  "Northwest by west ", "Northwest         ", "Northwest by north", "North-northwest   "
90 data  "North by west     "


A:=("X N NbE NNE NEbN NE NEbE ENE EbN E EbS ESE "  // one based array
        "SEbE SE SEbS SSE SbE S SbW SSW SWbS SW SWbW "
        "WSW WbS W WbN WNW NWbW NW NWbN NNW NbW").split(" ");

fcn compassBox(d){
    return(( ( (d + 360.0 / 64.0) % 360.0) * 32.0 / 360.0).ceil());
}

foreach i in ([0..32]){
   heading:=11.25*i;
   switch(i%3){  // or heading+=5.62*((i+1).divr(3)[1]-1);
      case(1){ heading+=5.62 }
      case(2){ heading-=5.62 }
   }
   box:=compassBox(heading);
   println("%6.2f\UB0; : %2d\t%s".fmt(heading,box,A[box]));
}


Debug.Print Hex(&HF0F0 And &HFF00)  'F000
Debug.Print Hex(&HF0F0 Or &HFF00)   'FFF0
Debug.Print Hex(&HF0F0 Xor &HFF00)  'FF0
Debug.Print Hex(Not &HF0F0)         'F0F
Debug.Print Hex(&HF0F0 Eqv &HFF00)  'F00F
Debug.Print Hex(&HF0F0 Imp &HFF00)  'FF0F


Sub Test(a as Integer, b as Integer)
   WriteLine("And " & a And b)
   WriteLine("Or " & a Or b)
   WriteLine("Xor " & a Xor b)
   WriteLine("Not " & Not a)
   WriteLine("Left Shift " & a << 2)
   WriteLine("Right Shift " & a >> 2)
End Sub


SetBatchLines, -1
CoordMode, Mouse
CoordMode, Pixel
CapsLock::
KeyWait, CapsLock
MouseGetPos, X, Y
PixelGetColor, color, X, Y
FloodFill(x, y, color, 0x000000, 1, "CapsLock")
MsgBox Done!
Return
FloodFill(x, y, target, replacement, mode=1, key="")
{
   If GetKeyState(key, "P")
      Return
   PixelGetColor, color, x, y
   If (color <> target || color = replacement || target = replacement)
      Return
   VarSetCapacity(Rect, 16, 0)
   NumPut(x, Rect, 0)
   NumPut(y, Rect, 4)
   NumPut(x+1, Rect, 8)
   NumPut(y+1, Rect, 12)
   hDC := DllCall("GetDC", UInt, 0)
   hBrush := DllCall("CreateSolidBrush", UInt, replacement)
   DllCall("FillRect", UInt, hDC, Str, Rect, UInt, hBrush)
   DllCall("ReleaseDC", UInt, 0, UInt, hDC)
   DllCall("DeleteObject", UInt, hBrush)
   FloodFill(x+1, y, target, replacement, mode, key)
   FloodFill(x-1, y, target, replacement, mode, key)
   FloodFill(x, y+1, target, replacement, mode, key)
   FloodFill(x, y-1, target, replacement, mode, key)
   If (mode = 2 || mode = 4)
      FloodFill(x, y, target, replacement, mode, key)
   If (Mode = 3 || mode = 4)
   {
      FloodFill(x+1, y+1, target, replacement, key)
      FloodFill(x-1, y+1, target, replacement, key)
      FloodFill(x+1, y-1, target, replacement, key)
      FloodFill(x-1, y-1, target, replacement, key)
   }
}


10 DATA "North","North by east","North-northeast"
20 DATA "Northeast by north","Northeast","Northeast by east","East-northeast"
30 DATA "East by north","East","East by south","East-southeast"
40 DATA "Southeast by east","Southeast","Southeast by south","South-southeast"
50 DATA "South by east","South","South by west","South-southwest"
60 DATA "Southwest by south","Southwest","Southwest by west","West-southwest"
70 DATA "West by south","West","West by north","West-northwest"
80 DATA "Northwest by west","Northwest","Northwest by north","North-northwest"
90 DATA "North by west"
100 DIM p$(32,18)
110 FOR i=1 TO 32
120 READ p$(i)
130 NEXT i
140 FOR i=0 TO 32
150 LET h=i*11.25
160 LET r=FN m(i,3)
170 IF r=1 THEN LET h=h+5.62: GO TO 190
180 IF r=2 THEN LET h=h-5.62
190 LET ind=FN m(i,32)+1
200 PRINT ind;TAB 4;
210 LET x=h/11.25+1.5
220 IF x>=33 THEN LET x=x-32
230 PRINT p$(INT x);TAB 25;h
240 NEXT i
250 STOP
260 DEF FN m(i,n)=((i/n)-INT (i/n))*n : REM modulus function


var rl = Fn.new { |x, y| x << y | x >> (32-y) }

var rr = Fn.new { |x, y| x >> y | x << (32-y) }

var bitwise = Fn.new { |x, y|
    if (!x.isInteger || !y.isInteger || x < 0 || y < 0 || x > 0xffffffff || y > 0xffffffff) {
        Fiber.abort("Operands must be in the range of a 32-bit unsigned integer")
    }
    System.print(" x      = %(x)")
    System.print(" y      = %(y)")
    System.print(" x & y  = %(x & y)")
    System.print(" x | y  = %(x | y)")
    System.print(" x ^ y  = %(x ^ y)")
    System.print("~x      = %(~x)")
    System.print(" x << y = %(x << y)")
    System.print(" x >> y = %(x >> y)")
    System.print(" x rl y = %(rl.call(x, y))")
    System.print(" x rr y = %(rr.call(x, y))")
}

bitwise.call(10, 2)


      MODE 8
      GCOL 15
      CIRCLE FILL 640, 512, 500
      GCOL 0
      CIRCLE FILL 500, 600, 200
      GCOL 3
      PROCflood(600, 200, 15)
      GCOL 4
      PROCflood(600, 700, 0)
      END

      DEF PROCflood(X%, Y%, C%)
      LOCAL L%, R%
      IF POINT(X%,Y%) <> C% ENDPROC
      L% = X%
      R% = X%
      WHILE POINT(L%-2,Y%) = C% : L% -= 2 : ENDWHILE
      WHILE POINT(R%+2,Y%) = C% : R% += 2 : ENDWHILE
      LINE L%,Y%,R%,Y%
      FOR X% = L% TO R% STEP 2
        PROCflood(X%, Y%+2, C%)
        PROCflood(X%, Y%-2, C%)
      NEXT
      ENDPROC


/*
 * RosettaCode: Bitmap/Flood fill, language C, dialects C89, C99, C11.
 *
 * This is an implementation of the recursive algorithm. For the sake of
 * simplicity, instead of reading files as JPEG, PNG, etc., the program
 * read and write Portable Bit Map (PBM) files in plain text format.
 * Portable Bit Map files can also be read and written with GNU GIMP.
 *
 * The program is just an example, so the image size is limited to 2048x2048,
 * the image can only be black and white, there is no run-time validation.
 *
 * Data is read from a standard input stream, the results are written to the
 * standard output file.
 *
 * In order for this program to work properly it is necessary to allocate
 * enough memory for the program stack. For example, in Microsoft Visual Studio,
 * the option /stack:134217728 declares a 128MB stack instead of the default
 * size of 1MB.
 */
#define _CRT_SECURE_NO_WARNINGS /* Unlock printf etc. in MSVC */
#include <stdio.h>
#include <stdlib.h>

#define MAXSIZE 2048
#define BYTE unsigned char

static int width, height;
static BYTE bitmap[MAXSIZE][MAXSIZE];
static BYTE oldColor;
static BYTE newColor;

void floodFill(int i, int j)
{
    if ( 0 <= i && i < height
    &&   0 <= j && j < width
    &&   bitmap[i][j] == oldColor )
    {
        bitmap[i][j] = newColor;
        floodFill(i-1,j);
        floodFill(i+1,j);
        floodFill(i,j-1);
        floodFill(i,j+1);
    }
}

/* *****************************************************************************
 * Input/output routines.
 */

void skipLine(FILE* file)
{
    while(!ferror(file) && !feof(file) && fgetc(file) != '\n')
        ;
}

void skipCommentLines(FILE* file)
{
    int c;
    int comment = '#';

    while ((c = fgetc(file)) == comment)
        skipLine(file);
    ungetc(c,file);
}

readPortableBitMap(FILE* file)
{
    int i,j;

    skipLine(file);
    skipCommentLines(file);  fscanf(file,"%d",&width);
    skipCommentLines(file);  fscanf(file,"%d",&height);
    skipCommentLines(file);

    if ( width <= MAXSIZE && height <= MAXSIZE )
        for ( i = 0; i < height; i++ )
            for ( j = 0; j < width; j++ )
                fscanf(file,"%1d",&(bitmap[i][j]));
    else exit(EXIT_FAILURE);
}

void writePortableBitMap(FILE* file)
{
    int i,j;
    fprintf(file,"P1\n");
    fprintf(file,"%d %d\n", width, height);
    for ( i = 0; i < height; i++ )
    {
        for ( j = 0; j < width; j++ )
            fprintf(file,"%1d", bitmap[i][j]);
        fprintf(file,"\n");
    }
}

/* *****************************************************************************
 * The main entry point.
 */

int main(void)
{
    oldColor = 1;
    newColor = oldColor ? 0 : 1;
    readPortableBitMap(stdin);
    floodFill(height/2,width/2);
    writePortableBitMap(stdout);
    return EXIT_SUCCESS;
}


	extern printf
	global main

	section .text
main
	mov	eax, dword [_a]
	mov	ecx, dword [_b]
	push	ecx
	push	eax

	and 	eax, ecx
	mov	ebx, _opand
	call	out_ops

	call	get_nums
	or	eax, ecx
	mov	ebx, _opor
	call	out_ops

	call	get_nums
	xor     eax, ecx
	mov	ebx, _opxor
	call	out_ops

	call	get_nums
	shr	eax, cl
	mov	ebx, _opshr
	call	out_ops

	call	get_nums
	shl	eax, cl
	mov	ebx, _opshl
	call	out_ops

	call	get_nums
	rol	eax, cl
	mov	ebx, _oprol
	call	out_ops

	call	get_nums
	ror	eax, cl
	mov	ebx, _opror
	call	out_ops

	call	get_nums
	sal	eax, cl
	mov	ebx, _opsal
	call	out_ops

	call	get_nums
	sar	eax, cl
	mov	ebx, _opsar
	call	out_ops

	mov	eax, dword [esp+0]
	not	eax
	push 	eax
	not	eax
	push	eax
	push	_opnot
	push	_null
	push	_testn
	call	printf
	add	esp, 20

	add	esp, 8
	ret

out_ops
	push	eax
	push	ecx
	push	ebx
	push	dword [_a]
	push	_test
	call	printf
	add	esp, 20
	ret

get_nums
	mov	eax, dword [esp+4]
	mov	ecx, dword [esp+8]
	ret

	section .data

_a	dd	11
_b	dd	3

	section .rodata
_test	db	'%08x %s %08x = %08x', 10, 0
_testn	db	'%08s %s %08x = %08x', 10, 0
_opand	db	'and', 0
_opor	db	'or ', 0
_opxor	db	'xor', 0
_opshl	db	'shl', 0
_opshr	db	'shr', 0
_opror	db	'ror', 0
_oprol	db	'rol', 0
_opnot	db	'not', 0
_opsal	db	'sal', 0
_opsar	db	'sar', 0
_null	db 	0

	end


using System;
using System.Collections.Generic;
using System.Drawing;

namespace FloodFill
{
    class Program
    {
        private static bool ColorMatch(Color a, Color b)
        {
            return (a.ToArgb() & 0xffffff) == (b.ToArgb() & 0xffffff);
        }

        static void FloodFill(Bitmap bmp, Point pt, Color targetColor, Color replacementColor)
        {
            Queue<Point> q = new Queue<Point>();
            q.Enqueue(pt);
            while (q.Count > 0)
            {
                Point n = q.Dequeue();
                if (!ColorMatch(bmp.GetPixel(n.X, n.Y),targetColor))
                    continue;
                Point w = n, e = new Point(n.X + 1, n.Y);
                while ((w.X >= 0) && ColorMatch(bmp.GetPixel(w.X, w.Y),targetColor))
                {
                    bmp.SetPixel(w.X, w.Y, replacementColor);
                    if ((w.Y > 0) && ColorMatch(bmp.GetPixel(w.X, w.Y - 1),targetColor))
                        q.Enqueue(new Point(w.X, w.Y - 1));
                    if ((w.Y < bmp.Height - 1) && ColorMatch(bmp.GetPixel(w.X, w.Y + 1),targetColor))
                        q.Enqueue(new Point(w.X, w.Y + 1));
                    w.X--;
                }
                while ((e.X <= bmp.Width - 1) && ColorMatch(bmp.GetPixel(e.X, e.Y),targetColor))
                {
                    bmp.SetPixel(e.X, e.Y, replacementColor);
                    if ((e.Y > 0) && ColorMatch(bmp.GetPixel(e.X, e.Y - 1), targetColor))
                        q.Enqueue(new Point(e.X, e.Y - 1));
                    if ((e.Y < bmp.Height - 1) && ColorMatch(bmp.GetPixel(e.X, e.Y + 1), targetColor))
                        q.Enqueue(new Point(e.X, e.Y + 1));
                    e.X++;
                }
            }
        }

        static void Main(string[] args)
        {
            Bitmap bmp = new Bitmap("Unfilledcirc.bmp");
            FloodFill(bmp, new Point(200, 200), Color.White, Color.Red);
            FloodFill(bmp, new Point(100, 100), Color.Black, Color.Blue);
            bmp.Save("Filledcirc.bmp");
        }
    }
}


PROGRAM "bitwise"

DECLARE FUNCTION Entry()
INTERNAL FUNCTION ULONG Rotr(ULONG x, ULONG s)

FUNCTION Entry()
  SLONG a, b
  ULONG ua, ub
  a = 21
  b = 3
  ua = a
  ub = b
  PRINT
  PRINT "= Decimal ="
  PRINT LTRIM$(STR$(a)); " AND"; b; ":"; a & b ' also: a AND b
  PRINT LTRIM$(STR$(a)); " OR"; b; ":"; a | b ' also: a OR b
  PRINT LTRIM$(STR$(a)); " XOR"; b; ":"; a ^ b' also: a XOR b
  PRINT "NOT"; a; ":"; ~a ' also: NOT a
  PRINT LTRIM$(STR$(a)); " <<<"; b; ":"; a <<< b ' arithmetic left shift
  PRINT LTRIM$(STR$(a)); " >>>"; b; ":"; a >>> b ' arithmetic right shift
  PRINT LTRIM$(STR$(ua)); " <<"; b; ":"; ua << b ' bitwise left shift
  PRINT LTRIM$(STR$(ua)); " >>"; b; ":"; ua >> b ' bitwise right shift
  PRINT LTRIM$(STR$(ua)); " rotr"; ub; ":"; Rotr(ua, ub)
  PRINT
  PRINT "= Binary ="
  PRINT BIN$(a); " AND "; BIN$(b); ": "; BIN$(a & b)
  PRINT BIN$(a); " OR "; BIN$(b); ": "; BIN$(a | b)
  PRINT BIN$(a); " XOR "; BIN$(b); ": "; BIN$(a ^ b)
  PRINT "NOT "; BIN$(a); ": "; BIN$(~a)
  PRINT BIN$(a); " <<< "; BIN$(b); ": "; BIN$(a <<< b)
  PRINT BIN$(a); " >>> "; BIN$(b); ": "; BIN$(a >>> b)
  PRINT BIN$(ua); " << "; BIN$(b); ": "; BIN$(ua << b)
  PRINT BIN$(ua); " >> "; BIN$(b); ": "; BIN$(ua >> b)
  PRINT BIN$(ua); " Rotr "; BIN$(ub); ": "; BIN$(Rotr(ua, ub))
END FUNCTION

' Rotate x to the right by s bits
FUNCTION ULONG Rotr(ULONG x, ULONG s)
  RETURN (x >> s) | (x << (SIZE(ULONG) * 8 - s))
END FUNCTION
END PROGRAM


#ifndef PROCESSING_FLOODFILLALGORITHM_H_
#define PROCESSING_FLOODFILLALGORITHM_H_

#include <opencv2/opencv.hpp>
#include <string.h>
#include <queue>

using namespace cv;
using namespace std;

class FloodFillAlgorithm {
public:
    FloodFillAlgorithm(Mat* image) :
        image(image) {
    }
    virtual ~FloodFillAlgorithm();

    void flood(Point startPoint, Scalar tgtColor, Scalar loDiff);
    void flood(Point startPoint, Mat* tgtMat);

protected:
    Mat* image;
private:
    bool insideImage(Point p);
};

#endif /* PROCESSING_FLOODFILLALGORITHM_H_ */


import std.array, bitmap;

void floodFill(Color)(Image!Color img, in uint x, in uint y,
                      in Color color)
/*pure*/ nothrow in {
    assert (y < img.ny && x < img.nx);
} body {
    immutable target = img[x, y];
    static struct Pos { uint x, y; }
    auto stack = [Pos(x, y)];

    while (!stack.empty) {
        immutable p = stack.back;
        stack.popBack;
        if (p.y < img.ny && p.x < img.nx && img[p.x, p.y] == target) {
            img[p.x, p.y] = color;
            stack.assumeSafeAppend;
            stack ~= [Pos(p.x,     p.y + 1), Pos(p.x,     p.y - 1),
                      Pos(p.x + 1, p.y),     Pos(p.x - 1, p.y)];
        }
    }
}

void main() {
    Image!RGB img;
    loadPPM6(img, "unfilled_circ.ppm");
    img.floodFill(200, 200, RGB(127, 0, 0));
    img.savePPM6("unfilled_circ_flooded.ppm");
}


(defun bitwise-operations (a b)
	; rotate operations are not supported
	(print `(,a and ,b = ,(logand a b)))
	(print `(,a or ,b = ,(logior a b)))
	(print `(,a xor ,b = ,(logxor a b)))
	(print `(,a left shift by ,b = ,(lsh a b)))
	(print `(,a right shift by ,b = ,(lsh a (- b)))) ; negative second operand shifts right
	(print `(,a arithmetic right shift by ,b = ,(ash a (- b)))) )


Text(0, "A and B = ");  HexOut(0, A and B);  CrLf(0);   \alternate symbol: &
Text(0, "A or B = ");   HexOut(0, A or B);   CrLf(0);   \alternate symbol: !
Text(0, "A xor B = ");  HexOut(0, A xor B);  CrLf(0);   \alternate symbol: |
Text(0, "not A = ");    HexOut(0, not A);    CrLf(0);   \alternate symbol: ~
Text(0, "A << B = ");   HexOut(0, A << B);   CrLf(0);
Text(0, "A >> B logical = ");  HexOut(0, A >> B);  CrLf(0);
Text(0, "A >> B arithmetic = ");  HexOut(0, A ->> B);  CrLf(0);

\Rotate operations must be done by calling a function such as:
func ROR(A, B); int A, B; return A>>B ! A<<(32-B);

Text(0, "A ror B = ");  HexOut(0, ROR(A,B));  CrLf(0);


def floodFill(image, x, y, newColor) {
  def matchColor := image[x, y]
  def w := image.width()
  def h := image.height()

  /** For any given pixel x,y, this algorithm first fills a contiguous
      horizontal line segment of pixels containing that pixel, then
      recursively scans the two adjacent rows over the same horizontal
      interval. Let this be invocation 0, and the immediate recursive
      invocations be 1, 2, 3, ..., # be pixels of the wrong color, and
      * be where each scan starts; the fill ordering is as follows:

      --------------##########-------
      -...1111111111*11####*33333...-
      ###########000*000000000000...-
      -...2222222222*22222##*4444...-
      --------------------##---------

      Each invocation returns the x coordinate of the rightmost pixel it filled,
      or x0 if none were.

      Since it is recursive, this algorithm is unsuitable for large images
      with small stacks.
    */
  def fillScan(var x0, y) {
    if (y >= 0 && y < h && x0 >= 0 && x0 < w) {
      image[x0, y] := newColor
      var x1 := x0

      # Fill rightward
      while (x1 < w - 1 && image.test(x1 + 1, y, matchColor)) {
        x1 += 1
        image[x1, y] := newColor # This could be replaced with a horizontal-line drawing operation
      }

      # Fill leftward
      while (x0 > 0 && image.test(x0 - 1, y, matchColor)) {
        x0 -= 1
        image[x0, y] := newColor
      }

      if (x0 > x1) { return x0 } # Filled at most center

      # x0..x1 is now a run of newly-filled pixels.

      # println(`Filled $y $x0..$x1`)
      # println(image)

      # Scan the lines above and below
      for ynext in [y - 1, y + 1] {
        if (ynext >= 0 && ynext < h) {
          var x := x0
          while (x <= x1) {
            if (image.test(x, ynext, matchColor)) {
              x := fillScan(x, ynext)
            }
            x += 1
          }
        }
      }

      return x1
    } else {
      return x0
    }
  }

  fillScan(x, y)
}


sub formBin$(n)
    return right$("00000000" + bin$(n), 8)
end sub

a = 6 : b = 3
print a, " = \t", formBin$(a)
print b, " = \t", formBin$(b)
print "\t--------"
print "AND = \t", formBin$(and(a, b))
print "OR = \t", formBin$(or(a, b))
print "XOR = \t", formBin$(xor(a, b))
print "NOT ", a, " =\t", formBin$(xor(255, a))