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

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).

Replies are listed 'Best First'.
Re^4: Too difficult for me...
by simonodell (Acolyte) on Jun 19, 2011 at 12:05 UTC
    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?

        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? Well the thing is, having learnt what I have learnt about things like catalyst etc, even I can slag my own code off as being extremely naive, i'm not so much trying to get people to fix my code, as to present the syntax I wrote it to work with, in the hope that if someone can grasp the nature of the syntax itself (and why it rocks) they will realise why I either need help with it or I'm going to spend the next 3-5 years of my life hacking away at it alone in the dark.

        here is a rough pseudo-code of what the parser does... please don't laugh too much!

        load plugins, build plugin hash table load appropriate body.aXML while ( commands_remain_unprocessed ) { for each plugin_name in plugins hash { scan using a regex for a corresponding tag making sure it does not contain any subtags if tag has been found that is ready to be computed { eval the code from the plugin file, passing it the data from inside the tag and any attribute values place the $result back into the document in the place of the original tag&data } } }
        My implemention is very naive! I'm sure that in a single scan/pass over the document it could be run/compiled whatever, however my version scans over the doc many times and the processing overhead grows rapidly with each extra tag / nesting level present (bad, very bad).

        Look... I didn't know that 0.04 seconds was a bad render time until recently, I thought I was doing quite well with it, the code I have is ROCK solid, the forum system I linked to earlier has been online for months without problems or resets and it runs on a box which cost $20 / month. If I used a 32 core processor dedicated box, I could just brute force process my performance problems out of the way, but I am trying to do two things by coming here with this:

        1) share what I have because I am sure people will like it when they get it

        2) garner support and insight in how to compile and process such a syntax in a more efficient manner than multi-passing regexes and evals, so that the solution will scale nicely to larger sizes without needing a server the size of jupiter.
      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; }