Public paste
avs
By: avs | Date: Feb 14 2010 17:07 | Format: None | Expires: never | Size: 5.77 KB | Hits: 1098

  1. // Avisynth v3.0 alpha.  Copyright 2005 David Pierre - Ben Rudiak-Gould et al.
  2. // http://www.avisynth.org
  3.  
  4. // This program is free software; you can redistribute it and/or modify
  5. // it under the terms of the GNU General Public License as published by
  6. // the Free Software Foundation; either version 2 of the License, or
  7. // (at your option) any later version.
  8. //
  9. // This program is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12. // GNU General Public License for more details.
  13. //
  14. // You should have received a copy of the GNU General Public License
  15. // along with this program; if not, write to the Free Software
  16. // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA, or visit
  17. // http://www.gnu.org/copyleft/gpl.html .
  18. //
  19. // Linking Avisynth statically or dynamically with other modules is making a
  20. // combined work based on Avisynth.  Thus, the terms and conditions of the GNU
  21. // General Public License cover the whole combination.
  22.  
  23.  
  24. //avisynth includes
  25. #include "statement.h"
  26. #include "../lazy/get.h"
  27. #include "../lazy/ref.h"
  28. #include "../lazy/tuple.h"
  29. #include "../action/check.h"
  30. #include "../action/action.h"
  31. #include "../functor/if.h"
  32. #include "../functor/while.h"
  33. #include "../functor/literal.h"
  34.  
  35. //spirit includes
  36. #include <boost/spirit/core.hpp>
  37. #include <boost/spirit/phoenix/statements.hpp>      //for operator,
  38.  
  39.  
  40. namespace avs { namespace parser { namespace grammar {
  41.  
  42.  
  43.  
  44. template <>
  45. Statement::definition<Scanner>::definition(Statement const & self)
  46. {
  47.  
  48.   using namespace lazy;
  49.   using namespace functor;
  50.   using namespace phoenix;
  51.  
  52.  
  53.   top
  54.       =   statement( CodeCouple(), self.localCtxt )
  55.           [
  56.             self.value = arg1
  57.           ]
  58.       ;
  59.  
  60.   statement
  61.       =   (   expression( value::Expression(), statement.localCtxt, self.globalCtxt )
  62.               [
  63.                 bind(&action::Action::ExprStatement)(statement.value, statement.localCtxt, arg1)
  64.               ]
  65.           |   createVar( ref_(first(statement.localCtxt)) )  //pass local VarTable
  66.           |   ifStatement
  67.           // |   whileStatement
  68.           |   returnStatement
  69.           )
  70.       >>  (   spirit::eol_p           //statement are normally ended by a newline
  71.           |   spirit::eps_p( '}' )    //but an end of block would do too
  72.           )
  73.       ;
  74.  
  75.   createVar
  76.       =   (   spirit::str_p("global")
  77.               [
  78.                 createVar.table = ref_(first(self.globalCtxt))    //set global VarTable as the table to use
  79.               ]
  80.           |   !   spirit::str_p("local")     //optional local keyword
  81.           )
  82.       >>  name
  83.           [
  84.             createVar.name = construct_<std::string>(arg1, arg2)
  85.           ]
  86.       >>  '='
  87.       >>  expression( value::Expression(), statement.localCtxt, self.globalCtxt )
  88.           [
  89.             bind(&action::Action::CreateVarStatement)
  90.                 (statement.value, statement.localCtxt, arg1, createVar.table, createVar.name)
  91.           ]
  92.       ;
  93.  
  94.   ifStatement
  95.       =   spirit::str_p("if")
  96.       >>  conditionBlock
  97.           [
  98.             statement.value += arg1
  99.           ]
  100.       >>  subContextBlock( CodeCouple(), get_(statement.localCtxt) )
  101.           [
  102.             ifStatement.value = arg1
  103.           ]
  104.       >>  (   *   spirit::eol_p
  105.           >>  spirit::str_p("else")
  106.           >>  subContextBlock( CodeCouple(), get_(statement.localCtxt) )
  107.               [
  108.                 statement.value -= construct_<functor::IfThenElse>(ifStatement.value, arg1)
  109.               ]
  110.           |   spirit::eps_p
  111.               [
  112.                 statement.value -= construct_<functor::IfThen>(ifStatement.value)
  113.               ]
  114.           )
  115.       ;
  116.  
  117.   whileStatement
  118.       =   spirit::str_p("while")
  119.       >>  conditionBlock
  120.           [
  121.             whileStatement.value = arg1
  122.           ]
  123.       >>  subContextBlock( CodeCouple(), get_(statement.localCtxt) )
  124.           [
  125.             statement.value -= construct_<functor::WhileDo>(whileStatement.value, arg1)
  126.           ]
  127.       ;
  128.  
  129.   conditionBlock
  130.       =   '('
  131.       >>  expression( value::Expression(), statement.localCtxt, self.globalCtxt )
  132.           [
  133.             bind(&action::Check::TypeIsExpected)(second(arg1), val('b')),
  134.             conditionBlock.value += first(arg1),
  135.             --second(statement.localCtxt)         //reports that the bool value is consumed
  136.           ]
  137.       >>  ')'
  138.       ;
  139.  
  140.   subContextBlock
  141.       =   spirit::eps_p
  142.           [    //get rid of last inherited from upper context
  143.             third(subContextBlock.localCtxt) = val( boost::none_t() )
  144.           ]
  145.       >>  *   spirit::eol_p   //skip newlines
  146.       >>  (   '{'
  147.           >> *(   statement( CodeCouple(), ref_(subContextBlock.localCtxt) )   //a block of statement delimited by { }
  148.                   [
  149.                     subContextBlock.value += arg1
  150.                   ]
  151.               |   spirit::eol_p
  152.               )
  153.           >>  '}'
  154.           |   statement( CodeCouple(), ref_(subContextBlock.localCtxt) )       //or a single one
  155.               [
  156.                 subContextBlock.value += arg1
  157.               ]
  158.           )
  159.       ;
  160.  
  161.   returnStatement
  162.       =   spirit::str_p("return")
  163.       >>  (   spirit::str_p("self")
  164.               [
  165.                 bind(&action::Check::TRecurseAllowed)(! self.termRecInfo)
  166.               ]
  167.           >>  argList( 0 )
  168.               [
  169.                 second(get_(self.termRecInfo)) = val(true),                //report that terminal recursivity is used
  170.                 statement.value -= construct_<literal<OpType> >(RECURSE)
  171.               ]
  172.           |   expression( value::Expression(), statement.localCtxt, self.globalCtxt )
  173.               [
  174.                 bind(&action::Check::ReturnTypeIsExpected)(second(arg1), self.returnTypeExpected),
  175.                 statement.value += first(arg1),
  176.                 statement.value -= construct_<literal<OpType> >(RETURN)
  177.               ]
  178.           )
  179.       ;
  180.  
  181.   argList
  182.       =   '('
  183.       >> !(   expression( value::Expression(), statement.localCtxt, self.globalCtxt )
  184.               [
  185.                 //check the type is the one expected by prototype of outer function
  186.                 bind(&action::Check::TypeIsExpected)(second(arg1), first(get_(self.termRecInfo))[argList.value]),
  187.                 statement.value += first(arg1),
  188.                 ++argList.value
  189.               ]
  190.           %   ','
  191.       )
  192.       >>  ')'
  193.       ;
  194.  
  195. }
  196.  
  197.  
  198.  
  199. } } } //namespace avs::parser::grammar