Gtk4-tutorial/docs/turtle_doc.html

517 lines
21 KiB
HTML
Raw Normal View History

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="generator" content="pandoc" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-9ndCyUaIbzAi2FUVXJi0CjmCapSmO7SnpJef0486qhLnuZ2cdeRhO02iuK6FUUVM" crossorigin="anonymous">
2023-01-05 13:35:42 +01:00
<title>GTK 4 tutorial</title>
<style>
code{white-space: pre-wrap;}
span.smallcaps{font-variant: small-caps;}
span.underline{text-decoration: underline;}
div.column{display: inline-block; vertical-align: top; width: 50%;}
div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
ul.task-list{list-style: none;}
pre{overflow: visible;}
pre > code.sourceCode { white-space: pre; position: relative; }
pre > code.sourceCode > span { display: inline-block; line-height: 1.25; }
pre > code.sourceCode > span:empty { height: 1.2em; }
code.sourceCode > span { color: inherit; text-decoration: inherit; }
div.sourceCode { margin: 1em 0; }
pre.sourceCode { margin: 0; }
@media screen {
div.sourceCode { overflow: auto; }
}
@media print {
pre > code.sourceCode { white-space: pre-wrap; }
pre > code.sourceCode > span { text-indent: -5em; padding-left: 5em; }
}
pre.numberSource code
{ counter-reset: source-line 0; }
pre.numberSource code > span
{ position: relative; left: -4em; counter-increment: source-line; }
pre.numberSource code > span > a:first-child::after
{ content: counter(source-line);
position: relative; left: -1em; text-align: right; vertical-align: baseline;
border: none; display: inline-block;
-webkit-touch-callout: none; -webkit-user-select: none;
-khtml-user-select: none; -moz-user-select: none;
-ms-user-select: none; user-select: none;
padding: 0 4px; width: 4em;
color: #aaaaaa;
}
pre.numberSource { margin-left: 3em; border-left: 1px solid #aaaaaa; padding-left: 4px; }
div.sourceCode
{ }
@media screen {
pre > code.sourceCode > span > a:first-child::before { text-decoration: underline; }
}
code span.al { color: #ff0000; font-weight: bold; } /* Alert */
code span.an { color: #60a0b0; font-weight: bold; font-style: italic; } /* Annotation */
code span.at { color: #7d9029; } /* Attribute */
code span.bn { color: #40a070; } /* BaseN */
code span.bu { } /* BuiltIn */
code span.cf { color: #007020; font-weight: bold; } /* ControlFlow */
code span.ch { color: #4070a0; } /* Char */
code span.cn { color: #880000; } /* Constant */
code span.co { color: #60a0b0; font-style: italic; } /* Comment */
code span.cv { color: #60a0b0; font-weight: bold; font-style: italic; } /* CommentVar */
code span.do { color: #ba2121; font-style: italic; } /* Documentation */
code span.dt { color: #902000; } /* DataType */
code span.dv { color: #40a070; } /* DecVal */
code span.er { color: #ff0000; font-weight: bold; } /* Error */
code span.ex { } /* Extension */
code span.fl { color: #40a070; } /* Float */
code span.fu { color: #06287e; } /* Function */
code span.im { } /* Import */
code span.in { color: #60a0b0; font-weight: bold; font-style: italic; } /* Information */
code span.kw { color: #007020; font-weight: bold; } /* Keyword */
code span.op { color: #666666; } /* Operator */
code span.ot { color: #007020; } /* Other */
code span.pp { color: #bc7a00; } /* Preprocessor */
code span.sc { color: #4070a0; } /* SpecialChar */
code span.ss { color: #bb6688; } /* SpecialString */
code span.st { color: #4070a0; } /* String */
code span.va { color: #19177c; } /* Variable */
code span.vs { color: #4070a0; } /* VerbatimString */
code span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */
div.sourceCode { margin: 10px; padding: 16px 10px 8px 10px; border: 2px solid silver; background-color: ghostwhite; overflow-x:scroll}
pre:not(.sourceCode) { margin: 10px; padding: 16px 10px 8px 10px; border: 2px solid silver; background-color: ghostwhite; overflow-x:scroll}
table {margin-left: auto; margin-right: auto; border-collapse: collapse; border: 1px solid;}
th {padding: 2px 6px; border: 1px solid; background-color: ghostwhite;}
td {padding: 2px 6px; border: 1px solid;}
img {display: block; margin-left: auto; margin-right: auto;}
figcaption {text-align: center;}
</style>
</head>
<body style="padding-top: 70px;">
<div class="container">
<nav class="navbar fixed-top navbar-expand-lg navbar-dark bg-primary">
<div class="container-fluid">
<span class="navbar-brand">Gtk4 tutorial</span>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
<li class="nav-item">
<a class="nav-link" href="index.html">Home</a>
</li>
</ul>
</div>
</div>
</nav>
<div class="row justify-content-center">
<div class="col-xl-10 col-xxl-9">
2023-01-18 06:27:57 +01:00
<h1 id="turtle-manual">Turtle manual</h1>
<p>Turtle is a simple interpreter for turtle graphics.</p>
<h2 id="prerequisite-and-compiling">Prerequisite and compiling</h2>
<p>Turtle is written in C language. You need:</p>
<ul>
2023-01-05 13:35:42 +01:00
<li>Linux. Turtle is tested on ubuntu 22.10</li>
<li>gcc, meson and ninja</li>
<li>gtk4</li>
</ul>
2023-01-05 13:35:42 +01:00
<p>It is easy to compile the source file of turtle. If you want tp
install it in your local area, put an option
<code>--prefix=$HOME/.local</code> to your meson command line. Then, it
will be installed under <code>$HOME/.local/bin</code>. The instruction
is:</p>
2023-07-29 14:41:57 +02:00
<pre><code>$ meson setup --prefix=$HOME/.local _build
$ ninja -C _build
$ ninja -C _build install</code></pre>
2023-01-05 13:35:42 +01:00
<p>If you want to install it in the system area, no option is necessary.
It will be installed under <code>/usr/local/bin</code>.</p>
2023-07-29 14:41:57 +02:00
<pre><code>$ meson setup _build
2023-01-05 13:35:42 +01:00
$ ninja -C _build
$ sudo ninja -C _build install</code></pre>
<p>Type the following command then turtle shows the following
window.</p>
<pre><code>$ turtle</code></pre>
<figure>
2023-01-05 13:35:42 +01:00
<img src="image/turtle1.png"
alt="Screenshot just after its executed" />
<figcaption aria-hidden="true">Screenshot just after its
executed</figcaption>
</figure>
2023-01-05 13:35:42 +01:00
<p>The left half is a text editor and the right half is a surface.
Surface is like a canvas to draw shapes.</p>
<p>Write turtle language in the text editor and click on
<code>run</code> button, then the program will be executed and it draws
shapes on the surface.</p>
<figure>
2023-01-05 13:35:42 +01:00
<img src="image/turtle_tree.png" alt="Tree" />
<figcaption aria-hidden="true">Tree</figcaption>
</figure>
2023-01-05 13:35:42 +01:00
<p>If you uncomment the following line in <code>turtle.y</code>, then
codes for debug will also be compiled. Turtle shows the status to the
standard output, but the speed is quite slow. It is not recommended
except you are developing the program.</p>
<pre><code>/* # define debug 1 */</code></pre>
<h2 id="example">Example</h2>
2023-01-05 13:35:42 +01:00
<p>Imagine a turtle. The turtle has a pen and initially it is at the
center of the screen, facing to the north (to the north means up on the
screen). You can let the turtle down the pen or up the pen. You can
order the turtle to move forward.</p>
<pre><code>pd
fd 100</code></pre>
<ul>
2023-01-05 13:35:42 +01:00
<li>pd: Pen Down. The turtle put the pen down so that the turtle will
draw a line if it moves.</li>
<li>fd 100: move ForwarD 100. The turtle goes forward 100 pixels.</li>
</ul>
2023-01-05 13:35:42 +01:00
<p>If you click on <code>run</code> button, then a line segment appears
on the screen. One of the endpoints of the line segment is at the center
of the surface and the other is at 100 pixels up from the center. The
point at the center is the start point of the turtle and the other
endpoint is the end point of the movement.</p>
<p>If the turtle picks the pen up, then no line segment appears.</p>
<pre><code>pu
fd 100</code></pre>
<p>The command <code>pu</code> means “Pen Up”.</p>
<p>The turtle can change the direction.</p>
<pre><code>pd
fd 100
tr 90
fd 100</code></pre>
2023-01-05 13:35:42 +01:00
<p>The command <code>tr</code> is “Turn Right”. The argument is angle
with degrees. Therefore, <code>tr 90</code> means “Turn right by 90
degrees”. If you click on the <code>run</code>button, then two line
segments appears. One is vertical and the other is horizontal.</p>
<figure>
2023-01-05 13:35:42 +01:00
<img src="image/turtle2.png" alt="Two line segments on the surface" />
<figcaption aria-hidden="true">Two line segments on the
surface</figcaption>
</figure>
2023-01-05 13:35:42 +01:00
<p>You can use <code>tl</code> (Turn Left) as well.</p>
<h2 id="background-and-foreground-color">Background and foreground
color</h2>
<p>Colors are specified with RGB. A vector (r, g, b) denotes RGB color.
Each of the elements is a real number between 0 and 1.</p>
<ul>
<li>Red is (1.0, 0.0, 0.0). You can write (1, 0, 0) instead.</li>
<li>Green is (0.0, 1.0, 0.0)</li>
<li>Blue is (0.0, 0.0, 1.0)</li>
<li>Black is (0.0, 0.0, 0.0)</li>
<li>White is (1.0, 1.0, 1.0)</li>
</ul>
<p>You can express a variety of colors by changing each element.</p>
<p>There are two commands to change colors.</p>
<ul>
2023-01-05 13:35:42 +01:00
<li>bc: Background Color. <code>bc (1,0,0)</code> changes the background
color to red. This command clear the surface and change the background
color. So, the shapes on the surface disappears.</li>
<li>fc: Foreground Color. <code>fc (0,1,0)</code> changes the foreground
color to green. This command changes the pen color. The prior shapes on
the surface arent affected. After this command, the turtle draws lines
with the new color.</li>
</ul>
<figure>
2023-01-05 13:35:42 +01:00
<img src="image/turtle3.png" alt="Change the foreground color" />
<figcaption aria-hidden="true">Change the foreground color</figcaption>
</figure>
<h2 id="other-simple-commands">Other simple commands</h2>
<ul>
2023-01-05 13:35:42 +01:00
<li>pw: Pen Width. This is the same as pen size or line width. For
example, <code>pw 5</code> makes lines thick and <code>pw 1</code> makes
it thin.</li>
<li>rs: ReSet. The turtle moves back to the initial position and
direction. In addition, The command initialize the pen, line width (pen
size), and foreground color. The pen is down, the line width is 2 and
the foreground color is black.</li>
</ul>
2023-01-05 13:35:42 +01:00
<p>An order such as <code>fd 100</code>, <code>pd</code> and so on is a
statement. Statements are executed in the order from the top to the end
in the program.</p>
<h2 id="comment-and-spaces">Comment and spaces</h2>
2023-01-05 13:35:42 +01:00
<p>Characters between <code>#</code> (hash mark) and <code>\n</code>
(new line) are comment. If the comment is at the end of the file, the
trailing new line can be left out. Comments are ignored.</p>
<pre><code># draw a triangle&lt;NEW LINE&gt;
fd 100 # forward 100 pixels&lt;NEW LINE&gt;
tr 120 # turn right by 90 degrees&lt;NEW LINE&gt;
fd 100&lt;NEW LINE&gt;
tr 120&lt;NEW LINE&gt;
fd 100 # Now a triangle appears.&lt;EOF&gt;</code></pre>
2023-01-05 13:35:42 +01:00
<p>&lt;NEW LINE&gt; and &lt;EOF&gt; indicate newline code and end of
file respectively. The comments in the line 1, 2, 3 and 6 are correct
syntactically.</p>
<p>Spaces (white space, tab and new line) are ignored. They are used
only as delimiters. Tabs are recognized as eight spaces to calculate the
column number.</p>
<h2 id="variables-and-expressions">Variables and expressions</h2>
2023-01-05 13:35:42 +01:00
<p>Variables begin alphabet followed by alphabet or digit. Key words
like <code>fd</code> or <code>tr</code> cant be variables.
<code>Distance</code> and <code>angle5</code> are variables, but
<code>1step</code> isnt a variable because the first character isnt
alphabet. Variable names are case sensitive. Variables keep real
numbers. Their type is the same as <code>double</code> in C language.
Integers are casted to real numbers automatically. So 1 and 1.0 are the
same value. Numbers begin digits, not signs (<code>+</code> or
<code>-</code>).</p>
<ul>
<li>100, 20.34 and 0.01 are numbers</li>
<li>+100 isnt a number. It causes syntax error. Use 100 instead.</li>
2023-01-05 13:35:42 +01:00
<li>-100 isnt a number. But turtle recognizes it unary minus and a
number 100. So turtle calculate it and the result is -100.</li>
<li>100 + -20: This is recognized 100 + (- 20). However, using bracket,
100 + (-20), is better for easy reading.</li>
</ul>
<pre><code>distance = 100
fd distance</code></pre>
2023-01-05 13:35:42 +01:00
<p>A value 100 is assigned to the variable <code>distance</code> in the
first line. Assignment is a statement. Most of statements begin with
commands like <code>fd</code>. Assignment is the only exception.</p>
<p>The example above draws a line segment of 100 pixels long.</p>
2023-01-05 13:35:42 +01:00
<p>You can use variables in expressions. There are 8 kinds of
calculations available.</p>
<ul>
<li>addition: x + y</li>
<li>subtraction: x - y</li>
<li>multiplication: x * y</li>
<li>division: x / y</li>
<li>unary minus: - x</li>
2023-01-05 13:35:42 +01:00
<li>logical equal: x = y. This symbol <code>=</code> works as
<code>==</code> in C language.</li>
<li>greater than: x &gt; y</li>
<li>less than: x &lt; y</li>
</ul>
2023-01-05 13:35:42 +01:00
<p>The last three symbols are mainly used in the condition of if
statement.</p>
<p>Variables are registered to a symbol table when it is assigned a
value for the first time. Evaluating a variable before the registration
isnt allowed and occurs an error.</p>
<h2 id="if-statement">If statement</h2>
<p>Turtle language has very simple if statement.</p>
<pre><code>if (x &gt; 50) {
fd x
}</code></pre>
<p>There is no else part.</p>
2023-01-05 13:35:42 +01:00
<h2 id="loop">Loop</h2>
<p>Turtle has very simple loop statement. It is <code>rp</code> (RePeat)
statement.</p>
<pre><code>rp (4) {
fd 100
tr 90
}</code></pre>
<p>The program repeats the statements in the brace four times.</p>
<h2 id="procedures">Procedures</h2>
2023-01-05 13:35:42 +01:00
<p>Procedures are similar to functions in C language. The difference is
that procedures dont have return values.</p>
<pre><code>dp triangle (side) {
fd side
tr 120
fd side
tr 120
fd side
}
triangle (100)</code></pre>
2023-01-05 13:35:42 +01:00
<p><code>dp</code> (Define Procedure) is a key word followed by
procedure name, parameters, and body. Procedure names start alphabet
followed by alphabet or digit. Parameters are a list of variables. For
example</p>
<pre><code>dp abc (a) { ... ... }
dp abc (a, b) { ... ... }
dp abc (a, b, c) { ... ... }</code></pre>
2023-01-05 13:35:42 +01:00
<p>Body is a sequence of statements. The statements arent executed when
the procedure is defined. They will be executed when the procedure is
called later.</p>
<p>Procedures are called by the name followed by arguments.</p>
<pre><code>dp proc (a, b, c) { ... ... }
proc (100, 0, -20*3)</code></pre>
2023-01-05 13:35:42 +01:00
<p>The number of parameters and arguments must be the same. Arguments
can be any expressions. When you call a procedure, brackets following
the procedure name must exist even if the procedure has no argument.</p>
<p>Procedure names and variable names dont conflict.</p>
<pre><code>dp a () {fd a}
a=100
a ()</code></pre>
<p>This is a correct program.</p>
<ul>
2023-01-05 13:35:42 +01:00
<li>1: Defines a procedure <code>a</code>. A variable <code>a</code> is
in its body.</li>
<li>2: Assigns 100 to a variable <code>a</code>.</li>
<li>3: Procedure <code>a</code> is called.</li>
</ul>
2023-01-05 13:35:42 +01:00
<p>However, using the same name to a procedure and variable makes
confusion. You should avoid that.</p>
<h2 id="recursive-call">Recursive call</h2>
<p>Procedures can be called recursively.</p>
<pre><code>dp repeat (n) {
n = n - 1
if (n &lt; 0) {
rt
}
fd 100
tr 90
repeat (n)
}
repeat (4)</code></pre>
2023-01-05 13:35:42 +01:00
<p>Repeat is called in the body of repeat. The call to itself is a
recursive call. Parameters are created and set each time the procedure
is called. So, parameter <code>n</code> is 4 at the first call but it is
3 at the second call. Every time the procedure is called, the parameter
<code>n</code> decreases by one. Finally, it becomes less than zero,
then the procedures return.</p>
<p>The program above draws a square.</p>
2023-01-05 13:35:42 +01:00
<p>It shows that we can program loop with a recursive call.</p>
<h2 id="fractal-curves">Fractal curves</h2>
2023-01-05 13:35:42 +01:00
<p>Recursive call can be applied to draw fractal curves. Fractal curves
appear when a procedure is applied to it repeatedly. The procedure
replaces a part of the curve with the contracted curve.</p>
<figure>
2023-01-05 13:35:42 +01:00
<img src="image/turtle_tree.png" alt="Tree" />
<figcaption aria-hidden="true">Tree</figcaption>
</figure>
2023-01-05 13:35:42 +01:00
<p>This shape is called tree. The basic pattern of this shape is a line
segment. It is the first stage. The second stage adds two shorter line
segments at the endpoint of the original segment. The new segment has 70
percent length to the original segment and the orientation is +30 or -30
degrees different. The third stage adds two shorter line segments to the
second stage line segments. And repeats it several times.</p>
<p>This repeating is programmed by recursive call. Two more examples are
shown here. They are Koch curve and Square Koch curve.</p>
<figure>
2023-01-05 13:35:42 +01:00
<img src="image/turtle_koch.png" alt="Koch curve" />
<figcaption aria-hidden="true">Koch curve</figcaption>
</figure>
<figure>
2023-01-05 13:35:42 +01:00
<img src="image/turtle_square_koch.png" alt="Square Koch curve" />
<figcaption aria-hidden="true">Square Koch curve</figcaption>
</figure>
<h2 id="tokens-and-punctuations">Tokens and punctuations</h2>
<p>The following is the list of tokens.</p>
<p>Keywords:</p>
<ul>
<li>pu: pen up</li>
<li>pd: pen down</li>
<li>pw: pen width = line width</li>
<li>fd: forward</li>
<li>tr: turn right</li>
2023-01-05 13:35:42 +01:00
<li>tl: turn left</li>
<li>bc: background color</li>
<li>fc: foreground color</li>
<li>if: if statement</li>
<li>rt: return</li>
<li>rs: reset</li>
2023-01-05 13:35:42 +01:00
<li>rp: repeat</li>
<li>dp: define procedure</li>
</ul>
<p>identifiers and numbers:</p>
<ul>
2023-01-05 13:35:42 +01:00
<li>identifier: This is used for the name of variables, parameters and
procedures. It is expressed <code>[a-zA-Z][a-zA-Z0-9]*</code> in regular
expression.</li>
<li>number: This is expressed <code>(0|[1-9][0-9]*)(\.[0-9]+)?</code> in
regular expression. It doesnt have <code>+</code> or <code>-</code>
sign because they bring some syntactic confusion. However negative
number such as <code>-10</code> can be recognized as unary minus and a
number.</li>
</ul>
<p>Symbols for expression</p>
<ul>
<li><code>=</code></li>
<li><code>&gt;</code></li>
<li><code>&lt;</code></li>
<li><code>+</code></li>
<li><code>-</code></li>
<li><code>*</code></li>
<li><code>/</code></li>
<li><code>(</code></li>
<li><code>)</code></li>
</ul>
<p>Delimiters</p>
<ul>
<li><code>(</code></li>
<li><code>)</code></li>
<li><code>{</code></li>
<li><code>}</code></li>
<li><code>,</code></li>
</ul>
<p>Comments and spaces:</p>
<ul>
2023-01-05 13:35:42 +01:00
<li>comment: This is characters between <code>#</code> and new line. If
a comment is at the end of the file, the trailing new line can be left
out.</li>
<li>white space:</li>
<li>horizontal tab: tab is recognized as eight spaces.</li>
<li>new line: This is the end of a line.</li>
</ul>
2023-01-05 13:35:42 +01:00
<p>These characters are used to separate tokens explicitly. They doesnt
have any syntactic meaning and are ignored by the parser.</p>
<h2 id="grammar">Grammar</h2>
<pre><code>program:
statement
| program statement
;
statement:
primary_procedure
| procedure_definition
;
primary_procedure:
2023-01-05 13:35:42 +01:00
pu
| pd
| pw expression
| fd expression
| tr expression
| tl expression
| bc &#39;(&#39; expression &#39;,&#39; expression &#39;,&#39; expression &#39;)&#39;
| fc &#39;(&#39; expression &#39;,&#39; expression &#39;,&#39; expression &#39;)&#39;
| ID &#39;=&#39; expression /* ID is an identifier which is a name of variable */
| if &#39;(&#39; expression &#39;)&#39; &#39;{&#39; primary_procedure_list &#39;}&#39;
| rt
| rs
| rp &#39;(&#39; expression &#39;)&#39; &#39;{&#39; primary_procedure_list &#39;}&#39;
| ID &#39;(&#39; &#39;)&#39; /* ID is an identifier which is a name of procedure */
| ID &#39;(&#39; argument_list &#39;)&#39; /* the same as above */
;
procedure_definition:
2023-01-05 13:35:42 +01:00
dp ID &#39;(&#39; &#39;)&#39; &#39;{&#39; primary_procedure_list &#39;}&#39;
| dp ID &#39;(&#39; parameter_list &#39;)&#39; &#39;{&#39; primary_procedure_list &#39;}&#39;
;
parameter_list:
ID
| parameter_list &#39;,&#39; ID
;
argument_list:
expression
| argument_list &#39;,&#39; expression
;
primary_procedure_list:
primary_procedure
| primary_procedure_list primary_procedure
;
expression:
expression &#39;=&#39; expression
| expression &#39;&gt;&#39; expression
| expression &#39;&lt;&#39; expression
| expression &#39;+&#39; expression
| expression &#39;-&#39; expression
| expression &#39;*&#39; expression
| expression &#39;/&#39; expression
| &#39;-&#39; expression %prec UMINUS
| &#39;(&#39; expression &#39;)&#39;
| ID
2023-01-05 13:35:42 +01:00
| NUM /* NUM is a number */
;</code></pre>
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>
</body>
</html>