website 8c4db6c44aea81818370f73283a9a8233be506e0

0 views
Skip to first unread message

letha...@gmail.com

unread,
May 21, 2009, 5:25:42 PM5/21/09
to syx-c...@googlegroups.com
Branch: website
commit 8c4db6c44aea81818370f73283a9a8233be506e0
Author: Luca Bruno <letha...@gmail.com>
Date: Tue Jan 27 16:20:39 2009 +0100

Added lua to syx example

:100644 100644 e4e5f6c... b307eb6... M .gitignore
:100644 100644 59ac320... 7d4ef8b... M css/site.css
:100644 100644 3a442f1... d0d96b8... M wml/Makefile
:100644 100644 b74b426... 7759014... M wml/doc/examples.wml
:000000 100644 0000000... c73dd23... A wml/doc/examples/embedding/lua.wml
:100644 100644 2452a72... f4fafbe... M wml/doc/syntax.inc

diff --git a/.gitignore b/.gitignore
index e4e5f6c..b307eb6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,2 @@
-*~
\ No newline at end of file
+*~
+*.html
\ No newline at end of file
diff --git a/css/site.css b/css/site.css
index 59ac320..7d4ef8b 100644
--- a/css/site.css
+++ b/css/site.css
@@ -24,6 +24,10 @@ code {
margin: 0.5em 0 0.5em 1em;
}

+em.icode {
+ color: darkred;
+}
+
table {
width: 100%;
}
diff --git a/wml/Makefile b/wml/Makefile
index 3a442f1..d0d96b8 100644
--- a/wml/Makefile
+++ b/wml/Makefile
@@ -6,8 +6,8 @@ DOCINCS=$(wildcard doc/*.inc)
CCDOC=$(CC) $(patsubst %,-i%,$(DOCINCS))
EXINCS=$(wildcard doc/examples/*.inc)
CCEX=$(CCDOC) $(patsubst %,-i%,$(EXINCS))
-SRCS=$(wildcard *.wml) $(wildcard doc/*.wml) $(wildcard doc/examples/basic/*.wml) $(wildcard doc/examples/console/*.wml)
-OBJDIRS=$(TOPDIR)/doc $(TOPDIR)/doc/examples/basic $(TOPDIR)/doc/examples/console
+SRCS=$(wildcard *.wml) $(wildcard doc/*.wml) $(wildcard doc/examples/basic/*.wml) $(wildcard doc/examples/console/*.wml) $(wildcard doc/examples/embedding/*.wml)
+OBJDIRS=$(TOPDIR)/doc $(TOPDIR)/doc/examples/basic $(TOPDIR)/doc/examples/console $(TOPDIR)/doc/examples/embedding
OBJS=$(patsubst %,$(TOPDIR)/%,$(SRCS:.wml=.html))
ARCHIVEDIR=$(subst .,_,$(LATEST))
ARCHIVESRCS=$(patsubst %,$(ARCHIVEDIR)/%,install.wml features.wml release-notes.wml)
@@ -17,20 +17,8 @@ all: $(OBJDIRS) $(OBJS) $(ARCHIVESRCS) $(TOPDIR)/$(ARCHIVEDIR) $(ARCHIVEOBJS)

# Directories creation

-$(TOPDIR)/doc:
- mkdir -p $(TOPDIR)/doc
-
-$(TOPDIR)/doc/examples/basic:
- mkdir -p $(TOPDIR)/doc/examples/basic
-
-$(TOPDIR)/doc/examples/example:
- mkdir -p $(TOPDIR)/doc/examples/example
-
-$(ARCHIVEDIR):
- mkdir -p $(ARCHIVEDIR)
-
-$(TOPDIR)/$(ARCHIVEDIR):
- mkdir -p $(TOPDIR)/$(ARCHIVEDIR)
+$(OBJDIRS) $(ARCHIVEDIR) $(TOPDIR)/$(ARCHIVEDIR):
+ mkdir -p $@

# Release archiving

@@ -50,6 +38,8 @@ $(TOPDIR)/%.html: %.wml $(INCS)

clean:
rm -f $(OBJS)
+ rmdir $(TOPDIR)/doc/examples/embedding
+ rmdir $(TOPDIR)/doc/examples/console
rmdir $(TOPDIR)/doc/examples/basic
rmdir $(TOPDIR)/doc/examples
rmdir $(TOPDIR)/doc
diff --git a/wml/doc/examples.wml b/wml/doc/examples.wml
index b74b426..7759014 100644
--- a/wml/doc/examples.wml
+++ b/wml/doc/examples.wml
@@ -18,7 +18,7 @@

<h3>Embedding</h3>
<p>
- Lua to Syx: Embedding a scripting language inside your C/C++ code. The original article related to Lua can be found here
+ Lua to Syx: <a href="$(ROOT)/doc/examples/embedding/lua.html">Embedding a scripting language inside your C/C++ code</a>. The original article related to Lua can be <a href="http://www.debian-administration.org/articles/264">found here</a>
</p>

<h3>Web</h3>
diff --git a/wml/doc/examples/embedding/lua.wml b/wml/doc/examples/embedding/lua.wml
new file mode 100644
index 0000000..c73dd23
--- /dev/null
+++ b/wml/doc/examples/embedding/lua.wml
@@ -0,0 +1,334 @@
+{#TITLE#:Lua to Syx:##}
+
+<items>
+ <item "Disclaimer">
+ <p>
+ First of all, this is a remake of the article <a href="http://www.debian-administration.org/articles/264"><em>Embedding a scripting language inside your C/C++ code</em></a> of the Lua programming language for Smalltalk YX.
+ </p>
+ <next "INTRODUCTION">
+ </item>
+
+ <item "Introduction">
+ <p>
+ <i>These examples can be found in the source distribution of Syx under the <strong>examples/embedding</strong> directory.</i>
+ </p>
+
+ <p>
+ Smalltalk is a well known programming language thanks to its pure object-oriented programming phylosophy and its powerful features such as the graphical environment and reflection. At all, many people don't know what are all the features that Smalltalk YX offers to developers. One of these is the easy embeddability into C/C++ applications.
+ </p>
+
+ <p>
+ There are many languages (such as Lua) with the main purpose to be used as scripting languages, but this is the first Smalltalk version you can use for both general and embedding purposes.
+ </p>
+
+ <p>
+ This article, briefly describes the main operations you can perform trough the C interface provided by Syx:
+ <ul>
+ <li>Initialise Syx</li>
+ <li>Call from C into a Syx script</li>
+ <li>Call from Syx into your C application</li>
+ </ul>
+ </p>
+
+ <next "INITIALISING SMALLTALK YX">
+ </item>
+
+ <item "Initialising Smalltalk YX">
+ <p>
+ The main thing to do before start scripting with Syx into your application, is initializing the entire interpreter engine:
+ <code>
+ <span style="color: #339933;">#include &lt;syx/syx.h&gt;</span><br />
+ <br />
+ <span style="color: #993333;">int</span> main <span style="color: #66cc66;">&#40;</span><span style="color: #993333;">int</span> argc, <span style="color: #993333;">char</span> <span style="color: #66cc66;">*</span>argv<span style="color: #66cc66;">&#91;</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span><br />
+ <span style="color: #66cc66;">&#123;</span><br />
+ &nbsp; <span style="color: #808080; font-style: italic;">/* initialize Syx */</span><br />
+ &nbsp; syx_init <span style="color: #66cc66;">&#40;</span>argc, argv, <span style="color: #000000; font-weight: bold;">NULL</span><span style="color: #66cc66;">&#41;</span>;<br />
+ &nbsp; <br />
+ &nbsp; <span style="color: #808080; font-style: italic;">/* load the default image */</span><br />
+ &nbsp; syx_memory_load_image <span style="color: #66cc66;">&#40;</span><span style="color: #000000; font-weight: bold;">NULL</span><span style="color: #66cc66;">&#41;</span>;<br />
+ &nbsp; <br />
+ &nbsp; <span style="color: #808080; font-style: italic;">/* cleanup Syx */</span><br />
+ &nbsp; syx_quit <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<br />
+ &nbsp; <br />
+ &nbsp; <span style="color: #b1b100;">return</span> <span style="color: #cc66cc;">0</span>;<br />
+ <span style="color: #66cc66;">&#125;</span>
+ </code>
+ </p>
+
+ <p>
+ Once you have saved this as init.c you can compile it by typeing:
+ <pre>
+ $ gcc -o init init.c -Wall -lsyx
+ </pre>
+ </p>
+
+ <p>
+ If you didn't get any errors, you should be able to execute the program and get no output from it:
+ <pre>
+ $ ./init
+ $
+ </pre>
+ </p>
+
+ <p>
+ The <f syx_init()> function prepares the external environment of Syx such as the root path and the image path. <f syx_memory_load_image()> loads the image at the given location: in this case we specified NULL which belongs to the default image path. Finally, <f syx_quit()> frees all the memory used by Syx without saving the image.
+ </p>
+
+ <next "CALLING FROM C INTO A SMALLTALK SCRIPT">
+ </item>
+
+ <item "Calling from C into a Smalltalk script">
+ <p>
+ Now it's time code more and know how C can interact with Syx. These two examples show the basic operations you can perform to reach the most common purposes for your application.
+ </p>
+
+ <p>
+ The first example will illustrate how to load a Smalltalk file, something like emulating the same behavior of <icode syx do-me.st/> from the command line.
+ </p>
+
+ <p>
+ The second example pass some arguments to a Smalltalk method in a way much closer to C.
+
+ Copy these lines of code in a file named <file do-me.st/>:
+ <code>
+ <span style="color: #7f0000;">'Start'</span> printNl<br />
+ <span style="color: #7f0000;">1</span> to: <span style="color: #00007f;"><span style="color: #7f0000;">10</span></span> do: <span style="">&#91;</span> :<span style="color: #00007f;">i</span> |<br />
+ &nbsp; &nbsp; i printNl <span style="">&#93;</span>.<br />
+ <span style="color: #7f0000;">'End'</span> printNl
+ </code>
+ </p>
+
+ <p>
+ Now create <file do-me.c/> file to load this file without scheduling the operation:
+ <code>
+ <span style="color: #339933;">#include &lt;syx/syx.h&gt;</span><br />
+ <br />
+ <span style="color: #993333;">int</span> main <span style="color: #66cc66;">&#40;</span><span style="color: #993333;">int</span> argc, <span style="color: #993333;">char</span> <span style="color: #66cc66;">*</span>argv<span style="color: #66cc66;">&#91;</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span><br />
+ <span style="color: #66cc66;">&#123;</span><br />
+ &nbsp; <span style="color: #808080; font-style: italic;">/* initialize Syx */</span><br />
+ &nbsp; syx_init <span style="color: #66cc66;">&#40;</span>argc, argv, <span style="color: #000000; font-weight: bold;">NULL</span><span style="color: #66cc66;">&#41;</span>;<br />
+ &nbsp; <br />
+ &nbsp; <span style="color: #808080; font-style: italic;">/* load the default image */</span><br />
+ &nbsp; syx_memory_load_image <span style="color: #66cc66;">&#40;</span><span style="color: #000000; font-weight: bold;">NULL</span><span style="color: #66cc66;">&#41;</span>;<br />
+ &nbsp; <br />
+ &nbsp; <span style="color: #808080; font-style: italic;">/* now file in our file in blocking mode, .i.e without scheduling the Process */</span><br />
+ &nbsp; syx_file_in_blocking <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;do-me.st&quot;</span><span style="color: #66cc66;">&#41;</span>;<br />
+ <br />
+ &nbsp; <span style="color: #808080; font-style: italic;">/* cleanup Syx */</span><br />
+ &nbsp; syx_quit <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<br />
+ &nbsp; <br />
+ &nbsp; <span style="color: #b1b100;">return</span> <span style="color: #cc66cc;">0</span>;<br />
+ <span style="color: #66cc66;">&#125;</span>
+ </code>
+ </p>
+
+ <p>
+ Now compile the program as showed in the previous example and run it. The output will be the same as doing <icode syx do-me.st> from the command line:
+ <pre>
+ $ gcc -o do-me do-me.c -lsyx -Wall
+ $ ./do-me
+ Start
+ 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+ 10
+ End
+ $
+ </pre>
+ </p>
+
+ <p>
+ Let's create a class named Sum and a simple method <f #with:and:/> that returns the result of adding two numbers. This is the <file add.st/> file:
+ <code>
+ <span style="color: #0000ff;">Object</span> subclass: <span style="color: #7f0000;">#Sum</span><br />
+ &nbsp; &nbsp; &nbsp; &nbsp;instanceVariableNames: <span style="color: #7f0000;">''</span><br />
+ &nbsp; &nbsp; &nbsp; &nbsp;classVariableNames: <span style="color: #7f0000;">''</span>!<br />
+ <br />
+ !<span style="color: #0000ff;">Sum</span> methodsFor: <span style="color: #7f0000;">'examples'</span>!<br />
+ <br />
+ with: <span style="color: #00007f;">firstNumber</span> and: <span style="color: #00007f;">secondNumber</span><br />
+ &nbsp; &nbsp; &nbsp; ^firstNumber + <span style="color: #00007f;">secondNumber</span><br />
+ ! !
+ </code>
+ </p>
+
+ <p>
+ I hope you have some knowledge of the Smalltalk interchange format, this cold syntax has been created to let the developer interchange Smalltalk code between different Smalltalk implementation and also to write code outside the Smalltalk environment.
+
+ Let's create a C interface called <file add.c/> and do the equivalent of <icode Sum new with: 3 and: 4/>:
+ <code>
+ <span style="color: #339933;">#include &lt;syx/syx.h&gt;</span><br />
+ <br />
+ <span style="color: #993333;">int</span> main <span style="color: #66cc66;">&#40;</span><span style="color: #993333;">int</span> argc, <span style="color: #993333;">char</span> <span style="color: #66cc66;">*</span>argv<span style="color: #66cc66;">&#91;</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span><br />
+ <span style="color: #66cc66;">&#123;</span><br />
+ &nbsp; SyxOop instance;<br />
+ &nbsp; SyxOop context;<br />
+ &nbsp; SyxOop process;<br />
+ &nbsp; SyxOop result;<br />
+ <br />
+ &nbsp; <span style="color: #808080; font-style: italic;">/* initialize Syx */</span><br />
+ &nbsp; syx_init <span style="color: #66cc66;">&#40;</span>argc, argv, <span style="color: #000000; font-weight: bold;">NULL</span><span style="color: #66cc66;">&#41;</span>;<br />
+ &nbsp; <br />
+ &nbsp; <span style="color: #808080; font-style: italic;">/* load the default image */</span><br />
+ &nbsp; syx_memory_load_image <span style="color: #66cc66;">&#40;</span><span style="color: #000000; font-weight: bold;">NULL</span><span style="color: #66cc66;">&#41;</span>;<br />
+ &nbsp; <br />
+ &nbsp; <span style="color: #808080; font-style: italic;">/* now file in class and method declarations from our ST file */</span><br />
+ &nbsp; syx_file_in_blocking <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;add.st&quot;</span><span style="color: #66cc66;">&#41;</span>;<br />
+ <br />
+ &nbsp; <span style="color: #808080; font-style: italic;">/* create a Sum instance */</span><br />
+ &nbsp; instance <span style="color: #66cc66;">=</span> syx_object_new <span style="color: #66cc66;">&#40;</span>syx_globals_at <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;Sum&quot;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>;<br />
+ &nbsp; <br />
+ &nbsp; <span style="color: #808080; font-style: italic;">/* create a Process */</span><br />
+ &nbsp; process <span style="color: #66cc66;">=</span> syx_process_new <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<br />
+ <br />
+ &nbsp; <span style="color: #808080; font-style: italic;">/* create a MethodContext which sends the #with:and: message */</span><br />
+ &nbsp; context <span style="color: #66cc66;">=</span> syx_send_message <span style="color: #66cc66;">&#40;</span>instance, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #808080; font-style: italic;">// the receiver</span><br />
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff0000;">&quot;with:and:&quot;</span>, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;">// the selector</span><br />
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #cc66cc;">2</span>, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;">// the number of arguments</span><br />
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; syx_small_integer_new <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">41</span><span style="color: #66cc66;">&#41;</span>, &nbsp; <span style="color: #808080; font-style: italic;">// first argument</span><br />
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; syx_small_integer_new <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">22</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>;<br />
+ <br />
+ &nbsp; <span style="color: #808080; font-style: italic;">/* enter the context in the created process */</span><br />
+ &nbsp; syx_interp_enter_context <span style="color: #66cc66;">&#40;</span>process, context<span style="color: #66cc66;">&#41;</span>;<br />
+ <br />
+ &nbsp; <span style="color: #808080; font-style: italic;">/* execute the process in blocking mode */</span><br />
+ &nbsp; syx_process_execute_blocking <span style="color: #66cc66;">&#40;</span>process<span style="color: #66cc66;">&#41;</span>;<br />
+ <br />
+ &nbsp; <span style="color: #808080; font-style: italic;">/* fetch the last returned object (an instance variable of Process) */</span><br />
+ &nbsp; result <span style="color: #66cc66;">=</span> SYX_PROCESS_RETURNED_OBJECT <span style="color: #66cc66;">&#40;</span>process<span style="color: #66cc66;">&#41;</span>;<br />
+ <br />
+ &nbsp; <span style="color: #000066;">printf</span> <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;The result is %d<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span>, SYX_SMALL_INTEGER <span style="color: #66cc66;">&#40;</span>result<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>;<br />
+ <br />
+ &nbsp; <span style="color: #808080; font-style: italic;">/* cleanup Syx */</span><br />
+ &nbsp; syx_quit <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<br />
+ &nbsp; <br />
+ &nbsp; <span style="color: #b1b100;">return</span> <span style="color: #cc66cc;">0</span>;<br />
+ <span style="color: #66cc66;">&#125;</span>
+ </code>
+ </p>
+
+ <p>
+ <i>Smalltalk YX uses its own scheduler with its own threads (called processes). Each method or block being executed runs respectively into a <c MethodContext> or <c BlockContext> inside a <c Process>. This is why we need that way of doing things, and the reason for which you can save the entire state of the interpreter in the image.</i>
+ </p>
+
+ <p>
+ Compile <file add.c/> in the usual way and you see the result:
+ <pre>
+ $ gcc -o add add.c -lsyx -Wall
+ $ ./add
+ The result of the sum is: 63
+ $
+ </pre>
+ </p>
+ <next "CALL FROM SYX INTO YOUR C APPLICATION">
+ </item>
+
+ <item "Call from Syx into your C application">
+ <p>
+ Smalltalk YX is also able to do the inverse thing as above very easily. There're several methods to call C from Smalltalk:
+ <ul>
+ <li>Use standard primitives, which are available into the interpreter for doing basic operations</li>
+ <li>Use a plugin </li>
+ </ul>
+ </p>
+
+ <p>
+ The second is what we need to extend Syx with external libraries. You can either create a method with a special syntax to boost up the call or use the general purpose method <f "Smalltalk>>#plugin:call:withArguments">. In this example, we'll use <f "Smalltalk>>#call:withArguments:"> to interface directly into the main program.
+ </p>
+
+ <p>
+ The <file average.st> file is the following:
+ <code>|<span style="color: #00007f;"> avgAndSum </span>|<br />
+ <span style="color: #00007f;">avgAndSum</span> <span style="color: #000066; font-weight:bold;">:=</span> <span style="color: #0000ff;">Smalltalk</span> cCall: <span style="color: #7f0000;">'average'</span> withArguments: <span style="color: #7f0000;">#<span style="">&#40;</span><span style="color: #00007f;"><span style="color: #7f0000;">10</span></span> <span style="color: #7f0000;">20</span> <span style="color: #7f0000;">30</span> <span style="color: #7f0000;">40</span> <span style="color: #7f0000;">50</span><span style="">&#41;</span></span>.<br />
+ <span style="">&#40;</span><span style="color: #7f0000;">'The average is '</span>, <span style="color: #00007f;">avgAndSum</span> first printString<span style="">&#41;</span> printNl.<br />
+ <span style="">&#40;</span><span style="color: #7f0000;">'The sum is '</span>, <span style="color: #00007f;">avgAndSum</span> second printString<span style="">&#41;</span> printNl
+ </code>
+ </p>
+
+ <p>And this is the <file average.c /> file containing the average function:
+ <code>
+ <span style="color: #339933;">#include &lt;syx/syx.h&gt;</span><br />
+ <br />
+ SYX_FUNC_PRIMITIVE<span style="color: #66cc66;">&#40;</span>average<span style="color: #66cc66;">&#41;</span><br />
+ <span style="color: #66cc66;">&#123;</span><br />
+ &nbsp; syx_int32 i;<br />
+ &nbsp; syx_int32 sum <span style="color: #66cc66;">=</span> <span style="color: #cc66cc;">0</span>;<br />
+ &nbsp; SyxOop oop;<br />
+ <br />
+ &nbsp; <span style="color: #808080; font-style: italic;">/* obtain the number of arguments that has been sent */</span><br />
+ &nbsp; syx_int32 args <span style="color: #66cc66;">=</span> es<span style="color: #66cc66;">-</span>&gt;message_arguments_count;<br />
+ <br />
+ &nbsp; <span style="color: #808080; font-style: italic;">/* create the array to hold both the average and the sum */</span><br />
+ &nbsp; SyxOop result <span style="color: #66cc66;">=</span> syx_array_new_size <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">2</span><span style="color: #66cc66;">&#41;</span>;<br />
+ <br />
+ &nbsp; <span style="color: #b1b100;">for</span> <span style="color: #66cc66;">&#40;</span>i<span style="color: #66cc66;">=</span><span style="color: #cc66cc;">0</span>; i &lt; args; i<span style="color: #66cc66;">++</span><span style="color: #66cc66;">&#41;</span><br />
+ &nbsp; &nbsp; <span style="color: #66cc66;">&#123;</span><br />
+ &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;">/* get the nth argument */</span><br />
+ &nbsp; &nbsp; &nbsp; oop <span style="color: #66cc66;">=</span> es<span style="color: #66cc66;">-</span>&gt;message_arguments<span style="color: #66cc66;">&#91;</span>i<span style="color: #66cc66;">&#93;</span>;<br />
+ &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;">/* assert the object is a SmallInteger */</span><br />
+ &nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">!</span>SYX_IS_SMALL_INTEGER <span style="color: #66cc66;">&#40;</span>oop<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><br />
+ &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#123;</span><br />
+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SYX_PRIM_FAIL;<br />
+ &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span><br />
+ <br />
+ &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;">/* get the integer value of the object and sum */</span><br />
+ &nbsp; &nbsp; &nbsp; sum <span style="color: #66cc66;">+=</span> SYX_SMALL_INTEGER <span style="color: #66cc66;">&#40;</span>oop<span style="color: #66cc66;">&#41;</span>;<br />
+ &nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span><br />
+ &nbsp; <br />
+ &nbsp; <span style="color: #808080; font-style: italic;">/* put into the array the two results */</span><br />
+ &nbsp; SYX_OBJECT_DATA<span style="color: #66cc66;">&#40;</span>result<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">=</span> syx_small_integer_new <span style="color: #66cc66;">&#40;</span>sum <span style="color: #66cc66;">/</span> args<span style="color: #66cc66;">&#41;</span>;<br />
+ &nbsp; SYX_OBJECT_DATA<span style="color: #66cc66;">&#40;</span>result<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#91;</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">=</span> syx_small_integer_new <span style="color: #66cc66;">&#40;</span>sum<span style="color: #66cc66;">&#41;</span>;<br />
+ &nbsp; <br />
+ &nbsp; SYX_PRIM_RETURN<span style="color: #66cc66;">&#40;</span>result<span style="color: #66cc66;">&#41;</span>;<br />
+ <span style="color: #66cc66;">&#125;</span><br />
+ <br />
+ <span style="color: #993333;">int</span> main <span style="color: #66cc66;">&#40;</span><span style="color: #993333;">int</span> argc, <span style="color: #993333;">char</span> <span style="color: #66cc66;">*</span>argv<span style="color: #66cc66;">&#91;</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span><br />
+ <span style="color: #66cc66;">&#123;</span><br />
+ &nbsp; <span style="color: #808080; font-style: italic;">/* initialize Syx */</span><br />
+ &nbsp; syx_init <span style="color: #66cc66;">&#40;</span>argc, argv, <span style="color: #000000; font-weight: bold;">NULL</span><span style="color: #66cc66;">&#41;</span>;<br />
+ &nbsp; <br />
+ &nbsp; <span style="color: #808080; font-style: italic;">/* load the default image */</span><br />
+ &nbsp; syx_memory_load_image <span style="color: #66cc66;">&#40;</span><span style="color: #000000; font-weight: bold;">NULL</span><span style="color: #66cc66;">&#41;</span>;<br />
+ &nbsp; <br />
+ &nbsp; <span style="color: #808080; font-style: italic;">/* now file in our file in blocking mode, .i.e without scheduling the Process */</span><br />
+ &nbsp; syx_file_in_blocking <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;average.st&quot;</span><span style="color: #66cc66;">&#41;</span>;<br />
+ <br />
+ &nbsp; <span style="color: #808080; font-style: italic;">/* cleanup Syx */</span><br />
+ &nbsp; syx_quit <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<br />
+ &nbsp; <br />
+ &nbsp; <span style="color: #b1b100;">return</span> <span style="color: #cc66cc;">0</span>;<br />
+ <span style="color: #66cc66;">&#125;</span>
+ </code>
+ </p>
+
+ <p>
+ SYX_FUNC_PRIMITIVE is a macro to create a primitive function for Syx. We use a macro to mantain code compatibility for future versions. The <icode es> veriable is an argument of the average function, automatically defined by the macro. This variable contains all the state of the interpreter, exactly it's the <c SyxExecState> structure. Notice how the interface is pretty simple and easy to understand.
+ </p>
+
+ <p>
+ Smalltalk doesn't support multiple return values, so we need to put both the average and the sum into an array. The macro SYX_PRIM_FAIL exits from the primitive and enters a Syx method that either raises an exception or perform operations similar to the primitive that fails to emulate the same behavior in Smalltalk itself.
+ </p>
+
+ <p>
+ Compile this with the <icode -rdynamic> option to allow the dynamic loader to lookup the average function (it's not needed on Windows):
+ <pre>
+ $ gcc -o average average.c -lsyx -Wall -rdynamic
+ $ ./average
+ The average is 30
+ The sum is 150
+ $
+ </pre>
+ </p>
+
+ <p>
+ This is basically what Syx currently offers when embedded, and will be surely improved in the future.
+ </p>
+ <top>
+ </item>
+</items>
diff --git a/wml/doc/syntax.inc b/wml/doc/syntax.inc
index 2452a72..f4fafbe 100644
--- a/wml/doc/syntax.inc
+++ b/wml/doc/syntax.inc
@@ -1,6 +1,6 @@
# Classes
-m4_define(_Transcript, <em>Transcript</em>)
-m4_define(_TextCollector, <em>TextCollector</em>)
+m4_define(_Transcript, <c Transcript>)
+m4_define(_TextCollector, <c TextCollector>)

# Methods
m4_define(_printNl, <em>printNl</em>)
@@ -13,4 +13,24 @@ m4_define(_printNl, <em>printNl</em>)
# String
<define-tag s>
<b>'%attributes'</b>
+</define-tag>
+
+# Function
+<define-tag f>
+ <em>%attributes</em>
+</define-tag>
+
+# Class
+<define-tag c>
+ <em>%attributes</em>
+</define-tag>
+
+# Inline code
+<define-tag icode>
+ <em class="icode">%attributes</em>
+</define-tag>
+
+# Filenames
+<define-tag file>
+ <b><em>%attributes</em></b>
</define-tag>
\ No newline at end of file

Reply all
Reply to author
Forward
0 new messages