in reply to Re: Too difficult for me...
in thread Too difficult for me...

You wouldn't like my code....

My code doesn't need fixing... it needs replacing! the parser I have written implements the syntax and provides a working platform, but it is pre-alpha at best.

I just read the link you gave me and it seems similar, but the syntax I have is not quite the same as XML, as it has two extra types of tag delimiters ( ) and [ ]

I'm really shooting in the dark as to how to explain what I have, so please bear with my ignorance (not stupidity, at least I hope not).

perhaps if I gave you some more examples of the syntax itself you could understand what I am getting at... like I said the code I have which runs it ought to be deleted, and the hard drive it is stored upon melted down!

anyway...

Upon receiving a request, the existing system looks up a file in the appropriate folder called body.aXML (aXML is what I call it but I am aware that name is taken, another reason for a rethink)
listing of an example body.aXML <html> <head> <title><conf>site_title</conf></title> </head> <body> <use>main</use> </body> </html> listing of main.aXML <div id="comments"> <table> (sql mode="mask") <query> SELECT * FROM comments; </query> <mask> <tr> <td><d>comment</d></td> <td>[link action="showuser" userid="<d>userid</d>" ]<d>username</d>[/link]</td> <td><d>timestamp</d></td> </tr> </mask> (/sql) </table> </div>
In most cases the body.aXML just contains a use tag which calls up a template, which then calls main.aXML but for simplicity I didn't bother putting that detail into the example. The example gives an output of comments from the SQL database, the system itself takes care of connecting to the database etc, leaving the designer free to simply plug together the existing modules using the simple syntax... this massively streamlines the development of new systems, as the modules are reusable and can be stacked together in multiple different abstract ways. for another example, here is a version of main.aXML which takes a query data argument telling it how many results to show;
<div id="comments"> <table> (sql mode="mask") <query> SELECT * FROM comments LIMIT (qd)limit(/qd); </query> <mask> <tr> <td><d>comment</d></td> <td>[link action="showuser" userid="<d>userid</d>" ]<d>username</d>[/link]</td> <td><d>timestamp</d></td> </tr> </mask> (/sql) </table> </div>
Where (qd)limit(/qd) would refer to a value passed in the query data key => value hash, under the key named "limit".

Replies are listed 'Best First'.
Re^3: Too difficult for me...
by Corion (Patriarch) on Jun 19, 2011 at 09:30 UTC

    I can only recommend to you to write a compiler that takes your input language and outputs (for example) Perl:

    <div id="comments"> <table> (sql mode="mask") <query> SELECT * FROM comments LIMIT (qd)limit(/qd); </query> <mask> <tr> <td><d>comment</d></td> <td>[link action="showuser" userid="<d>userid</d>" ]<d>username</d>[/link]</td> <td><d>timestamp</d></td> </tr> </mask> (/sql) </table> </div>
    ... could become
    my $output; $output .= <<HTML; <div id="comments"> <table> HTML my $limit = get_qd('limit'); # whatever "qd" is supposed to be my $results = fetch_sql( mode => "mask", query => <<SQL); SELECT * FROM comments LIMIT (qd)limit(/qd); SQL for my $row (@$results) { $output .= <<HTML; <mask> <tr> <td> HTML $output .= $row->{comment}; $output .= <<HTML; </td> <td> HTML $output .= link( action => 'showuser', userid => $row->{userid}, text +=> <<HTML ); $row->{username} HTML $output .= <<HTML; </td> <td> HTML $output .= $row->{timestamp}; $output .= <<HTML; </td> </tr> </mask> HTML }; # (/sql) $output .= <<HTML </table> </div> HTML

    This is basically the same technique that Template uses. The remaining infrastructure of including parts of pages from other code reminds me of HTML::Mason. I think you could learn lots from looking at the respective implementations. The Everything Engine (which this site runs on) is also fairly similar, except that it doesn't try to encode database queries as HTML - it leaves plain Perl for that. Subroutine calls can be encoded as special tags, but I'm not sure that this is an overall good idea.

    Note that I'm no friend of large frameworks, because they usually work for nobody other than the author(s).

      Well in effect the engine I have already scans and converts the code to perl for execution... it's just too slow because my methods are not as advanced as they could be... in all honesty I don't think I as a programmer am worthy of the discovery I am hamfistedly trying to describe and implement.

      The system is not a large framework at all, infact the core engine is less than 67KB, with about another 70KB of plugins which includes everything from input validation to database and file i/o, session management, and a whole bunch of other stuff.

      As far as I am aware, mason is 477KB just for the core engine, and catalyst 248KB.

      To answer the hidden question above, qd is a plugin which provides access to a hash containing GET and POST data.

      The source of the qd plugin is a one liner;

      $result = $qd->{$data};
      Using the rules of this syntax, consider a request something like;

      action.pl?action=test&a=b&b=c&c=42
      This is a silly example I know, but I can't think of any other way to express the nature of the system.

      listing of /actions/test/body.aXML ---------------------------------- <qd><qd><qd>a</qd></qd></qd>
      Output : 42

      The computation starts with;

      0: <qd><qd><qd>a</qd></qd></qd>
      the innermost qd tag runs, and in the query we find that  $qd->{'a'} = 'b'; the result 'b' is then handed off to the next tag in the expression
      1: <qd><qd>b</qd></qd>
      once again the plugin qd is called, only this time it is fed the result of the previous call, which was the letter 'b'. If we look up the key 'b' in the query data, we get the letter 'c'.

      the structure of the expression causes it to iterate one more time :
      2 : <qd>c</qd>
      and since in the query c = 42, the result of the expression

      <qd><qd><qd>a</qd></qd></qd>
      is 42.

      The system supports unlimited levels of nesting, using any combination of the existing plugins and is extensible by writing new plugins and either adding them to the core plugins folder, the site local plugins folder, or the action local plugin folder.

      lets say you wanted to write a silly plugin to say hello...
      listing of "/plugins/sayhello.aXMLpi" ------------------------------------- $result = "hello $data monks";
      now if that plugin is placed in the core plugins folder, any page on any site on the server can use the tag,
      <sayhello>perl</sayhello>
      and the page will contain the result "hello perl monks".

      <sayhello>java</sayhello>
      will produce "hello java monks"... etc etc.

      if our query data contains a key value pair 'who' => 'PERL' and we include into the document; <sayhello><qd>who</qd></sayhello>
      we get "hello PERL monks".

      You all think I'm barking mad don't you??
        Well in effect the engine I have already scans and converts the code to perl for execution... it's just too slow because my methods are not as advanced as they could be...

        Maybe you could start by showing a short, self-contained piece of your tagged text and the Perl code that gets created for it? Also maybe tell us whether that code is compiled every time, or whether it is cached and how.

        How do you expect us to come up with more than general handwaving suggestions if you don't show any code and only tell us about your framework as a black box?

        Oh and another couple of things quickly; the <perl> tag allows for embedding perl into the aXML docs, and another pair of really useful tags I have are the
        <loggedin> markup to show if the user is logged in </loggedin> <notloggedin> markup to show if the user is not logged in</notlogged +in> as with all the tags, nesting allows building of complexity such that <loggedin>[use]somefile[/use]</loggedin> loads up "somefile" if the user is logged in. you can also do it another way <use>somefile<notloggedin>guest</notloggedin></use> where the string "somefileguest" is the result when the user is not logged in, and "somefile" is the result if they are. the code for the loggedin / notlogged in tags is again very simple; listing "/plugins/loggedin.aXMLpi" ---------------------------------- if ($userdata->{'loggedin'}) { $result = $data; } listing "/plugins/notloggedin.aXMLpi" ------------------------------------- unless ($userdata->{'loggedin'}) { $result = $data; }
Re^3: Too difficult for me...
by simonodell (Acolyte) on Jun 19, 2011 at 07:52 UTC
    With a more efficient rendering program, it would be possible to add in extra levels of abstraction to quickly and easily implement things such as a database abstraction layer. I could go into that in more detail but I don't want to over do it before the simplicity of the ruleset and structure becomes apparent.
      Just had an idea.... later on I will make a short video presentation using screen capture, and hopefully seeing the thing in dynamic action will clarify it better than writing a wall of text!

      (side note...is it possible to embed a youtube video onto this forum?)

        It's not possible, nor is it wanted, to embed images or videos here.

        My advice for you is to sit back and structure your presentation. If you feel that you can better "show than tell", please really do think about whether your "show" consists of the same thing you would have written. If you feel that the big structure can only be shown in a screen cast, think about how you could reduce the big structure to some simple example that shows the same concepts except in smaller text. For example, instead of generating and outputting HTML, you could generate and output plain text. This reduces the size of the templates and the cognitive load for the reader who then clearly sees what is text and what is tagged control structure.

        You should also find out what your actual goal is with your system. If you want to attract more users and/or developers, you will need to write good documentation so that your system becomes usable for people not familiar with it already. You will also need to compare and show where (and how) your system is better than existing and established systems.

        If you "just" want to make your system better (faster, less fragile, more extensible), you will have to give us more to work with than just the 10,000 ft. explanations of how things work, and also in what dimension you seek improvement. I can imagine at least three ways to implement the interpreter/compiler for your language, but without knowing what way you chose, I can't give any concrete advice other than general points.