start working on a 'program mode'

a new syntax for simple scripting



git-svn-id: svn://ttmath.org/publicrep/ezc/trunk@1134 e52654a7-88a9-db11-a3e9-0013d4bc506e
This commit is contained in:
2018-10-29 23:50:10 +00:00
parent 54387e43bb
commit c825c85878
7 changed files with 366 additions and 27 deletions

View File

@@ -47,6 +47,7 @@
#include <sstream>
#include <fstream>
#include <vector>
#include "expressionparser.h"
namespace Ezc
@@ -111,6 +112,11 @@ public:
// true by default
void CanUseVars(bool can_use_variables);
void SetProgramMode(bool program_mode);
void SetExpressionParser(ExpressionParser * expression_parser);
// the main methods for generating
void Generate(StreamType & out);
void Generate(StreamType & out, OutStreams<StreamType> & out_streams);
@@ -209,6 +215,11 @@ private:
bool can_use_vars;
bool can_find_in_cache;
bool program_mode;
ExpressionParser * expression_parser;
void ResizeStreamStack(std::vector<StreamType*> & stream_tab, size_t stream_tab_max_size);
void ResizeFilterTab();
@@ -305,6 +316,8 @@ private:
void CreateUnknownMsg(const std::wstring & fun);
bool LimitAchieved();
void EvaluateProgramNode(Item & item);
void MakeTextIf_go(Item & item, bool result);
void MakeTextIf(Item & item);
void MakeTextFor(Item & item);
@@ -349,6 +362,7 @@ Generator<StreamType>::Generator() : empty_stream()
ezc_out_stack_size = 16;
can_find_in_cache = true;
can_use_vars = true;
expression_parser = nullptr;
}
@@ -381,6 +395,7 @@ Generator<StreamType> & Generator<StreamType>::operator=(const Generator<StreamT
stack_size = n.stack_size;
block_stack_size = n.block_stack_size;
ezc_out_stack_size = n.ezc_out_stack_size;
expression_parser = n.expression_parser;
// vars doesn't have to be copied
@@ -487,6 +502,18 @@ void Generator<StreamType>::CanUseVars(bool can_use_variables)
can_use_vars = can_use_variables;
}
template<class StreamType>
void Generator<StreamType>::SetProgramMode(bool set_program_mode)
{
this->program_mode = set_program_mode;
}
template<class StreamType>
void Generator<StreamType>::SetExpressionParser(ExpressionParser * expression_parser)
{
this->expression_parser = expression_parser;
}
@@ -1415,6 +1442,41 @@ void Generator<StreamType>::CreateUnknownMsg(const std::wstring & fun)
template<class StreamType>
void Generator<StreamType>::EvaluateProgramNode(Item & item)
{
if( output_stream )
{
if( item.type == Item::item_function )
*output_stream << " expression: " << item.text << "\n";
if( item.type == Item::item_if )
*output_stream << " if: " << item.text << "\n";
if( item.type == Item::item_for )
*output_stream << " for: " << item.text << "\n";
}
last_res = false;
if( expression_parser )
{
if( expression_parser->Parse(item.text) )
{
last_res = expression_parser->LastResultToBool();
}
else
{
if( output_stream )
{
*output_stream << " syntax error when evaluating expression\n";
}
}
}
}
template<class StreamType>
void Generator<StreamType>::MakeItemText(Item & item)
@@ -1448,14 +1510,21 @@ void Generator<StreamType>::MakeTextNormal(Item & item)
{
is_generating_normal = true;
if( output_stream )
if( program_mode )
{
Call(item.function, *output_stream, false, empty_stream);
EvaluateProgramNode(item);
}
else
{
Call(item.function, stream_temp1, false, empty_stream);
ClearStream(stream_temp1);
if( output_stream )
{
Call(item.function, *output_stream, false, empty_stream);
}
else
{
Call(item.function, stream_temp1, false, empty_stream);
ClearStream(stream_temp1);
}
}
}
@@ -1484,8 +1553,15 @@ void Generator<StreamType>::MakeTextIf(Item & item)
{
is_generating_if = true;
if( !Call(item.function) )
return;
if( program_mode )
{
EvaluateProgramNode(item);
}
else
{
if( !Call(item.function) )
return;
}
MakeTextIf_go(item, last_res);
}
@@ -1510,13 +1586,21 @@ void Generator<StreamType>::MakeTextFor(Item & item)
// is_generating_for will be changed by next call to MakeText()
// so we should set it in each iterations
is_generating_for = true;
Call(item.function, stream_temp1, true, empty_stream);
if( program_mode )
{
EvaluateProgramNode(item);
}
else
{
Call(item.function, stream_temp1, true, empty_stream);
}
if( !last_res )
break;
if( !item.item_tab.empty() )
MakeText( *item.item_tab[0] ); // should be only one item - item_container
MakeText( *item.item_tab[0] ); // should be only one item
}
}