Compare commits
1 Commits
Author | SHA1 | Date | |
---|---|---|---|
03b5c3d5a5
|
110
src/generator.h
110
src/generator.h
@@ -36,8 +36,8 @@
|
||||
#ifndef headerfile_ezc_generator
|
||||
#define headerfile_ezc_generator
|
||||
|
||||
#include <sstream>
|
||||
#include <fstream>
|
||||
//#include <sstream>
|
||||
//#include <fstream>
|
||||
#include <vector>
|
||||
#include "blocks.h"
|
||||
#include "pattern.h"
|
||||
@@ -191,6 +191,15 @@ private:
|
||||
size_t block_stack_index;
|
||||
size_t block_stack_size;
|
||||
|
||||
struct ForIn
|
||||
{
|
||||
// one Var for each for-in
|
||||
std::vector<Var> args;
|
||||
};
|
||||
|
||||
typedef std::map<std::wstring, ForIn> ForInMap;
|
||||
std::map<std::wstring, ForIn> for_in_map;
|
||||
|
||||
// current output stream (can be null)
|
||||
// at the beginning it is pointing to the main stream (to the StreamType argument passsed to Generate method)
|
||||
StreamType * output_stream;
|
||||
@@ -298,12 +307,14 @@ private:
|
||||
|
||||
bool IsTestingFunctionExistence();
|
||||
|
||||
bool FindInForIn(Item::Function & item_fun, FindHelper & find_helper);
|
||||
|
||||
bool CheckBlockArgument(int arg_index, FindHelper & find_helper);
|
||||
|
||||
bool FindInCache(Item::Function & item_fun, FindHelper & find_helper);
|
||||
|
||||
#ifdef EZC_HAS_MORM_LIBRARY
|
||||
bool FindInModels(FindHelper & find_helper);
|
||||
bool FindInModels(const std::wstring & name, FindHelper & find_helper);
|
||||
#endif
|
||||
|
||||
bool FindInFunctionsAndBlocks(const std::wstring & name, FindHelper & find_helper);
|
||||
@@ -413,6 +424,7 @@ private:
|
||||
void MakeTextIfDef(Item & item);
|
||||
void MakeTextIfNotDef(Item & item);
|
||||
void MakeTextFor(Item & item);
|
||||
void MakeTextForIn(Item & item);
|
||||
void MakeItemText(Item & item);
|
||||
void MakeTextContainer(Item & item);
|
||||
void MakeTextFunction(Item & item);
|
||||
@@ -520,6 +532,7 @@ Generator<StreamType, is_pikotools_stream, is_autoescape_stream>::operator=(cons
|
||||
|
||||
// don't copy filter tab
|
||||
// don't copy stack
|
||||
// don't copy for_in_map
|
||||
// don't copy ezc_frame_stack_tab
|
||||
// don't copy output_stream and output_frames_streams
|
||||
|
||||
@@ -1010,6 +1023,45 @@ bool Generator<StreamType, is_pikotools_stream, is_autoescape_stream>::IsTesting
|
||||
}
|
||||
|
||||
|
||||
template<class StreamType, bool is_pikotools_stream, bool is_autoescape_stream>
|
||||
bool Generator<StreamType, is_pikotools_stream, is_autoescape_stream>::FindInForIn(Item::Function & item_fun, FindHelper & find_helper)
|
||||
{
|
||||
#ifdef EZC_HAS_MORM_LIBRARY
|
||||
|
||||
if( item_fun.parameters.size() != 1 )
|
||||
{
|
||||
CreateMsg(L"incorrect parameter for for-in statement GIVE ME a better error description");
|
||||
return false;
|
||||
}
|
||||
|
||||
typename ForInMap::iterator iterator = for_in_map.find(item_fun.name);
|
||||
|
||||
if( iterator != for_in_map.end() )
|
||||
{
|
||||
if( !iterator->second.args.empty() )
|
||||
{
|
||||
if( FindInModels(item_fun.parameters[0]->name, find_helper) )
|
||||
return true;
|
||||
|
||||
// if( !item_fun.fields.empty() && !IsTestingFunctionExistence() )
|
||||
// {
|
||||
// CreateMsg(L"unknown model", find_helper.fun_name->c_str());
|
||||
// return false;
|
||||
// }
|
||||
|
||||
CreateMsg(L"unknown model used in a for-in statement", find_helper.fun_name->c_str());
|
||||
|
||||
|
||||
//find_helper.variable = &(iterator->second.args.back());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
template<class StreamType, bool is_pikotools_stream, bool is_autoescape_stream>
|
||||
bool Generator<StreamType, is_pikotools_stream, is_autoescape_stream>::CheckBlockArgument(int arg_index, FindHelper & find_helper)
|
||||
{
|
||||
@@ -1066,11 +1118,11 @@ return false;
|
||||
#ifdef EZC_HAS_MORM_LIBRARY
|
||||
|
||||
template<class StreamType, bool is_pikotools_stream, bool is_autoescape_stream>
|
||||
bool Generator<StreamType, is_pikotools_stream, is_autoescape_stream>::FindInModels(FindHelper & find_helper)
|
||||
bool Generator<StreamType, is_pikotools_stream, is_autoescape_stream>::FindInModels(const std::wstring & name, FindHelper & find_helper)
|
||||
{
|
||||
if( pmodels )
|
||||
{
|
||||
morm::Wrapper * m = pmodels->Find(*find_helper.fun_name);
|
||||
morm::Wrapper * m = pmodels->Find(name);
|
||||
|
||||
if( m )
|
||||
{
|
||||
@@ -1151,11 +1203,14 @@ bool Generator<StreamType, is_pikotools_stream, is_autoescape_stream>::FindInVar
|
||||
template<class StreamType, bool is_pikotools_stream, bool is_autoescape_stream>
|
||||
bool Generator<StreamType, is_pikotools_stream, is_autoescape_stream>::Find(Item::Function & item_fun, FindHelper & find_helper)
|
||||
{
|
||||
if( FindInForIn(item_fun, find_helper) )
|
||||
return true;
|
||||
|
||||
if( CheckBlockArgument(item_fun.arg, find_helper) )
|
||||
return true;
|
||||
|
||||
#ifdef EZC_HAS_MORM_LIBRARY
|
||||
if( FindInModels(find_helper) )
|
||||
if( FindInModels(*find_helper.fun_name, find_helper) )
|
||||
return true;
|
||||
|
||||
if( !item_fun.fields.empty() && !IsTestingFunctionExistence() )
|
||||
@@ -2615,6 +2670,48 @@ void Generator<StreamType, is_pikotools_stream, is_autoescape_stream>::MakeTextF
|
||||
}
|
||||
|
||||
|
||||
template<class StreamType, bool is_pikotools_stream, bool is_autoescape_stream>
|
||||
void Generator<StreamType, is_pikotools_stream, is_autoescape_stream>::MakeTextForIn(Item & item)
|
||||
{
|
||||
stack_tab[stack_index-1].is_for = true;
|
||||
|
||||
//for_in_map
|
||||
|
||||
for( ; !break_generating ; stack_tab[stack_index-1].iter += 1 )
|
||||
{
|
||||
if( stack_tab[stack_index-1].iter >= max_for_items )
|
||||
{
|
||||
CreateMsg(item.function.name.c_str(),
|
||||
L"function exceeded a limit for a [for-in] statement");
|
||||
break;
|
||||
}
|
||||
|
||||
// IMPLEMENT ME
|
||||
|
||||
|
||||
// is_generating_for will be changed by next call to MakeText()
|
||||
// so we should set it in each iterations
|
||||
is_generating_for = true;
|
||||
|
||||
if( program_mode )
|
||||
{
|
||||
EvaluateProgramNode(item);
|
||||
}
|
||||
else
|
||||
{
|
||||
if( !Call(item.function, nullptr, stream_temp1, true, empty_stream) )
|
||||
return;
|
||||
}
|
||||
|
||||
if( !last_res )
|
||||
break;
|
||||
|
||||
if( !item.item_tab.empty() )
|
||||
MakeText( *item.item_tab[0] ); // should be only one item
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<class StreamType, bool is_pikotools_stream, bool is_autoescape_stream>
|
||||
void Generator<StreamType, is_pikotools_stream, is_autoescape_stream>::MakeTextDefine(Item & item, Var & var)
|
||||
{
|
||||
@@ -3005,6 +3102,7 @@ void Generator<StreamType, is_pikotools_stream, is_autoescape_stream>::MakeText(
|
||||
else if( item.type == Item::item_let ) MakeTextLet(item);
|
||||
else if( item.type == Item::item_let_if_not_set ) MakeTextLetIfNotSet(item);
|
||||
else if( item.type == Item::item_for ) MakeTextFor(item);
|
||||
else if( item.type == Item::item_for_in ) MakeTextForIn(item);
|
||||
else if( item.type == Item::item_filter ) MakeTextFilter(item);
|
||||
else if( item.type == Item::item_ezc ) MakeTextEzc(item);
|
||||
else if( item.type == Item::item_return ) MakeTextReturn(item);
|
||||
|
@@ -4,8 +4,8 @@
|
||||
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007-2021, Tomasz Sowa
|
||||
/*
|
||||
* Copyright (c) 2007-2024, Tomasz Sowa
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -51,7 +51,7 @@ struct Item
|
||||
enum Type
|
||||
{
|
||||
item_none, item_container, item_text, item_function, item_if, item_if_def, item_if_not_def,
|
||||
item_for, item_else, item_end, item_err, item_include, item_comment,
|
||||
item_for, item_for_in, item_else, item_end, item_err, item_include, item_comment,
|
||||
item_def, item_def_if_not_set, item_let, item_let_if_not_set,
|
||||
item_filter, item_ezc, item_block, item_return
|
||||
};
|
||||
|
@@ -4,8 +4,8 @@
|
||||
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007-2021, Tomasz Sowa
|
||||
/*
|
||||
* Copyright (c) 2007-2024, Tomasz Sowa
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -34,7 +34,8 @@
|
||||
|
||||
|
||||
#include "patternparser.h"
|
||||
#include "convert/convert.h"
|
||||
#include "convert/text.h"
|
||||
//#include "convert/convert.h"
|
||||
|
||||
|
||||
|
||||
@@ -793,6 +794,17 @@ void PatternParser::ReadDirectiveFor(Item & item)
|
||||
}
|
||||
|
||||
|
||||
void PatternParser::ReadDirectiveForIn(Item & item)
|
||||
{
|
||||
item.type = Item::item_for_in;
|
||||
|
||||
if( ReadFunction(item) )
|
||||
{
|
||||
if( item.function.parameters.size() != 1 )
|
||||
item.type = Item::item_err;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PatternParser::ReadDirectiveComment(Item & item)
|
||||
{
|
||||
@@ -1022,6 +1034,7 @@ std::wstring name;
|
||||
else if( name == L"end" ) ReadDirectiveEnd(item);
|
||||
else if( name == L"else" ) ReadDirectiveElse(item);
|
||||
else if( name == L"for" ) ReadDirectiveFor(item);
|
||||
else if( name == L"for-in" ) ReadDirectiveForIn(item);
|
||||
else if( name == L"include" ) ReadDirectiveInclude(item);
|
||||
else if( name == L"def" ) ReadDirectiveDef(item);
|
||||
else if( name == L"def?" ) ReadDirectiveDefIfNotSet(item);
|
||||
|
@@ -4,8 +4,8 @@
|
||||
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007-2021, Tomasz Sowa
|
||||
/*
|
||||
* Copyright (c) 2007-2024, Tomasz Sowa
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -178,6 +178,7 @@ private:
|
||||
void ReadDirectiveEnd(Item & item);
|
||||
void ReadDirectiveElse(Item & item);
|
||||
void ReadDirectiveFor(Item & item);
|
||||
void ReadDirectiveForIn(Item & item);
|
||||
void ReadDirectiveComment(Item & item);
|
||||
void ReadDirectiveInclude(Item & item);
|
||||
void ReadDirectiveDef(Item & item);
|
||||
|
Reference in New Issue
Block a user