@@ -2359,9 +2359,9 @@ class BlockNode : public AstNode {
2359
2359
2360
2360
class TextNode : public AstNode {
2361
2361
public:
2362
- std::string content ;
2362
+ size_t length ;
2363
2363
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 ) { }
2365
2365
2366
2366
void accept (NodeVisitor& v) const {
2367
2367
v.visit (*this );
@@ -2393,14 +2393,19 @@ class JsonNode : public ExpressionNode {
2393
2393
std::string name;
2394
2394
std::string ptr {" " };
2395
2395
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;
2398
2398
do {
2399
2399
nonstd::string_view part;
2400
2400
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 ());
2403
2403
} 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);
2404
2409
}
2405
2410
2406
2411
void accept (NodeVisitor& v) const {
@@ -2423,10 +2428,10 @@ class FunctionNode : public ExpressionNode {
2423
2428
Op operation;
2424
2429
2425
2430
std::string name;
2426
- size_t number_args;
2431
+ int number_args; // Should also be negative -> -1 for unknown number
2427
2432
CallbackFunction callback;
2428
2433
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 ) { }
2430
2435
explicit FunctionNode (Op operation, size_t pos) : ExpressionNode(pos), operation(operation), number_args(1 ) {
2431
2436
switch (operation) {
2432
2437
case Op::Not: {
@@ -2493,6 +2498,10 @@ class FunctionNode : public ExpressionNode {
2493
2498
precedence = 4 ;
2494
2499
associativity = Associativity::Left;
2495
2500
} break ;
2501
+ case Op::AtId: {
2502
+ precedence = 8 ;
2503
+ associativity = Associativity::Left;
2504
+ } break ;
2496
2505
default : {
2497
2506
precedence = 1 ;
2498
2507
associativity = Associativity::Left;
@@ -2909,7 +2918,6 @@ class Parser {
2909
2918
operation = FunctionStorage::Operation::Modulo;
2910
2919
} break ;
2911
2920
case Token::Kind::Dot: {
2912
- std::cout << " test" << std::endl;
2913
2921
operation = FunctionStorage::Operation::AtId;
2914
2922
} break ;
2915
2923
default : {
@@ -3159,7 +3167,7 @@ class Parser {
3159
3167
}
3160
3168
} return ;
3161
3169
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 ()));
3163
3171
} break ;
3164
3172
case Token::Kind::StatementOpen: {
3165
3173
get_next_token ();
@@ -3398,7 +3406,7 @@ class Renderer : public NodeVisitor {
3398
3406
}
3399
3407
3400
3408
void visit (const TextNode& node) {
3401
- * output_stream << node.content ;
3409
+ output_stream-> write (current_template-> content . c_str () + node.pos , node. length ) ;
3402
3410
}
3403
3411
3404
3412
void visit (const ExpressionNode&) { }
@@ -3550,7 +3558,7 @@ class Renderer : public NodeVisitor {
3550
3558
result_ptr = std::make_shared<json>(std::move (result));
3551
3559
json_tmp_stack.push_back (result_ptr);
3552
3560
} 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 >());
3554
3562
result_ptr = std::make_shared<json>(std::move (result));
3555
3563
json_tmp_stack.push_back (result_ptr);
3556
3564
}
@@ -3563,19 +3571,14 @@ class Renderer : public NodeVisitor {
3563
3571
json_eval_stack.push (result_ptr.get ());
3564
3572
} break ;
3565
3573
case Op::AtId: {
3566
- std::cout << " test " << std::endl;
3574
+ json_eval_stack. pop (); // Pop id nullptr
3567
3575
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);
3578
3578
}
3579
+ auto id_node = not_found_stack.top ();
3580
+ not_found_stack.pop ();
3581
+ json_eval_stack.push (&container->at (id_node->name ));
3579
3582
} break ;
3580
3583
case Op::At: {
3581
3584
auto args = get_arguments<2 >(node);
@@ -3600,7 +3603,7 @@ class Renderer : public NodeVisitor {
3600
3603
} break ;
3601
3604
case Op::Exists: {
3602
3605
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) )));
3604
3607
json_tmp_stack.push_back (result_ptr);
3605
3608
json_eval_stack.push (result_ptr.get ());
3606
3609
} break ;
0 commit comments