@@ -2359,9 +2359,9 @@ class BlockNode : public AstNode {
23592359
23602360class TextNode : public AstNode {
23612361public:
2362- std::string content ;
2362+ size_t length ;
23632363
2364- explicit TextNode (nonstd::string_view content , size_t pos ): AstNode(pos), content(content ) { }
2364+ explicit TextNode (size_t pos , size_t length ): AstNode(pos), length(length ) { }
23652365
23662366 void accept (NodeVisitor& v) const {
23672367 v.visit (*this );
@@ -2393,14 +2393,19 @@ class JsonNode : public ExpressionNode {
23932393 std::string name;
23942394 std::string ptr {" " };
23952395
2396- explicit JsonNode (nonstd::string_view ptr_name, size_t pos) : ExpressionNode(pos), name( ptr_name) {
2397- // Convert dot notation to json pointer notation
2396+ static std::string convert_dot_to_json_ptr (nonstd::string_view ptr_name) {
2397+ std::string result;
23982398 do {
23992399 nonstd::string_view part;
24002400 std::tie (part, ptr_name) = string_view::split (ptr_name, ' .' );
2401- ptr .push_back (' /' );
2402- ptr .append (part.begin (), part.end ());
2401+ result .push_back (' /' );
2402+ result .append (part.begin (), part.end ());
24032403 } while (!ptr_name.empty ());
2404+ return result;
2405+ }
2406+
2407+ explicit JsonNode (nonstd::string_view ptr_name, size_t pos) : ExpressionNode(pos), name(ptr_name) {
2408+ ptr = convert_dot_to_json_ptr (ptr_name);
24042409 }
24052410
24062411 void accept (NodeVisitor& v) const {
@@ -2423,10 +2428,10 @@ class FunctionNode : public ExpressionNode {
24232428 Op operation;
24242429
24252430 std::string name;
2426- size_t number_args;
2431+ int number_args; // Should also be negative -> -1 for unknown number
24272432 CallbackFunction callback;
24282433
2429- explicit FunctionNode (nonstd::string_view name, size_t pos) : ExpressionNode(pos), precedence(5 ), associativity(Associativity::Left), operation(Op::Callback), name(name), number_args(1 ) { }
2434+ explicit FunctionNode (nonstd::string_view name, size_t pos) : ExpressionNode(pos), precedence(8 ), associativity(Associativity::Left), operation(Op::Callback), name(name), number_args(1 ) { }
24302435 explicit FunctionNode (Op operation, size_t pos) : ExpressionNode(pos), operation(operation), number_args(1 ) {
24312436 switch (operation) {
24322437 case Op::Not: {
@@ -2493,6 +2498,10 @@ class FunctionNode : public ExpressionNode {
24932498 precedence = 4 ;
24942499 associativity = Associativity::Left;
24952500 } break ;
2501+ case Op::AtId: {
2502+ precedence = 8 ;
2503+ associativity = Associativity::Left;
2504+ } break ;
24962505 default : {
24972506 precedence = 1 ;
24982507 associativity = Associativity::Left;
@@ -2909,7 +2918,6 @@ class Parser {
29092918 operation = FunctionStorage::Operation::Modulo;
29102919 } break ;
29112920 case Token::Kind::Dot: {
2912- std::cout << " test" << std::endl;
29132921 operation = FunctionStorage::Operation::AtId;
29142922 } break ;
29152923 default : {
@@ -3159,7 +3167,7 @@ class Parser {
31593167 }
31603168 } return ;
31613169 case Token::Kind::Text: {
3162- current_block->nodes .emplace_back (std::make_shared<TextNode>(tok.text , tok. text . data () - tmpl.content .c_str ()));
3170+ current_block->nodes .emplace_back (std::make_shared<TextNode>(tok.text . data () - tmpl.content .c_str (), tok. text . size ()));
31633171 } break ;
31643172 case Token::Kind::StatementOpen: {
31653173 get_next_token ();
@@ -3398,7 +3406,7 @@ class Renderer : public NodeVisitor {
33983406 }
33993407
34003408 void visit (const TextNode& node) {
3401- * output_stream << node.content ;
3409+ output_stream-> write (current_template-> content . c_str () + node.pos , node. length ) ;
34023410 }
34033411
34043412 void visit (const ExpressionNode&) { }
@@ -3550,7 +3558,7 @@ class Renderer : public NodeVisitor {
35503558 result_ptr = std::make_shared<json>(std::move (result));
35513559 json_tmp_stack.push_back (result_ptr);
35523560 } else {
3553- double result = std::pow (args[0 ]->get <int >(), args[1 ]->get <int >());
3561+ double result = std::pow (args[0 ]->get <double >(), args[1 ]->get <int >());
35543562 result_ptr = std::make_shared<json>(std::move (result));
35553563 json_tmp_stack.push_back (result_ptr);
35563564 }
@@ -3563,19 +3571,14 @@ class Renderer : public NodeVisitor {
35633571 json_eval_stack.push (result_ptr.get ());
35643572 } break ;
35653573 case Op::AtId: {
3566- std::cout << " test " << std::endl;
3574+ json_eval_stack. pop (); // Pop id nullptr
35673575 auto container = get_arguments<1 , false >(node)[0 ];
3568- auto id = get_arguments<1 , false >(node)[0 ];
3569- if (id == nullptr ) {
3570- auto id_node = not_found_stack.top ();
3571- not_found_stack.pop ();
3572-
3573- auto ptr = json::json_pointer (id_node->ptr );
3574- json_eval_stack.push (&container->at (ptr));
3575-
3576- } else {
3577- json_eval_stack.push (id);
3576+ if (not_found_stack.empty ()) {
3577+ throw_renderer_error (" could not find element with given name" , node);
35783578 }
3579+ auto id_node = not_found_stack.top ();
3580+ not_found_stack.pop ();
3581+ json_eval_stack.push (&container->at (id_node->name ));
35793582 } break ;
35803583 case Op::At: {
35813584 auto args = get_arguments<2 >(node);
@@ -3600,7 +3603,7 @@ class Renderer : public NodeVisitor {
36003603 } break ;
36013604 case Op::Exists: {
36023605 auto &&name = get_arguments<1 >(node)[0 ]->get_ref <const std::string &>();
3603- result_ptr = std::make_shared<json>(json_input->contains (json::json_pointer (JsonNode (name, 0 ). ptr )));
3606+ result_ptr = std::make_shared<json>(json_input->contains (json::json_pointer (JsonNode::convert_dot_to_json_ptr (name) )));
36043607 json_tmp_stack.push_back (result_ptr);
36053608 json_eval_stack.push (result_ptr.get ());
36063609 } break ;
0 commit comments