<?xml version="1.0" encoding="UTF-8"?>

<rss version="2.0" xmlns:blogChannel="http://backend.userland.com/blogChannelModule">

<channel>
<title><![CDATA[Perl 6: SMOP sm0p Language]]></title>
<link>http://www.perlfoundation.org/perl6/index.cgi?smop_sm0p_language</link>
<description></description>
<pubDate>Thu, 17 Jul 2008 17:42:51 -0000</pubDate>
<webMaster>synedra@gmail.com</webMaster>
<generator>Socialtext Workspace v2.14.7.2</generator>

<item>
<title><![CDATA[SMOP sm0p Language]]></title>
<link>http://www.perlfoundation.org/perl6/index.cgi?smop_sm0p_language</link>
<description><![CDATA[<div class="wiki">
<h1 id="sm0p">sm0p</h1>
<h2 id="basic_structure">Basic Structure</h2>
<p>
sm0p has a simple structure of a finite set of nodes. Each node is represented by a statement, and no inner blocks are allowed. It is delimited by the q:sm0p { ... } construct, and must be used as the rvalue of a C assignement like: &quot;continuation = q:sm0p { ... }&quot;.<br />
Every symbol is replaced by its C counterpart, which means that they are resolved at &quot;definition time&quot;. On the other hand, the defined operations will only be executed later by the interpreter at &quot;runtime&quot;. As sm0p is really a macro language, there's no much sense in defining a &quot;compile time&quot;</p>
<h3 id="statement">Statement</h3>
<p>
Each statement is composed by three parts:</p>
<ol>
<li>Optional Label</li>
<li>Invocant / Responder</li>
<li>Identifier</li>
<li>Capture</li>
</ol>
<p>
And this three parts are always resolved at definition time, with the following rules:</p>
<ol>
<li>If they have a $ sigil, they should be resolved as local C variables.</li>
<li>Barewords are treated as constant identifiers, use q:identifier[infix:+] for non alphanumerics</li>
<li>SMOP__SLIME__Capturize.new(x,(a,b,c),(q,w,e),z) is translated directly to its lowlevel equivalent and usually appears as the argument to the move_capturize call</li>
<li>When there are mixed named and positional arguments, the named must be before (for parsing reasons)</li>
<li>Labels are defined to with label: in front of the node and refered to as `label (the translate to number representing the relative position of the labeled node</li>
</ol>
<p>
The messages are composed by:</p>
<ol>
<li>taking the responder interface of the invocant as the responder for the message.</li>
<li>translating the capture of the call to a native capture creation, using the invocant unless other invocant is defined.</li>
<li>taking the identifier as is.</li>
<li>When the capture have the prefix:&lt;|&gt; operator, the given object is set as the capture instead of composing a capture with the object</li>
</ol>
<h2 id="example">Example</h2>
<p>
The default implementation of the interpreter in SMOP now is pretty lame. The sm0p language is a macro language that will translate from a higher-level meaningfull language to a set of repetitive C calls that noone wants to write by hand. The exemple seems to be the better way to illustrate that.</p>
<pre>
// c code before here
continuation = q:sm0p {
   $current;
   $interpreter;
   $obj.DESTROYALL(|$obj);
   $SMOP__SLIME__CurrentFrame.move_capturize(
       SMOP__SLIME__Capturize.new(2,(3),(),3));
   $SMOP__SLIME__CurrentFrame.forget();
   $SMOP__SLIME__CurrentFrame.free(|$obj);
   $interpreter.goto()
};
// c code after here
</pre>
<br /><p>
This embedded code, that means:</p>
<pre>
continuation = Frame.new(
  Node.new(
    result =&gt; $current
  ),
  Node.new(
    result =&gt; $interpreter
  ),
  Node.new(
    responder =&gt; ___RI___($obj),
    identifier =&gt; DESTROYALL,
    capture =&gt; $obj,
  ),
  Node.new(
    responder =&gt; ___RI___(SMOP__STACK__CurrentFrame),
    identifier =&gt; move_capturize,
    capture =&gt; \( SMOP__STACK__OPCAPTURE_Move_Capturize.new(2,(3),(),3) ),
  ),
  Node.new(
    responder =&gt; ___RI___(SMOP__STACK__CurrentFrame),
    identifier =&gt; forget,
  ),
  Node.new(
    responder =&gt; ___RI___(SMOP__STACK__CurrentFrame),
    identifier =&gt; free,
    capture =&gt; $obj,
  ),
  Node.new(
    responder =&gt; ___RI___($interpreter),
    identifier =&gt; goto,
    capture =&gt; \( $interpreter: )
  )
);
</pre>
<br /><p>
Would be translated by a pre-processor to:</p>
<pre>
continuation = SMOP_DISPATCH
(NULL, SMOP__SLIME__Frame, SMOP__ID__new, 
 SMOP__NATIVE__capture_create
 (SMOP__SLIME__Frame,
  (SMOP__Object*[]){
    // $current;
    SMOP_DISPATCH
    (NULL, SMOP__SLIME__Node, SMOP__ID__new,
     SMOP__NATIVE__capture_create
     (SMOP__SLIME__Node, NULL,
      (SMOP__Object*[]){
        SMOP__ID__result,
        current
      })),
    // $interpreter;
    SMOP_DISPATCH
    (NULL, SMOP__SLIME__Node, SMOP__ID__new,
     SMOP__NATIVE__capture_create
     (SMOP__SLIME__Node, NULL,
      (SMOP__Object*[]){
        SMOP__ID__result,
        interpreter
      })),
    // $obj.DESTROYALL(|$obj);
    SMOP_DISPATCH
    (NULL, SMOP__SLIME__Node, SMOP__ID__new,
     SMOP__NATIVE__capture_create
     (SMOP__SLIME__Node, NULL,
      (SMOP__Object*[]){
        SMOP__ID__responder,
        SMOP_RI(obj),
        SMOP__ID__identifier,
        SMOP__ID__DESTROYALL,
        SMOP__ID__capture,
        obj
      })),
    // SMOP__SLIME__CurrentFrame.move_capturize(
    //    SMOP__SLIME__Capturize.new(2,(3),(),3));
    SMOP_DISPATCH
    (NULL, SMOP__SLIME__Node, SMOP__ID__new,
     SMOP__NATIVE__capture_create
     (SMOP__SLIME__Node, NULL,
      (SMOP__Object*[]){
        SMOP__ID__responder,
        SMOP_RI(SMOP__SLIME__CurrentFrame),
        SMOP__ID__identifier,
        SMOP__ID__move_capturize,
        SMOP__ID__capture,
        SMOP__NATIVE__capture_create(SMOP__SLIME__CurrentFrame, SMOP__SLIME__Capturize_create(2,(int[]){3,0}, NULL, 3));
      })),
    // SMOP__SLIME__CurrentFrame.forget();
    SMOP_DISPATCH
    (NULL, SMOP__SLIME__Node, SMOP__ID__new,
     SMOP__NATIVE__capture_create
     (SMOP__SLIME__Node, NULL,
      (SMOP__Object*[]){
        SMOP__ID__responder,
        SMOP_RI(SMOP__SLIME__CurrentFrame),
        SMOP__ID__identifier,
        SMOP__ID__forget
      })),
    // SMOP__SLIME__Operators.free(|$obj);
    SMOP_DISPATCH
    (NULL, SMOP__SLIME__Node, SMOP__ID__new,
     SMOP__NATIVE__capture_create
     (SMOP__SLIME__Node, NULL,
      (SMOP__Object*[]){
        SMOP__ID__responder,
        SMOP_RI(SMOP__SLIME__Operators),
        SMOP__ID__identifier,
        SMOP__ID__free,
        SMOP__ID__capture,
        SMOP__NATIVE__capture_create(obj, NULL, NULL)
      })),
    // ___INTERPRETER___.goto()
    SMOP_DISPATCH
    (NULL, SMOP__SLIME__Node, SMOP__ID__new,
     SMOP__NATIVE__capture_create
     (SMOP__SLIME__Node, NULL,
      (SMOP__Object*[]){
        SMOP__ID__responder,
        SMOP_RI(___INTERPRETER___),
        SMOP__ID__identifier,
        SMOP__ID__goto
      })),
  })); 
  
</pre>
</div>
]]></description>
<author>pawelmurias@hidden</author>
<guid isPermaLink="true">http://www.perlfoundation.org/perl6/index.cgi?smop_sm0p_language</guid>
<pubDate>Thu, 17 Jul 2008 17:42:51 -0000</pubDate>
</item>

</channel>
</rss>