├── COPYING ├── README.md ├── examples ├── basics.jtc └── derivatives.jtc └── jtc.cpp /COPYING: -------------------------------------------------------------------------------- 1 | Copyright (c) 2013 Jakob Progsch 2 | 3 | This software is provided 'as-is', without any express or implied 4 | warranty. In no event will the authors be held liable for any damages 5 | arising from the use of this software. 6 | 7 | Permission is granted to anyone to use this software for any purpose, 8 | including commercial applications, and to alter it and redistribute it 9 | freely, subject to the following restrictions: 10 | 11 | 1. The origin of this software must not be misrepresented; you must not 12 | claim that you wrote the original software. If you use this software 13 | in a product, an acknowledgment in the product documentation would be 14 | appreciated but is not required. 15 | 16 | 2. Altered source versions must be plainly marked as such, and must not be 17 | misrepresented as being the original software. 18 | 19 | 3. This notice may not be removed or altered from any source 20 | distribution. 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # jtc 2 | 3 | A toy programming language interpreter 4 | 5 | ## building 6 | 7 | the jtc interpreter has no dependencies and sits in a single C++ file. 8 | C++11 capable compilers should compile it without extra options other 9 | than enabling C++11. 10 | 11 | example: `g++ -o jtc jtc.cpp -std=c++0x -O3` 12 | -------------------------------------------------------------------------------- /examples/basics.jtc: -------------------------------------------------------------------------------- 1 | // examples of the basic syntax 2 | 3 | pi = 3.14159 // numbers are always doubles 4 | 5 | greeting = "Hello World!" // string 6 | 7 | square = function(x) { // functions are first class citizens 8 | return x*x 9 | } 10 | 11 | arr = [pi greeting nil] // array types 12 | arr[2] = square //replace the nil element (indices start at 0) 13 | arr += [23] // append 14 | length = size(arr) // use the size operator to find an arrays length 15 | 16 | // tables are associative containers that can use any object as key 17 | table = { 18 | "pi" = 3.14159 19 | 23 = "twenty three" 20 | "bar" = square 21 | } 22 | table.e = 2.71 // equivalent to table["e"] = 2.71 23 | table.bar = function() { print(this.e, "\n") } 24 | table.bar() 25 | 26 | // flow control uses C style 27 | if(pi > 2) { 28 | print("pi is greater than 2\n") 29 | } else { 30 | print("pi is less or equal 2\n") 31 | } 32 | 33 | x = 2 34 | while(x < 1024) { 35 | print(x = square(x) ", ") 36 | } 37 | print("\n") 38 | 39 | //no ++ or -- operators 40 | for(i = 0;i 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | // utility 14 | 15 | template 16 | bool isint(T x) { 17 | return x == std::trunc(x); 18 | } 19 | 20 | std::string unescape(const std::string &str) { 21 | std::string result; 22 | for(auto i = str.begin();i!=str.end();++i) { 23 | if(*i == '\\') { 24 | switch(*(++i)) { 25 | case 'a': result += '\a'; break; 26 | case 'b': result += '\b'; break; 27 | case 'f': result += '\f'; break; 28 | case 'n': result += '\n'; break; 29 | case 'r': result += '\r'; break; 30 | case 't': result += '\t'; break; 31 | case 'v': result += '\v'; break; 32 | case '\'': result += '\''; break; 33 | case '\"': result += '\"'; break; 34 | } 35 | } else { 36 | result += *i; 37 | } 38 | } 39 | return result; 40 | } 41 | 42 | enum TokenType { 43 | NUMBER, IDENTIFIER, STRING, LEFT_PAREN, RIGHT_PAREN, LEFT_BRACKET, 44 | RIGHT_BRACKET, LEFT_BRACE, RIGHT_BRACE, PLUS, DASH, STAR, PERCENT, 45 | SLASH, PLUS_EQUAL, DASH_EQUAL, STAR_EQUAL, PERCENT_EQUAL, 46 | SLASH_EQUAL,NOT, COMMA, SEMICOLON, DOT, COLON, EQUAL, EQ_OP, 47 | NOT_EQUAL, GREATER, GREATER_EQUAL, LESS, LESS_EQUAL, LOGICAL_AND, 48 | LOGICAL_OR, IF, ELSE, WHILE, FOR, RETURN, BREAK, CONTINUE, FUNCTION, 49 | EXPRESSION, STATEMENT, ROOT, NIL, EVAL, PARSE_STATEMENT, 50 | PARSE_EXPRESSION, GLOBAL, LOCAL, PRINT, TYPE, SIZE 51 | }; 52 | 53 | const std::unordered_map keywords = { 54 | {"if", IF}, {"else", ELSE}, {"while", WHILE}, {"for", FOR}, 55 | {"return", RETURN}, {"break", BREAK}, {"continue", CONTINUE}, 56 | {"function", FUNCTION}, {"nil", NIL}, {"expression", EXPRESSION}, 57 | {"statement", STATEMENT}, {"eval", EVAL}, 58 | {"parse_statement", PARSE_STATEMENT}, 59 | {"parse_expression", PARSE_EXPRESSION}, {"global", GLOBAL}, 60 | {"local", LOCAL}, {"root", ROOT}, {"type", TYPE}, {"size", SIZE} 61 | }; 62 | 63 | template 64 | struct Token { 65 | Token(TokenType type_, Iter begin_, Iter end_) 66 | : type(type_), begin(begin_), end(end_) { } 67 | const TokenType type; 68 | const Iter begin, end; 69 | }; 70 | 71 | // helper to find line & column position on demand 72 | template 73 | std::pair line_column(Iter begin, Iter pos) { 74 | int line = 1, column = 0; 75 | for(Iter i = begin;i!=pos;++i) { 76 | if(*i == '\n'){ 77 | ++line; 78 | column = 0; 79 | } 80 | ++column; 81 | } 82 | return std::make_pair(line, column); 83 | } 84 | 85 | template 86 | std::shared_ptr>> tokenize(Iter begin, Iter end) 87 | { 88 | auto tokens_ptr = std::make_shared>>(); 89 | std::vector> &tokens = *tokens_ptr; 90 | Iter i = begin; 91 | while(i!=end) 92 | { 93 | Iter start = i; 94 | switch(*i) 95 | { 96 | case ' ': case '\t': case '\n': // ignore whitespaces 97 | ++i; break; 98 | case '(': 99 | tokens.emplace_back(LEFT_PAREN, i, i+1); ++i; break; 100 | case ')': 101 | tokens.emplace_back(RIGHT_PAREN, i, i+1); ++i; break; 102 | case '[': 103 | tokens.emplace_back(LEFT_BRACKET, i, i+1); ++i; break; 104 | case ']': 105 | tokens.emplace_back(RIGHT_BRACKET, i, i+1); ++i; break; 106 | case '{': 107 | tokens.emplace_back(LEFT_BRACE, i, i+1); ++i; break; 108 | case '}': 109 | tokens.emplace_back(RIGHT_BRACE, i, i+1); ++i; break; 110 | case ',': 111 | tokens.emplace_back(COMMA, i, i+1); ++i; break; 112 | case '.': 113 | tokens.emplace_back(DOT, i, i+1); ++i; break; 114 | case ';': 115 | tokens.emplace_back(SEMICOLON, i, i+1); ++i; break; 116 | case ':': 117 | tokens.emplace_back(COLON, i, i+1); ++i; break; 118 | case '+': 119 | if(i+1 != end && *(i+1) == '='){ 120 | tokens.emplace_back(PLUS_EQUAL, i, i+2); i+=2; 121 | } else { 122 | tokens.emplace_back(PLUS, i, i+1); ++i; 123 | } 124 | break; 125 | case '-': 126 | if(i+1 != end && *(i+1) == '='){ 127 | tokens.emplace_back(DASH_EQUAL, i, i+2); i+=2; 128 | } else { 129 | tokens.emplace_back(DASH, i, i+1); ++i; 130 | } 131 | break; 132 | case '*': 133 | if(i+1 != end && *(i+1) == '='){ 134 | tokens.emplace_back(STAR_EQUAL, i, i+2); i+=2; 135 | } else { 136 | tokens.emplace_back(STAR, i, i+1); ++i; 137 | } 138 | break; 139 | case '%': 140 | if(i+1 != end && *(i+1) == '='){ 141 | tokens.emplace_back(PERCENT_EQUAL, i, i+2); i+=2; 142 | } else { 143 | tokens.emplace_back(PERCENT, i, i+1); ++i; 144 | } 145 | break; 146 | case '/': 147 | if(i+1 != end && *(i+1) == '/') { 148 | ++i; while(i!=end && *i != '\n') ++i; ++i; 149 | } else if(i+1 != end && *(i+1) == '='){ 150 | tokens.emplace_back(SLASH_EQUAL, i, i+2); i+=2; 151 | } else { 152 | tokens.emplace_back(SLASH, i, i+1); ++i; 153 | } 154 | break; 155 | case '<': 156 | if(i+1 != end && *(i+1) == '='){ 157 | tokens.emplace_back(LESS_EQUAL, i, i+2); i+=2; 158 | } else { 159 | tokens.emplace_back(LESS, i, i+1); ++i; 160 | } 161 | break; 162 | case '>': 163 | if(i+1 != end && *(i+1) == '='){ 164 | tokens.emplace_back(GREATER_EQUAL, i, i+2); i+=2; 165 | } else { 166 | tokens.emplace_back(GREATER, i, i+1); ++i; 167 | } 168 | break; 169 | case '=': 170 | if(i+1 != end && *(i+1) == '='){ 171 | tokens.emplace_back(EQ_OP, i, i+2); i+=2; 172 | } else { 173 | tokens.emplace_back(EQUAL, i, i+1); ++i; 174 | } 175 | break; 176 | case '!': 177 | if(i+1 != end && *(i+1) == '='){ 178 | tokens.emplace_back(NOT_EQUAL, i, i+2); i+=2; 179 | } else { 180 | tokens.emplace_back(NOT, i, i+1); i+=2; 181 | } 182 | break; 183 | case '&': 184 | if(i+1 != end && *(i+1) == '&'){ 185 | tokens.emplace_back(LOGICAL_AND, i, i+2); i+=2; 186 | } else { 187 | auto lc = line_column(begin, i); 188 | throw std::runtime_error(std::to_string(lc.first)+":"+std::to_string(lc.second)+": unrecognized symbol: '" + *i + "'"); 189 | } 190 | break; 191 | case '|': 192 | if(i+1 != end && *(i+1) == '|'){ 193 | tokens.emplace_back(LOGICAL_OR, i, i+2); i+=2; 194 | } else { 195 | auto lc = line_column(begin, i); 196 | throw std::runtime_error(std::to_string(lc.first)+":"+std::to_string(lc.second)+": unrecognized symbol: '" + *i + "'"); 197 | } 198 | break; 199 | case '"': 200 | ++i; 201 | while(i!=end && !(*i == '"' && *(i-1) != '\\')) ++i; 202 | ++i; 203 | tokens.emplace_back(STRING, start, i); 204 | break; 205 | default: 206 | if(std::isdigit(*i)) { 207 | while(i!=end && std::isdigit(*i)) ++i; 208 | if(i!=end && *i=='.') { 209 | ++i; 210 | while(i!=end && std::isdigit(*i)) ++i; 211 | } 212 | if(i!=end && *i=='e') { 213 | ++i; 214 | if(i!=end && *i=='-') ++i; 215 | while(i!=end && std::isdigit(*i)) ++i; 216 | } 217 | tokens.emplace_back(NUMBER, start, i); 218 | break; 219 | } else if(std::isalpha(*i) || *i == '_') { 220 | ++i; 221 | while(i!=end && (std::isalnum(*i) || *i == '_')) ++i; 222 | auto kw = keywords.find(std::string(start, i)); 223 | if(kw == keywords.end()) 224 | tokens.emplace_back(IDENTIFIER, start, i); 225 | else 226 | tokens.emplace_back(kw->second, start, i); 227 | break; 228 | } else { 229 | auto lc = line_column(begin, i); 230 | throw std::runtime_error(std::to_string(lc.first)+":"+std::to_string(lc.second)+": unrecognized symbol: '" + *i + "'"); 231 | } 232 | } 233 | } 234 | return tokens_ptr; 235 | } 236 | 237 | // Abstract Syntax Tree node types 238 | template 239 | struct ASTNode : public std::enable_shared_from_this>{ 240 | Iter begin, end; 241 | virtual R accept(F&) = 0; 242 | virtual std::shared_ptr>& operator[](size_t) = 0; 243 | virtual size_t size() const = 0; 244 | virtual void inject_dependencies() = 0; 245 | std::shared_ptr source; 246 | std::shared_ptr>> tokens; 247 | std::weak_ptr> root; 248 | }; 249 | 250 | template 251 | struct Variadic : public ASTNode { 252 | virtual R accept(F &f) { return f(*this); } 253 | std::vector>> children; 254 | virtual std::shared_ptr>& operator[](size_t i) { return children[i]; } 255 | virtual size_t size() const { return children.size(); } 256 | virtual void inject_dependencies() { 257 | for(auto& child : children) { 258 | child->root = this->root; 259 | child->source = this->source; 260 | child->tokens = this->tokens; 261 | child->inject_dependencies(); 262 | } 263 | } 264 | }; 265 | 266 | template 267 | struct Ternary : public ASTNode { 268 | virtual R accept(F &f) { return f(*this); } 269 | std::array>, 3> children; 270 | virtual std::shared_ptr>& operator[](size_t i) { return children[i]; } 271 | virtual size_t size() const { return children.size(); } 272 | virtual void inject_dependencies() { 273 | for(auto& child : children) { 274 | child->root = this->root; 275 | child->source = this->source; 276 | child->tokens = this->tokens; 277 | child->inject_dependencies(); 278 | } 279 | } 280 | }; 281 | 282 | template 283 | struct Binary : public ASTNode { 284 | virtual R accept(F &f) { return f(*this); } 285 | std::array>, 2> children; 286 | virtual std::shared_ptr>& operator[](size_t i) { return children[i]; } 287 | virtual size_t size() const { return children.size(); } 288 | virtual void inject_dependencies() { 289 | for(auto& child : children) { 290 | child->root = this->root; 291 | child->source = this->source; 292 | child->tokens = this->tokens; 293 | child->inject_dependencies(); 294 | } 295 | } 296 | }; 297 | 298 | template 299 | struct Unary : public ASTNode { 300 | virtual R accept(F &f) { return f(*this); } 301 | std::array>, 1> children; 302 | virtual std::shared_ptr>& operator[](size_t i) { return children[i]; } 303 | virtual size_t size() const { return children.size(); } 304 | virtual void inject_dependencies() { 305 | for(auto& child : children) { 306 | child->root = this->root; 307 | child->source = this->source; 308 | child->tokens = this->tokens; 309 | child->inject_dependencies(); 310 | } 311 | } 312 | }; 313 | 314 | template 315 | struct Nullary : public ASTNode { 316 | virtual R accept(F &f) { return f(*this); } 317 | std::array>, 0> children; 318 | virtual std::shared_ptr>& operator[](size_t i) { return children[i]; } 319 | virtual size_t size() const { return children.size(); } 320 | virtual void inject_dependencies() { 321 | for(auto& child : children) { 322 | child->root = this->root; 323 | child->source = this->source; 324 | child->tokens = this->tokens; 325 | child->inject_dependencies(); 326 | } 327 | } 328 | }; 329 | 330 | template 331 | struct Variable : public Nullary { 332 | virtual R accept(F &f) { return f(*this); } 333 | R name; 334 | }; 335 | 336 | template 337 | struct GlobalVariable : public Variable { 338 | virtual R accept(F &f) { return f(*this); } 339 | }; 340 | 341 | template 342 | struct LocalVariable : public Variable { 343 | virtual R accept(F &f) { return f(*this); } 344 | }; 345 | 346 | template 347 | struct FieldName : public Nullary { 348 | virtual R accept(F &f) { return f(*this); } 349 | R name; 350 | }; 351 | 352 | template 353 | struct Nop : public Nullary { 354 | virtual R accept(F &f) { return f(*this); } 355 | double value; 356 | }; 357 | 358 | template 359 | struct Constant : public Nullary { 360 | virtual R accept(F &f) { return f(*this); } 361 | R value; 362 | }; 363 | 364 | template 365 | struct Nil : public Nullary { 366 | virtual R accept(F &f) { return f(*this); } 367 | }; 368 | 369 | template 370 | struct String : public Nullary { 371 | virtual R accept(F &f) { return f(*this); } 372 | R value; 373 | }; 374 | 375 | template 376 | struct FieldAccess : public Binary { 377 | virtual R accept(F &f) { return f(*this); } 378 | }; 379 | 380 | template 381 | struct FieldAssignment : public Ternary { 382 | virtual R accept(F &f) { return f(*this); } 383 | }; 384 | 385 | template 386 | struct AddFieldAssignment : public FieldAssignment { 387 | virtual R accept(F &f) { return f(*this); } 388 | }; 389 | 390 | template 391 | struct SubFieldAssignment : public FieldAssignment { 392 | virtual R accept(F &f) { return f(*this); } 393 | }; 394 | 395 | template 396 | struct MulFieldAssignment : public FieldAssignment { 397 | virtual R accept(F &f) { return f(*this); } 398 | }; 399 | 400 | template 401 | struct DivFieldAssignment : public FieldAssignment { 402 | virtual R accept(F &f) { return f(*this); } 403 | }; 404 | 405 | template 406 | struct ModFieldAssignment : public FieldAssignment { 407 | virtual R accept(F &f) { return f(*this); } 408 | }; 409 | 410 | template 411 | struct Call : public Variadic { 412 | virtual R accept(F &f) { return f(*this); } 413 | }; 414 | 415 | template 416 | struct MemberCall : public Variadic { 417 | virtual R accept(F &f) { return f(*this); } 418 | }; 419 | 420 | template 421 | struct EvalStatement : public Unary { 422 | virtual R accept(F &f) { return f(*this); } 423 | }; 424 | 425 | template 426 | struct Eval : public Unary { 427 | virtual R accept(F &f) { return f(*this); } 428 | }; 429 | 430 | template 431 | struct ParseStatement : public Unary { 432 | virtual R accept(F &f) { return f(*this); } 433 | }; 434 | 435 | template 436 | struct ParseExpression : public Unary { 437 | virtual R accept(F &f) { return f(*this); } 438 | }; 439 | 440 | template 441 | struct UnaryExpression : public Unary { 442 | virtual R accept(F &f) { return f(*this); } 443 | }; 444 | 445 | template 446 | struct UnaryPlusExpression : public UnaryExpression { 447 | virtual R accept(F &f) { return f(*this); } 448 | }; 449 | 450 | template 451 | struct UnaryMinusExpression : public UnaryExpression { 452 | virtual R accept(F &f) { return f(*this); } 453 | }; 454 | 455 | template 456 | struct UnaryNotExpression : public UnaryExpression { 457 | virtual R accept(F &f) { return f(*this); } 458 | }; 459 | 460 | template 461 | struct MultiplicativeExpression : public Binary { 462 | virtual R accept(F &f) { return f(*this); } 463 | }; 464 | 465 | template 466 | struct MultiplyExpression : public MultiplicativeExpression { 467 | virtual R accept(F &f) { return f(*this); } 468 | }; 469 | 470 | template 471 | struct DivideExpression : public MultiplicativeExpression { 472 | virtual R accept(F &f) { return f(*this); } 473 | }; 474 | 475 | template 476 | struct ModuloExpression : public MultiplicativeExpression { 477 | virtual R accept(F &f) { return f(*this); } 478 | }; 479 | 480 | template 481 | struct AdditiveExpression : public Binary { 482 | virtual R accept(F &f) { return f(*this); } 483 | }; 484 | 485 | template 486 | struct AddExpression : public AdditiveExpression { 487 | virtual R accept(F &f) { return f(*this); } 488 | }; 489 | 490 | template 491 | struct SubtractExpression : public AdditiveExpression { 492 | virtual R accept(F &f) { return f(*this); } 493 | }; 494 | 495 | template 496 | struct RelationalExpression : public Binary { 497 | virtual R accept(F &f) { return f(*this); } 498 | }; 499 | 500 | template 501 | struct LessExpression : public RelationalExpression { 502 | virtual R accept(F &f) { return f(*this); } 503 | }; 504 | 505 | template 506 | struct LessEqualExpression : public RelationalExpression { 507 | virtual R accept(F &f) { return f(*this); } 508 | }; 509 | 510 | template 511 | struct GreaterExpression : public RelationalExpression { 512 | virtual R accept(F &f) { return f(*this); } 513 | }; 514 | 515 | template 516 | struct GreaterEqualExpression : public RelationalExpression { 517 | virtual R accept(F &f) { return f(*this); } 518 | }; 519 | 520 | template 521 | struct EqualityExpression : public Binary { 522 | virtual R accept(F &f) { return f(*this); } 523 | }; 524 | 525 | template 526 | struct EqualExpression : public EqualityExpression { 527 | virtual R accept(F &f) { return f(*this); } 528 | }; 529 | 530 | template 531 | struct NotEqualExpression : public EqualityExpression { 532 | virtual R accept(F &f) { return f(*this); } 533 | }; 534 | 535 | template 536 | struct LogicalAndExpression : public Binary { 537 | virtual R accept(F &f) { return f(*this); } 538 | }; 539 | 540 | template 541 | struct LogicalOrExpression : public Binary { 542 | virtual R accept(F &f) { return f(*this); } 543 | }; 544 | 545 | template 546 | struct AssignmentExpression : public Binary { 547 | virtual R accept(F &f) { return f(*this); } 548 | }; 549 | 550 | template 551 | struct GlobalAssignmentExpression : public AssignmentExpression { 552 | virtual R accept(F &f) { return f(*this); } 553 | }; 554 | 555 | template 556 | struct LocalAssignmentExpression : public AssignmentExpression { 557 | virtual R accept(F &f) { return f(*this); } 558 | }; 559 | 560 | template 561 | struct AddAssignmentExpression : public AssignmentExpression { 562 | virtual R accept(F &f) { return f(*this); } 563 | }; 564 | 565 | template 566 | struct SubAssignmentExpression : public AssignmentExpression { 567 | virtual R accept(F &f) { return f(*this); } 568 | }; 569 | 570 | template 571 | struct MulAssignmentExpression : public AssignmentExpression { 572 | virtual R accept(F &f) { return f(*this); } 573 | }; 574 | 575 | template 576 | struct DivAssignmentExpression : public AssignmentExpression { 577 | virtual R accept(F &f) { return f(*this); } 578 | }; 579 | 580 | template 581 | struct ModAssignmentExpression : public AssignmentExpression { 582 | virtual R accept(F &f) { return f(*this); } 583 | }; 584 | 585 | template 586 | struct InitializerAssignmentExpression : public Variadic { 587 | virtual R accept(F &f) { return f(*this); } 588 | }; 589 | 590 | template 591 | struct Block : public Unary { 592 | virtual R accept(F &f) { return f(*this); } 593 | }; 594 | 595 | template 596 | struct TableInitializer : public Variadic { 597 | virtual R accept(F &f) { return f(*this); } 598 | }; 599 | 600 | template 601 | struct ArrayInitializer : public Variadic { 602 | virtual R accept(F &f) { return f(*this); } 603 | }; 604 | 605 | template 606 | struct IdentifierList : public Variadic { 607 | virtual R accept(F &f) { return f(*this); } 608 | }; 609 | 610 | template 611 | struct Function : public Binary { 612 | virtual R accept(F &f) { return f(*this); } 613 | }; 614 | 615 | template 616 | struct Tree : public Unary { 617 | virtual R accept(F &f) { return f(*this); } 618 | }; 619 | 620 | template 621 | struct Root : public Variadic { 622 | virtual R accept(F &f) { return f(*this); } 623 | }; 624 | 625 | template 626 | struct Type : public Unary { 627 | virtual R accept(F &f) { return f(*this); } 628 | }; 629 | 630 | template 631 | struct Size : public Unary { 632 | virtual R accept(F &f) { return f(*this); } 633 | }; 634 | 635 | template 636 | struct StatementList : public Variadic { 637 | virtual R accept(F &f) { return f(*this); } 638 | }; 639 | 640 | template 641 | struct IfStatement : public Variadic { 642 | virtual R accept(F &f) { return f(*this); } 643 | }; 644 | 645 | template 646 | struct WhileStatement : public Binary { 647 | virtual R accept(F &f) { return f(*this); } 648 | }; 649 | 650 | template 651 | struct ForStatement : public Variadic { 652 | virtual R accept(F &f) { return f(*this); } 653 | }; 654 | 655 | template 656 | struct ForEachStatement : public Variadic { 657 | virtual R accept(F &f) { return f(*this); } 658 | }; 659 | 660 | template 661 | struct ReturnStatement : public Variadic { 662 | virtual R accept(F &f) { return f(*this); } 663 | }; 664 | 665 | template 666 | struct ContinueStatement : public Nullary { 667 | virtual R accept(F &f) { return f(*this); } 668 | }; 669 | 670 | template 671 | struct BreakStatement : public Nullary { 672 | virtual R accept(F &f) { return f(*this); } 673 | }; 674 | 675 | template 676 | struct ExpressionStatement : public Unary { 677 | virtual R accept(F &f) { return f(*this); } 678 | }; 679 | 680 | template 681 | struct BuiltinFunction : public Nullary { 682 | virtual R accept(F &f) { return f(*this); } 683 | std::function&)> function; 684 | }; 685 | 686 | template 687 | struct Parens : public Unary { 688 | virtual R accept(F &f) { return f(*this); } 689 | }; 690 | 691 | template 692 | class Parser { 693 | public: 694 | typedef std::vector>::iterator Iter; 695 | typedef std::shared_ptr> return_t; 696 | 697 | template 698 | return_t operator()(StrIter sbegin, StrIter send) 699 | { 700 | auto source = std::make_shared(sbegin, send); 701 | auto tokens = tokenize(source->begin(), source->end()); 702 | this->begin = tokens->begin(); 703 | this->end = tokens->end(); 704 | i = this->begin; 705 | accepted = this->end; 706 | auto node = statement_list(); 707 | node->source = source; 708 | node->tokens = tokens; 709 | node->root = node; 710 | node->inject_dependencies(); 711 | return node; 712 | } 713 | 714 | template 715 | return_t parse_expression(StrIter sbegin, StrIter send) 716 | { 717 | auto source = std::make_shared(sbegin, send); 718 | auto tokens = tokenize(source->begin(), source->end()); 719 | this->begin = tokens->begin(); 720 | this->end = tokens->end(); 721 | i = this->begin; 722 | accepted = this->end; 723 | auto node = expression(); 724 | node->source = source; 725 | node->tokens = tokens; 726 | node->root = node; 727 | node->inject_dependencies(); 728 | return node; 729 | } 730 | 731 | private: 732 | Iter i, accepted; 733 | Iter begin; 734 | Iter end; 735 | 736 | void advance() { 737 | if(i==end) { 738 | Iter last = end-1; 739 | auto lc = line_column(begin->begin, last->end); 740 | throw std::runtime_error(std::to_string(lc.first)+":"+std::to_string(lc.second)+": unexpected end of input at"); 741 | } else { 742 | ++i; 743 | } 744 | } 745 | 746 | void rewind(Iter pos) { 747 | i = pos; 748 | } 749 | 750 | bool peek(TokenType t, int amount = 0) { 751 | return i+amount != end && (i+amount)->type == t; 752 | } 753 | 754 | bool accept(TokenType t) { 755 | if(i != end && i->type == t) { 756 | accepted = i; advance(); 757 | return true; 758 | } else { 759 | return false; 760 | } 761 | } 762 | bool end_of_input() { 763 | return i == end; 764 | } 765 | 766 | bool expect(TokenType t) { 767 | if(accept(t)) { 768 | return true; 769 | } else { 770 | i = std::min(i, end-1); 771 | auto lc = line_column(begin->begin, i->begin); 772 | throw std::runtime_error(std::to_string(lc.first)+":"+std::to_string(lc.second)+": unexpected token '" + std::string(i->begin, i->end) + "'"); 773 | return false; 774 | } 775 | } 776 | 777 | void expect(const std::string &expected) { 778 | i = std::min(i, end-1); 779 | auto lc = line_column(begin->begin, i->begin); 780 | throw std::runtime_error(std::to_string(lc.first)+":"+std::to_string(lc.second)+": expected " + expected+ " but got '" + std::string(i->begin, i->end) + "'"); 781 | } 782 | 783 | return_t variable() { 784 | expect(IDENTIFIER); 785 | std::shared_ptr> node = std::make_shared>(); 786 | node->begin = accepted; 787 | node->end = accepted+1; 788 | node->name = R(accepted->begin, accepted->end); 789 | return std::move(node); 790 | } 791 | 792 | return_t field_name() { 793 | expect(IDENTIFIER); 794 | std::shared_ptr> node = std::make_shared>(); 795 | node->begin = accepted; 796 | node->end = accepted+1; 797 | node->name = R(accepted->begin, accepted->end); 798 | return std::move(node); 799 | } 800 | 801 | return_t identifier_list() { 802 | std::shared_ptr> node = std::make_shared>(); 803 | node->begin = i; 804 | expect(LEFT_PAREN); 805 | while(!accept(RIGHT_PAREN)) { 806 | node->children.push_back(field_name()); 807 | if(!peek(RIGHT_PAREN)) 808 | accept(COMMA); 809 | } 810 | node->end = accepted+1; 811 | return std::move(node); 812 | } 813 | 814 | return_t function() { 815 | std::shared_ptr> node = std::make_shared>(); 816 | node->begin = i; 817 | expect(FUNCTION); 818 | node->children[0] = identifier_list(); 819 | node->children[1] = statement(); 820 | node->end = accepted+1; 821 | return std::move(node); 822 | } 823 | 824 | return_t parse_expression() { 825 | std::shared_ptr> node = std::make_shared>(); 826 | node->begin = i; 827 | expect(PARSE_EXPRESSION); 828 | expect(LEFT_PAREN); 829 | node->children[0] = expression(); 830 | expect(RIGHT_PAREN); 831 | node->end = accepted+1; 832 | return std::move(node); 833 | } 834 | 835 | return_t parse_statement() { 836 | std::shared_ptr> node = std::make_shared>(); 837 | node->begin = i; 838 | expect(PARSE_STATEMENT); 839 | expect(LEFT_PAREN); 840 | node->children[0] = expression(); 841 | expect(RIGHT_PAREN); 842 | node->end = accepted+1; 843 | return std::move(node); 844 | } 845 | 846 | return_t tree() { 847 | std::shared_ptr> node = std::make_shared>(); 848 | node->begin = i; 849 | if(accept(EXPRESSION)) { 850 | expect(LEFT_PAREN); 851 | node->children[0] = expression(); 852 | expect(RIGHT_PAREN); 853 | } else { 854 | expect(STATEMENT); 855 | expect(LEFT_PAREN); 856 | node->children[0] = statement(); 857 | expect(RIGHT_PAREN); 858 | } 859 | node->end = accepted+1; 860 | return std::move(node); 861 | } 862 | 863 | return_t root() { 864 | std::shared_ptr> node = std::make_shared>(); 865 | node->begin = i; 866 | expect(ROOT); 867 | if(accept(LEFT_PAREN)) { 868 | node->children.push_back(expression()); 869 | expect(RIGHT_PAREN); 870 | } 871 | node->end = accepted+1; 872 | return std::move(node); 873 | } 874 | 875 | return_t eval() { 876 | std::shared_ptr> node = std::make_shared>(); 877 | node->begin = i; 878 | expect(EVAL); 879 | expect(LEFT_PAREN); 880 | node->children[0] = unary_expression(); 881 | expect(RIGHT_PAREN); 882 | node->end = accepted+1; 883 | return std::move(node); 884 | } 885 | 886 | return_t type() { 887 | std::shared_ptr> node = std::make_shared>(); 888 | node->begin = i; 889 | expect(TYPE); 890 | if(accept(LEFT_PAREN)) { 891 | node->children[0] = expression(); 892 | expect(RIGHT_PAREN); 893 | } 894 | node->end = accepted+1; 895 | return std::move(node); 896 | } 897 | 898 | return_t size() { 899 | std::shared_ptr> node = std::make_shared>(); 900 | node->begin = i; 901 | expect(SIZE); 902 | if(accept(LEFT_PAREN)) { 903 | node->children[0] = expression(); 904 | expect(RIGHT_PAREN); 905 | } 906 | node->end = accepted+1; 907 | return std::move(node); 908 | } 909 | 910 | return_t table_initializer() { 911 | std::shared_ptr> node = std::make_shared>(); 912 | node->begin = i; 913 | expect(LEFT_BRACE); 914 | while(!accept(RIGHT_BRACE)) { 915 | node->children.push_back(initializer_assignment_expression()); 916 | if(!peek(RIGHT_BRACE)) 917 | accept(COMMA); 918 | } 919 | node->end = accepted+1; 920 | return std::move(node); 921 | } 922 | 923 | return_t array_initializer() { 924 | std::shared_ptr> node = std::make_shared>(); 925 | node->begin = i; 926 | expect(LEFT_BRACKET); 927 | while(!accept(RIGHT_BRACKET)) { 928 | node->children.push_back(logical_or_expression()); 929 | if(!peek(RIGHT_BRACKET)) 930 | accept(COMMA); 931 | } 932 | node->end = accepted+1; 933 | return std::move(node); 934 | } 935 | 936 | return_t primary_expression() { 937 | if (peek(IDENTIFIER) || peek(GLOBAL) || peek(LOCAL)) { 938 | return variable(); 939 | } else if (accept(NUMBER)) { 940 | std::shared_ptr> node = std::make_shared>(); 941 | node->begin = accepted; 942 | node->end = accepted+1; 943 | node->value = std::stod(std::string(accepted->begin, accepted->end)); 944 | return std::move(node); 945 | } else if (accept(NIL)) { 946 | std::shared_ptr> node = std::make_shared>(); 947 | node->begin = accepted; 948 | node->end = accepted+1; 949 | return std::move(node); 950 | } else if (accept(STRING)) { 951 | std::shared_ptr> node = std::make_shared>(); 952 | node->begin = accepted; 953 | node->end = accepted+1; 954 | node->value = R(unescape(std::string(accepted->begin+1, accepted->end-1))); 955 | return std::move(node); 956 | } else if (accept(LEFT_PAREN)) { 957 | std::shared_ptr> node = std::make_shared>(); 958 | node->begin = accepted; 959 | node->children[0] = expression(); 960 | expect(RIGHT_PAREN); 961 | node->end = accepted+1; 962 | return std::move(node); 963 | } else if (peek(LEFT_BRACE)) { 964 | return table_initializer(); 965 | } else if (peek(LEFT_BRACKET)) { 966 | return array_initializer(); 967 | } else if (peek(EXPRESSION) || peek(STATEMENT)) { 968 | return tree(); 969 | } else if (peek(ROOT)) { 970 | return root(); 971 | } else if (peek(TYPE)) { 972 | return type(); 973 | } else if (peek(EVAL)) { 974 | return eval(); 975 | } else if (peek(SIZE)) { 976 | return size(); 977 | } else if (peek(PARSE_EXPRESSION)) { 978 | return parse_expression(); 979 | } else if (peek(PARSE_STATEMENT)) { 980 | return parse_statement(); 981 | } else if (peek(FUNCTION)) { 982 | return function(); 983 | } else { 984 | expect("primary expression"); 985 | return nullptr; 986 | } 987 | } 988 | 989 | return_t postfix_expression() { 990 | Iter from = i; 991 | return_t left = primary_expression(); 992 | while(true) { 993 | if(accept(LEFT_BRACKET)) { 994 | return_t right = expression(); 995 | expect(RIGHT_BRACKET); 996 | 997 | if(peek(EQUAL) || peek(PLUS_EQUAL) || peek(DASH_EQUAL) || 998 | peek(STAR_EQUAL) || peek(SLASH_EQUAL) || peek(PERCENT_EQUAL)) { 999 | 1000 | std::shared_ptr> node; 1001 | if(accept(EQUAL)) { 1002 | node = std::make_shared>(); 1003 | } else if(accept(PLUS_EQUAL)) { 1004 | node = std::make_shared>(); 1005 | } else if(accept(DASH_EQUAL)) { 1006 | node = std::make_shared>(); 1007 | } else if(accept(STAR_EQUAL)) { 1008 | node = std::make_shared>(); 1009 | } else if(accept(SLASH_EQUAL)) { 1010 | node = std::make_shared>(); 1011 | } else if(accept(PERCENT_EQUAL)) { 1012 | node = std::make_shared>(); 1013 | } 1014 | node->begin = from; 1015 | node->children[0] = std::move(left); 1016 | node->children[1] = std::move(right); 1017 | node->children[2] = expression(); 1018 | node->end = accepted+1; 1019 | left = std::move(node); 1020 | } else { 1021 | std::shared_ptr> node = std::make_shared>(); 1022 | node->begin = from; 1023 | node->children[0] = std::move(left); 1024 | node->children[1] = std::move(right); 1025 | node->end = accepted+1; 1026 | left = std::move(node); 1027 | } 1028 | } else if(accept(DOT)) { 1029 | return_t right = field_name(); 1030 | if(peek(EQUAL) || peek(PLUS_EQUAL) || peek(DASH_EQUAL) || 1031 | peek(STAR_EQUAL) || peek(SLASH_EQUAL) || peek(PERCENT_EQUAL)) { 1032 | 1033 | std::shared_ptr> node; 1034 | if(accept(EQUAL)) { 1035 | node = std::make_shared>(); 1036 | } else if(accept(PLUS_EQUAL)) { 1037 | node = std::make_shared>(); 1038 | } else if(accept(DASH_EQUAL)) { 1039 | node = std::make_shared>(); 1040 | } else if(accept(STAR_EQUAL)) { 1041 | node = std::make_shared>(); 1042 | } else if(accept(SLASH_EQUAL)) { 1043 | node = std::make_shared>(); 1044 | } else if(accept(PERCENT_EQUAL)) { 1045 | node = std::make_shared>(); 1046 | } 1047 | node->begin = from; 1048 | node->children[0] = std::move(left); 1049 | node->children[1] = std::move(right); 1050 | node->children[2] = expression(); 1051 | node->end = accepted+1; 1052 | left = std::move(node); 1053 | } else if(accept(LEFT_PAREN)) { 1054 | std::shared_ptr> node = std::make_shared>(); 1055 | node->begin = from; 1056 | node->children.push_back(std::move(left)); 1057 | node->children.push_back(std::move(right)); 1058 | while(!accept(RIGHT_PAREN)) { 1059 | node->children.push_back(expression()); 1060 | if(!peek(RIGHT_PAREN)) 1061 | accept(COMMA); 1062 | } 1063 | node->end = accepted+1; 1064 | left = std::move(node); 1065 | } else { 1066 | std::shared_ptr> node = std::make_shared>(); 1067 | node->begin = from; 1068 | node->children[0] = std::move(left); 1069 | node->children[1] = std::move(right); 1070 | node->end = accepted+1; 1071 | left = std::move(node); 1072 | } 1073 | } else if(accept(LEFT_PAREN)) { 1074 | std::shared_ptr> node = std::make_shared>(); 1075 | node->begin = from; 1076 | node->children.push_back(std::move(left)); 1077 | while(!accept(RIGHT_PAREN)) { 1078 | node->children.push_back(expression()); 1079 | if(!peek(RIGHT_PAREN)) 1080 | accept(COMMA); 1081 | } 1082 | node->end = accepted+1; 1083 | left = std::move(node); 1084 | } else { 1085 | return std::move(left); 1086 | } 1087 | } 1088 | } 1089 | 1090 | return_t unary_expression() { 1091 | if(accept(PLUS) || accept(DASH) || accept(NOT)) { 1092 | typedef std::shared_ptr> node_t; 1093 | node_t node; 1094 | switch(accepted->type) { 1095 | case PLUS: node = node_t(new UnaryPlusExpression); break; 1096 | case DASH: node = node_t(new UnaryMinusExpression); break; 1097 | case NOT: node = node_t(new UnaryNotExpression); break; 1098 | default: break; 1099 | } 1100 | node->begin = accepted; 1101 | node->children[0] = postfix_expression(); 1102 | node->end = accepted+1; 1103 | return std::move(node); 1104 | } else { 1105 | return postfix_expression(); 1106 | } 1107 | } 1108 | 1109 | return_t multiplicative_expression() { 1110 | Iter from = i; 1111 | return_t left = unary_expression(); 1112 | if(accept(STAR) || accept(SLASH) || accept(PERCENT)) { 1113 | typedef std::shared_ptr> node_t; 1114 | node_t node; 1115 | switch(accepted->type) { 1116 | case STAR: node = node_t(new MultiplyExpression); break; 1117 | case SLASH: node = node_t(new DivideExpression); break; 1118 | case PERCENT: node = node_t(new ModuloExpression); break; 1119 | default: break; 1120 | } 1121 | node->begin = from; 1122 | node->children[0] = std::move(left); 1123 | node->children[1] = multiplicative_expression(); 1124 | node->end = accepted+1; 1125 | return std::move(node); 1126 | } else { 1127 | return std::move(left); 1128 | } 1129 | } 1130 | 1131 | return_t additive_expression() { 1132 | Iter from = i; 1133 | return_t left = multiplicative_expression(); 1134 | if(accept(PLUS) || accept(DASH)) { 1135 | typedef std::shared_ptr> node_t; 1136 | node_t node; 1137 | switch(accepted->type) { 1138 | case PLUS: node = node_t(new AddExpression); break; 1139 | case DASH: node = node_t(new SubtractExpression); break; 1140 | default: break; 1141 | } 1142 | node->begin = from; 1143 | node->children[0] = std::move(left); 1144 | node->children[1] = additive_expression(); 1145 | node->end = accepted+1; 1146 | return std::move(node); 1147 | } else { 1148 | return std::move(left); 1149 | } 1150 | } 1151 | 1152 | return_t relational_expression() { 1153 | Iter from = i; 1154 | return_t left = additive_expression(); 1155 | if(accept(LESS) || accept(LESS_EQUAL) || accept(GREATER) || accept(GREATER_EQUAL)) { 1156 | typedef std::shared_ptr> node_t; 1157 | node_t node; 1158 | switch(accepted->type) { 1159 | case LESS: node = node_t(new LessExpression); break; 1160 | case LESS_EQUAL: node = node_t(new LessEqualExpression); break; 1161 | case GREATER: node = node_t(new GreaterExpression); break; 1162 | case GREATER_EQUAL: node = node_t(new GreaterEqualExpression); break; 1163 | default: break; 1164 | } 1165 | node->begin = from; 1166 | node->children[0] = std::move(left); 1167 | node->children[1] = relational_expression(); 1168 | node->end = accepted+1; 1169 | return std::move(node); 1170 | } else { 1171 | return std::move(left); 1172 | } 1173 | } 1174 | 1175 | return_t equality_expression() { 1176 | Iter from = i; 1177 | return_t left = relational_expression(); 1178 | if(accept(EQ_OP) || accept(NOT_EQUAL)) { 1179 | typedef std::shared_ptr> node_t; 1180 | node_t node; 1181 | switch(accepted->type) { 1182 | case EQ_OP: node = node_t(new EqualExpression); break; 1183 | case NOT_EQUAL: node = node_t(new NotEqualExpression); break; 1184 | default: break; 1185 | } 1186 | node->begin = from; 1187 | node->children[0] = std::move(left); 1188 | node->children[1] = relational_expression(); 1189 | node->end = accepted+1; 1190 | return std::move(node); 1191 | } else { 1192 | return std::move(left); 1193 | } 1194 | } 1195 | 1196 | return_t logical_and_expression() { 1197 | Iter from = i; 1198 | return_t left = equality_expression(); 1199 | if(accept(LOGICAL_AND)) { 1200 | std::shared_ptr> node = std::make_shared>(); 1201 | node->begin = from; 1202 | node->children[0] = std::move(left); 1203 | node->children[1] = equality_expression(); 1204 | node->end = accepted+1; 1205 | return std::move(node); 1206 | } else { 1207 | return std::move(left); 1208 | } 1209 | } 1210 | 1211 | return_t logical_or_expression() { 1212 | Iter from = i; 1213 | return_t left = logical_and_expression(); 1214 | if(accept(LOGICAL_OR)) { 1215 | std::shared_ptr> node = std::make_shared>(); 1216 | node->begin = from; 1217 | node->children[0] = std::move(left); 1218 | node->children[1] = logical_and_expression(); 1219 | node->end = accepted+1; 1220 | return std::move(node); 1221 | } else { 1222 | return std::move(left); 1223 | } 1224 | } 1225 | 1226 | return_t assignment_expression() { 1227 | Iter from = i; 1228 | if(peek(GLOBAL) || peek(LOCAL)) 1229 | { 1230 | bool global = accept(GLOBAL); 1231 | bool local = accept(LOCAL); 1232 | return_t left = field_name(); 1233 | if(accept(EQUAL)) { 1234 | std::shared_ptr> node; 1235 | node = global? 1236 | std::make_shared>(): 1237 | local? 1238 | std::make_shared>(): 1239 | std::make_shared>(); 1240 | node->begin = from; 1241 | node->children[0] = std::move(left); 1242 | node->children[1] = assignment_expression(); 1243 | node->end = accepted+1; 1244 | return std::move(node); 1245 | } 1246 | } else if(peek(IDENTIFIER)) { 1247 | return_t left = field_name(); 1248 | std::shared_ptr> node; 1249 | if(accept(EQUAL)) { 1250 | node = std::make_shared>(); 1251 | } else if(accept(PLUS_EQUAL)) { 1252 | node = std::make_shared>(); 1253 | } else if(accept(DASH_EQUAL)) { 1254 | node = std::make_shared>(); 1255 | } else if(accept(STAR_EQUAL)) { 1256 | node = std::make_shared>(); 1257 | } else if(accept(SLASH_EQUAL)) { 1258 | node = std::make_shared>(); 1259 | } else if(accept(PERCENT_EQUAL)) { 1260 | node = std::make_shared>(); 1261 | } else { 1262 | rewind(from); 1263 | return logical_or_expression(); 1264 | } 1265 | node->begin = from; 1266 | node->children[0] = std::move(left); 1267 | node->children[1] = assignment_expression(); 1268 | node->end = accepted+1; 1269 | return std::move(node); 1270 | } 1271 | rewind(from); 1272 | return logical_or_expression(); 1273 | } 1274 | 1275 | return_t initializer_assignment_expression() { 1276 | std::shared_ptr> node = std::make_shared>(); 1277 | node->begin = i; 1278 | node->children.push_back(logical_or_expression()); 1279 | if(accept(EQUAL)) { 1280 | node->children.push_back(logical_or_expression()); 1281 | } 1282 | node->end = accepted+1; 1283 | return std::move(node); 1284 | } 1285 | 1286 | return_t expression() { 1287 | return assignment_expression(); 1288 | } 1289 | 1290 | return_t block() { 1291 | std::shared_ptr> node = std::make_shared>(); 1292 | node->begin = i; 1293 | expect(LEFT_BRACE); 1294 | node->children[0] = statement_list(); 1295 | expect(RIGHT_BRACE); 1296 | node->end = accepted+1; 1297 | return std::move(node); 1298 | } 1299 | 1300 | return_t if_statement() { 1301 | std::shared_ptr> node = std::make_shared>(); 1302 | node->begin = i; 1303 | expect(IF); 1304 | expect(LEFT_PAREN); 1305 | node->children.push_back(expression()); 1306 | expect(RIGHT_PAREN); 1307 | node->children.push_back(statement()); 1308 | if(accept(ELSE)) { 1309 | node->children.push_back(statement()); 1310 | } 1311 | node->end = accepted+1; 1312 | return std::move(node); 1313 | } 1314 | 1315 | return_t while_statement() { 1316 | std::shared_ptr> node = std::make_shared>(); 1317 | node->begin = i; 1318 | expect(WHILE); 1319 | expect(LEFT_PAREN); 1320 | node->children[0] = expression(); 1321 | expect(RIGHT_PAREN); 1322 | node->children[1] = statement(); 1323 | node->end = accepted+1; 1324 | return std::move(node); 1325 | } 1326 | 1327 | return_t nop() { 1328 | std::shared_ptr> node = std::make_shared>(); 1329 | node->begin = i; 1330 | node->end = i; 1331 | return std::move(node); 1332 | } 1333 | 1334 | return_t for_statement() { 1335 | Iter from = i; 1336 | expect(FOR); 1337 | expect(LEFT_PAREN); 1338 | if(peek(IDENTIFIER) && (peek(COMMA, 1) || peek(COLON, 1))) { 1339 | std::shared_ptr> node = std::make_shared>(); 1340 | node->begin = from; 1341 | node->children.push_back(field_name()); 1342 | if(accept(COMMA)) { 1343 | node->children.push_back(field_name()); 1344 | } 1345 | expect(COLON); 1346 | node->children.push_back(expression()); 1347 | expect(RIGHT_PAREN); 1348 | node->children.push_back(statement()); 1349 | node->end = accepted+1; 1350 | return std::move(node); 1351 | } else { 1352 | std::shared_ptr> node = std::make_shared>(); 1353 | node->begin = from; 1354 | if(accept(SEMICOLON)) { 1355 | node->children.push_back(nop()); 1356 | } else { 1357 | node->children.push_back(expression()); 1358 | expect(SEMICOLON); 1359 | } 1360 | if(accept(SEMICOLON)) { 1361 | node->children.push_back(nop()); 1362 | } else { 1363 | node->children.push_back(expression()); 1364 | expect(SEMICOLON); 1365 | } 1366 | if(accept(RIGHT_PAREN)) { 1367 | node->children.push_back(nop()); 1368 | } else { 1369 | node->children.push_back(expression()); 1370 | expect(RIGHT_PAREN); 1371 | } 1372 | node->children.push_back(statement()); 1373 | node->end = accepted+1; 1374 | return std::move(node); 1375 | } 1376 | } 1377 | 1378 | return_t break_statement() { 1379 | std::shared_ptr> node = std::make_shared>(); 1380 | node->begin = i; 1381 | expect(BREAK); 1382 | accept(SEMICOLON); 1383 | node->end = accepted+1; 1384 | return std::move(node); 1385 | } 1386 | 1387 | return_t continue_statement() { 1388 | std::shared_ptr> node = std::make_shared>(); 1389 | node->begin = i; 1390 | expect(CONTINUE); 1391 | accept(SEMICOLON); 1392 | node->end = accepted+1; 1393 | return std::move(node); 1394 | } 1395 | 1396 | return_t return_statement() { 1397 | std::shared_ptr> node = std::make_shared>(); 1398 | node->begin = i; 1399 | expect(RETURN); 1400 | if(accept(SEMICOLON)) { 1401 | node->end = accepted+1; 1402 | return std::move(node); 1403 | } 1404 | node->children.push_back(expression()); 1405 | accept(SEMICOLON); 1406 | node->end = accepted+1; 1407 | return std::move(node); 1408 | } 1409 | 1410 | return_t statement() { 1411 | if(peek(LEFT_BRACE)) { 1412 | return block(); 1413 | } else if (peek(IF)) { 1414 | return if_statement(); 1415 | } else if (peek(WHILE)) { 1416 | return while_statement(); 1417 | } else if (peek(FOR)) { 1418 | return for_statement(); 1419 | } else if (peek(RETURN)) { 1420 | return return_statement(); 1421 | } else if (peek(CONTINUE)) { 1422 | return continue_statement(); 1423 | } else if (peek(BREAK)) { 1424 | return break_statement(); 1425 | } else { 1426 | std::shared_ptr> node = std::make_shared>(); 1427 | node->begin = i; 1428 | node->children[0] = expression(); 1429 | accept(SEMICOLON); 1430 | node->end = accepted+1; 1431 | return std::move(node); 1432 | } 1433 | } 1434 | 1435 | return_t statement_list() { 1436 | std::shared_ptr> node = std::make_shared>(); 1437 | node->begin = i; 1438 | while(!end_of_input() && !peek(RIGHT_BRACE)) { 1439 | node->children.push_back(statement()); 1440 | } 1441 | node->end = accepted+1; 1442 | return std::move(node); 1443 | } 1444 | }; 1445 | 1446 | template 1447 | class Table; 1448 | 1449 | template 1450 | class Array; 1451 | 1452 | template 1453 | struct Value { 1454 | typedef std::string string_t; 1455 | typedef string_t::iterator str_iter; 1456 | struct proto_string_t { 1457 | proto_string_t(str_iter begin_, str_iter end_) 1458 | : begin(begin_), end(end_), hash(std::hash()(string_t(begin_, end_))) 1459 | { } 1460 | str_iter begin, end; size_t hash; 1461 | }; 1462 | typedef double number_t; 1463 | typedef std::shared_ptr> pointer_t; 1464 | typedef std::shared_ptr> function_t; 1465 | typedef pointer_t tree_t; 1466 | typedef std::shared_ptr> array_t; 1467 | typedef std::shared_ptr> table_t; 1468 | class return_tag { }; 1469 | class break_tag { }; 1470 | class continue_tag { }; 1471 | enum Type {NIL, NUMBER, STRING, PROTO_STRING, TREE, FUNCTION, TABLE, ARRAY, RETURN, BREAK, CONTINUE}; 1472 | private: 1473 | Type type_; 1474 | union { 1475 | number_t number_; 1476 | pointer_t pointer_; 1477 | table_t table_; 1478 | array_t array_; 1479 | string_t str_; 1480 | proto_string_t proto_str_; 1481 | }; 1482 | public: 1483 | Type type() const { 1484 | if(type_ == PROTO_STRING) 1485 | return STRING; 1486 | else if(type_>=RETURN && type_ <= CONTINUE) 1487 | return NIL; 1488 | return type_; 1489 | } 1490 | Type internal_type() const { return type_; } 1491 | 1492 | const number_t& number() const { return number_; } 1493 | number_t& number() { return number_; } 1494 | 1495 | const pointer_t& pointer() const { return pointer_; } 1496 | pointer_t& pointer() { return pointer_; } 1497 | 1498 | const function_t function() const { return std::static_pointer_cast>(pointer_); } 1499 | function_t function() { return std::static_pointer_cast>(pointer_); } 1500 | 1501 | const tree_t tree() const { return pointer_; } 1502 | tree_t tree() { return pointer_; } 1503 | 1504 | const table_t& table() const { return table_; } 1505 | table_t& table() { return table_; } 1506 | 1507 | const string_t string() const { 1508 | if(type_==PROTO_STRING) 1509 | return std::string(proto_str_.begin, proto_str_.end); 1510 | return str_; 1511 | } 1512 | string_t& string() { decay(); return str_; } 1513 | 1514 | const array_t& array() const { return array_; } 1515 | array_t& array() { return array_; } 1516 | 1517 | void decay() { 1518 | if(type_ == PROTO_STRING) { 1519 | str_iter tmpbegin = proto_str_.begin; 1520 | str_iter tmpend = proto_str_.end; 1521 | type_ = STRING; 1522 | new (&str_) string_t(tmpbegin, tmpend); 1523 | } else if(type_>=RETURN && type_ <= CONTINUE) { 1524 | type_ = NIL; 1525 | } 1526 | } 1527 | 1528 | Value() : type_(NIL), number_(0) { } 1529 | Value(const return_tag&) : type_(RETURN), number_(0) { } 1530 | Value(const break_tag&) : type_(BREAK), number_(0) { } 1531 | Value(const continue_tag&) : type_(CONTINUE), number_(0) { } 1532 | Value(double value) : type_(NUMBER), number_(value) { } 1533 | Value(Type t, const pointer_t &ptr) : type_(t), pointer_(ptr) { } 1534 | Value(const table_t &ptr) : type_(TABLE), table_(ptr) { } 1535 | Value(const array_t &ptr) : type_(ARRAY), array_(ptr) { } 1536 | Value(const string_t &value) : type_(STRING), str_(value) { } 1537 | Value(str_iter begin, str_iter end) : type_(PROTO_STRING), proto_str_(begin, end) { } 1538 | 1539 | Value(const Value &that) : type_(that.type_) { 1540 | switch(type_) { 1541 | case RETURN: case BREAK: case CONTINUE: case NIL: 1542 | new (&number_) number_t(0); break; 1543 | case NUMBER: new (&number_) number_t(that.number_); break; 1544 | case STRING: new (&str_) string_t(that.str_); break; 1545 | case PROTO_STRING: new (&proto_str_) proto_string_t(that.proto_str_); break; 1546 | case TREE: case FUNCTION: 1547 | new (&pointer_) pointer_t(that.pointer_); break; 1548 | case TABLE: new (&table_) table_t(that.table_); break; 1549 | case ARRAY: new (&array_) array_t(that.array_); break; 1550 | default: break; 1551 | } 1552 | } 1553 | 1554 | Value& operator=(const Value &that) { 1555 | switch(type_) { 1556 | case STRING: str_.~string_t(); break; 1557 | case TREE: case FUNCTION: pointer_.~pointer_t(); break; 1558 | case TABLE: table_.~table_t(); break; 1559 | case ARRAY: array_.~array_t(); break; 1560 | default: break; 1561 | } 1562 | type_ = that.type_; 1563 | switch(type_) { 1564 | case RETURN: case BREAK: case CONTINUE: case NIL: 1565 | new (&number_) number_t(0); break; 1566 | case NUMBER: new (&number_) number_t(that.number_); break; 1567 | case STRING: new (&str_) string_t(that.str_); break; 1568 | case PROTO_STRING: new (&proto_str_) proto_string_t(that.proto_str_); break; 1569 | case TREE: case FUNCTION: 1570 | new (&pointer_) pointer_t(that.pointer_); break; 1571 | case TABLE: new (&table_) table_t(that.table_); break; 1572 | case ARRAY: new (&array_) array_t(that.array_); break; 1573 | default: break; 1574 | } 1575 | return *this; 1576 | } 1577 | 1578 | ~Value() { 1579 | switch(type_) { 1580 | case STRING: str_.~string_t(); break; 1581 | case TREE: case FUNCTION: pointer_.~pointer_t(); break; 1582 | case TABLE: table_.~table_t(); break; 1583 | case ARRAY: array_.~array_t(); break; 1584 | default: break; 1585 | } 1586 | } 1587 | 1588 | bool operator==(const Value &that) const { 1589 | 1590 | if(type() != that.type()) 1591 | return false; 1592 | 1593 | switch(type_) { 1594 | case RETURN: case BREAK: case CONTINUE: case NIL: case NUMBER: 1595 | return number() == that.number(); 1596 | case TREE: case FUNCTION: 1597 | return pointer() == that.pointer(); 1598 | case TABLE: 1599 | return table() == that.table(); 1600 | case ARRAY: 1601 | return array() == that.array(); 1602 | case STRING: 1603 | if(that.type_ == STRING) { 1604 | return str_ == that.str_; 1605 | } else { 1606 | if(str_.end()-str_.begin() != that.proto_str_.end - that.proto_str_.begin) return false; 1607 | return std::equal(str_.begin(), str_.end(), that.proto_str_.begin); 1608 | } 1609 | case PROTO_STRING: 1610 | if(that.type_ == STRING) { 1611 | if(proto_str_.end - proto_str_.begin != that.str_.end() - that.str_.begin()) return false; 1612 | return std::equal(proto_str_.begin, proto_str_.end, that.str_.begin()); 1613 | } else { 1614 | if(proto_str_.end - proto_str_.begin != that.proto_str_.end - that.proto_str_.begin) return false; 1615 | return std::equal(proto_str_.begin, proto_str_.end, that.proto_str_.begin); 1616 | } 1617 | default: return false; 1618 | } 1619 | } 1620 | 1621 | friend struct std::hash>; 1622 | }; 1623 | 1624 | namespace std { 1625 | template 1626 | struct hash> { 1627 | public: 1628 | typedef Value T; 1629 | std::size_t operator()(Value const& x) const 1630 | { 1631 | switch(x.type_) { 1632 | case T::NIL: case T::NUMBER: 1633 | return std::hash()(x.number()); 1634 | case T::STRING: 1635 | return std::hash()(x.string()); 1636 | case T::PROTO_STRING: 1637 | return x.proto_str_.hash; 1638 | case T::TREE: case T::FUNCTION: 1639 | return std::hash()(x.pointer()); 1640 | case T::TABLE: 1641 | return std::hash()(x.table()); 1642 | case T::ARRAY: 1643 | return std::hash()(x.array()); 1644 | default: return 0; 1645 | } 1646 | } 1647 | }; 1648 | } 1649 | 1650 | template 1651 | std::ostream& operator<<(std::ostream &out, const Value &v) { 1652 | typedef Value T; 1653 | switch(v.type()) { 1654 | case T::NIL: return out << "nil"; 1655 | case T::NUMBER: 1656 | return out << v.number(); 1657 | case T::STRING: 1658 | return out << v.string(); 1659 | case T::TREE: 1660 | return out << "tree: " << v.tree(); 1661 | case T::FUNCTION: 1662 | return out << "function: " << v.function(); 1663 | case T::TABLE: 1664 | return out << "table: " << v.table(); 1665 | case T::ARRAY: 1666 | return out << "array: " << v.array(); 1667 | default: return out; 1668 | } 1669 | } 1670 | 1671 | template 1672 | class Table { 1673 | public: 1674 | typedef typename std::unordered_map::iterator iterator; 1675 | void set(T key, T value) { 1676 | if(key.type() == T::NIL) return; 1677 | if(value.type() == T::NIL) data.erase(key); 1678 | data[key] = value; 1679 | } 1680 | T get(T key) { 1681 | auto iter = data.find(key); 1682 | if(iter == data.end()) return nil; 1683 | else return iter->second; 1684 | } 1685 | void append(const Table &that) { data.insert(that.data.begin(), that.data.end()); } 1686 | size_t size() const { return data.size(); } 1687 | iterator begin() { return data.begin(); } 1688 | iterator end() { return data.end(); } 1689 | private: 1690 | std::unordered_map data; 1691 | T nil; 1692 | }; 1693 | 1694 | template 1695 | class Array { 1696 | public: 1697 | typedef typename std::vector::iterator iterator; 1698 | void set(T key, T value) { 1699 | int index = key.number(); 1700 | data[index] = value; 1701 | } 1702 | T get(T key) { 1703 | int index = key.number(); 1704 | return data[index]; 1705 | } 1706 | void append(const Array &that) { data.insert(data.end(), that.data.begin(), that.data.end()); } 1707 | void add(const T &value) { data.push_back(value); } 1708 | size_t size() const { return data.size(); } 1709 | iterator begin() { return data.begin(); } 1710 | iterator end() { return data.end(); } 1711 | private: 1712 | std::vector data; 1713 | T nil; 1714 | }; 1715 | 1716 | struct Interpreter { 1717 | typedef std::vector>::iterator Iter; 1718 | typedef Interpreter F; 1719 | typedef Value R; 1720 | 1721 | struct FunctionScope { 1722 | FunctionScope(Interpreter &ev_) : ev(ev_) { ev.beginFunctionScope(); } 1723 | ~FunctionScope() { ev.endFunctionScope(); } 1724 | Interpreter &ev; 1725 | }; 1726 | 1727 | struct LocalScope { 1728 | LocalScope(Interpreter &ev_) : ev(ev_) { ev.beginLocalScope(); } 1729 | ~LocalScope() { ev.endLocalScope(); } 1730 | Interpreter &ev; 1731 | }; 1732 | 1733 | R operator()(Variable &node) { 1734 | return get(node.name); 1735 | } 1736 | 1737 | R operator()(FieldName &node) { 1738 | return node.name; 1739 | } 1740 | 1741 | R operator()(Constant &node) { 1742 | return node.value; 1743 | } 1744 | 1745 | R operator()(Nop &) { 1746 | return R(1.0); 1747 | } 1748 | 1749 | R operator()(Nil &) { 1750 | return R(); 1751 | } 1752 | 1753 | R operator()(String &node) { 1754 | return node.value; 1755 | } 1756 | 1757 | R operator()(Parens &node) { 1758 | return node.children[0]->accept(*this); 1759 | } 1760 | 1761 | R operator()(ExpressionStatement &node) { 1762 | return node.children[0]->accept(*this); 1763 | } 1764 | 1765 | R operator()(Type &node) { 1766 | R expr = node.children[0]->accept(*this); 1767 | switch(expr.type()) { 1768 | case R::STRING: return R(std::string("string")); 1769 | case R::NUMBER: return R(std::string("number")); 1770 | case R::TREE: return R(std::string("tree")); 1771 | case R::FUNCTION: return R(std::string("function")); 1772 | case R::TABLE: return R(std::string("table")); 1773 | case R::ARRAY: return R(std::string("array")); 1774 | case R::NIL: return R(std::string("nil")); 1775 | default: error("unknown type", node); return R(); 1776 | } 1777 | } 1778 | 1779 | R operator()(Size &node) { 1780 | R expr = node.children[0]->accept(*this); 1781 | switch(expr.type()) { 1782 | case R::STRING: return R(expr.string().size()); 1783 | case R::NUMBER: return R(1); 1784 | case R::TREE: return R(expr.pointer()->size()); 1785 | case R::FUNCTION: return R(expr.pointer()->size()); 1786 | case R::TABLE: return R(expr.table()->size()); 1787 | case R::ARRAY: return R(expr.array()->size()); 1788 | case R::NIL: return R(0); 1789 | default: error("unknown type", node); return R(); 1790 | } 1791 | } 1792 | 1793 | R operator()(FieldAccess &node) { 1794 | R left = node.children[0]->accept(*this); 1795 | if(left.type() == R::TABLE) { 1796 | R right = node.children[1]->accept(*this); 1797 | return left.table()->get(right); 1798 | } else if(left.type() == R::ARRAY) { 1799 | R right = node.children[1]->accept(*this); 1800 | if(right.type() != R::NUMBER || !isint(right.number())) error("array index not a integer.", node); 1801 | int idx = right.number(); 1802 | if(idx<0 || idx>=int(left.array()->size())) error("array index out of range.", node); 1803 | return left.array()->get(right); 1804 | } else { 1805 | error("can only index tables or arrays.", node); 1806 | return R(); 1807 | } 1808 | } 1809 | 1810 | R operator()(FieldAssignment &node) { 1811 | R table = node.children[0]->accept(*this); 1812 | if(table.type() == R::TABLE) { 1813 | R index = node.children[1]->accept(*this); 1814 | R value = node.children[2]->accept(*this); 1815 | table.table()->set(index, value); 1816 | return value; 1817 | } else if(table.type() == R::ARRAY) { 1818 | R index = node.children[1]->accept(*this); 1819 | if(index.type() != R::NUMBER || !isint(index.number())) error("array index not a integer.", node); 1820 | int idx = index.number(); 1821 | if(idx<0 || idx>=int(table.array()->size())) error("array index out of range.", node); 1822 | R value = node.children[2]->accept(*this); 1823 | table.array()->set(index, value); 1824 | return value; 1825 | } else { 1826 | error("can only index tables or arrays.", node); 1827 | return R(); 1828 | } 1829 | } 1830 | 1831 | R operator()(AddFieldAssignment &node) { 1832 | R table = node.children[0]->accept(*this); 1833 | R index, left, right; 1834 | R::Type t = table.type(); 1835 | if(t == R::TABLE) { 1836 | index = node.children[1]->accept(*this); 1837 | left = table.table()->get(index); 1838 | right = node.children[2]->accept(*this); 1839 | } else if(t == R::ARRAY) { 1840 | index = node.children[1]->accept(*this); 1841 | if(index.type() != R::NUMBER || !isint(index.number())) error("array index not a integer.", node); 1842 | int idx = index.number(); 1843 | if(idx<0 || idx>=int(table.array()->size())) error("array index out of range.", node); 1844 | left = table.array()->get(index); 1845 | right = node.children[2]->accept(*this); 1846 | } else { 1847 | error("can only index tables and arrays.", node); 1848 | return R(); 1849 | } 1850 | 1851 | if(left.type() == R::NUMBER && right.type() == R::NUMBER) { 1852 | left = R(left.number() + right.number()); 1853 | } else if(left.type() == R::STRING && right.type() == R::STRING) { 1854 | left.string() += right.string(); 1855 | } else if(left.type() == R::TABLE && right.type() == R::TABLE) { 1856 | left.table()->append(*right.table()); 1857 | } else if(left.type() == R::ARRAY && right.type() == R::ARRAY) { 1858 | left.array()->append(*right.array()); 1859 | } else { 1860 | error("invalid operands '+='.", node); 1861 | return R(); 1862 | } 1863 | 1864 | if(t == R::TABLE) { 1865 | table.table()->set(index, left); 1866 | } else if(t == R::ARRAY) { 1867 | table.array()->set(index, left); 1868 | } 1869 | return left; 1870 | } 1871 | 1872 | R operator()(SubFieldAssignment &node) { 1873 | R table = node.children[0]->accept(*this); 1874 | R index, left, right; 1875 | R::Type t = table.type(); 1876 | if(t == R::TABLE) { 1877 | index = node.children[1]->accept(*this); 1878 | left = table.table()->get(index); 1879 | right = node.children[2]->accept(*this); 1880 | } else if(t == R::ARRAY) { 1881 | index = node.children[1]->accept(*this); 1882 | if(index.type() != R::NUMBER || !isint(index.number())) error("array index not a integer.", node); 1883 | int idx = index.number(); 1884 | if(idx<0 || idx>=int(table.array()->size())) error("array index out of range.", node); 1885 | left = table.array()->get(index); 1886 | right = node.children[2]->accept(*this); 1887 | } else { 1888 | error("can only index tables and arrays.", node); 1889 | return R(); 1890 | } 1891 | 1892 | if(left.type() == R::NUMBER && right.type() == R::NUMBER) { 1893 | left = R(left.number() - right.number()); 1894 | } else { 1895 | error("invalid operands to '-='.", node); 1896 | return R(); 1897 | } 1898 | 1899 | if(t == R::TABLE) { 1900 | table.table()->set(index, left); 1901 | } else if(t == R::ARRAY) { 1902 | table.array()->set(index, left); 1903 | } 1904 | return left; 1905 | } 1906 | 1907 | R operator()(MulFieldAssignment &node) { 1908 | R table = node.children[0]->accept(*this); 1909 | R index, left, right; 1910 | R::Type t = table.type(); 1911 | if(t == R::TABLE) { 1912 | index = node.children[1]->accept(*this); 1913 | left = table.table()->get(index); 1914 | right = node.children[2]->accept(*this); 1915 | } else if(t == R::ARRAY) { 1916 | index = node.children[1]->accept(*this); 1917 | if(index.type() != R::NUMBER || !isint(index.number())) error("array index not a integer.", node); 1918 | int idx = index.number(); 1919 | if(idx<0 || idx>=int(table.array()->size())) error("array index out of range.", node); 1920 | left = table.array()->get(index); 1921 | right = node.children[2]->accept(*this); 1922 | } else { 1923 | error("can only index tables and arrays.", node); 1924 | return R(); 1925 | } 1926 | 1927 | if(left.type() == R::NUMBER && right.type() == R::NUMBER) { 1928 | left = R(left.number() * right.number()); 1929 | } else { 1930 | error("invalid operands to '*='.", node); 1931 | return R(); 1932 | } 1933 | 1934 | if(t == R::TABLE) { 1935 | table.table()->set(index, left); 1936 | } else if(t == R::ARRAY) { 1937 | table.array()->set(index, left); 1938 | } 1939 | return left; 1940 | } 1941 | 1942 | R operator()(DivFieldAssignment &node) { 1943 | R table = node.children[0]->accept(*this); 1944 | R index, left, right; 1945 | R::Type t = table.type(); 1946 | if(t == R::TABLE) { 1947 | index = node.children[1]->accept(*this); 1948 | left = table.table()->get(index); 1949 | right = node.children[2]->accept(*this); 1950 | } else if(t == R::ARRAY) { 1951 | index = node.children[1]->accept(*this); 1952 | if(index.type() != R::NUMBER || !isint(index.number())) error("array index not a integer.", node); 1953 | int idx = index.number(); 1954 | if(idx<0 || idx>=int(table.array()->size())) error("array index out of range.", node); 1955 | left = table.array()->get(index); 1956 | right = node.children[2]->accept(*this); 1957 | } else { 1958 | error("can only index tables and arrays.", node); 1959 | return R(); 1960 | } 1961 | 1962 | if(left.type() == R::NUMBER && right.type() == R::NUMBER) { 1963 | left = R(left.number() / right.number()); 1964 | } else { 1965 | error("invalid operands to '/='.", node); 1966 | return R(); 1967 | } 1968 | 1969 | if(t == R::TABLE) { 1970 | table.table()->set(index, left); 1971 | } else if(t == R::ARRAY) { 1972 | table.array()->set(index, left); 1973 | } 1974 | return left; 1975 | } 1976 | 1977 | R operator()(ModFieldAssignment &node) { 1978 | R table = node.children[0]->accept(*this); 1979 | R index, left, right; 1980 | R::Type t = table.type(); 1981 | if(t == R::TABLE) { 1982 | index = node.children[1]->accept(*this); 1983 | left = table.table()->get(index); 1984 | right = node.children[2]->accept(*this); 1985 | } else if(t == R::ARRAY) { 1986 | index = node.children[1]->accept(*this); 1987 | if(index.type() != R::NUMBER || !isint(index.number())) error("array index not a integer.", node); 1988 | int idx = index.number(); 1989 | if(idx<0 || idx>=int(table.array()->size())) error("array index out of range.", node); 1990 | left = table.array()->get(index); 1991 | right = node.children[2]->accept(*this); 1992 | } else { 1993 | error("can only index tables and arrays.", node); 1994 | return R(); 1995 | } 1996 | 1997 | if(left.type() == R::NUMBER && right.type() == R::NUMBER) { 1998 | left = R(std::fmod(left.number(), right.number())); 1999 | } else { 2000 | error("invalid operands to '%='.", node); 2001 | return R(); 2002 | } 2003 | 2004 | if(t == R::TABLE) { 2005 | table.table()->set(index, left); 2006 | } else if(t == R::ARRAY) { 2007 | table.array()->set(index, left); 2008 | } 2009 | return left; 2010 | } 2011 | 2012 | R operator()(UnaryPlusExpression &node) { 2013 | R operand = node.children[0]->accept(*this); 2014 | if(operand.type() != R::NUMBER) error("invalid operand to '+'.", node); 2015 | return operand; 2016 | } 2017 | 2018 | R operator()(UnaryMinusExpression &node) { 2019 | R operand = node.children[0]->accept(*this); 2020 | if(operand.type() != R::NUMBER) error("invalid operand to '-'.", node); 2021 | return R(-operand.number()); 2022 | } 2023 | 2024 | R operator()(UnaryNotExpression &node) { 2025 | R operand = node.children[0]->accept(*this); 2026 | if(operand.type() != R::NUMBER) error("invalid operand to '!'.", node); 2027 | return R(operand.number()==0.0?1.0:0.0); 2028 | } 2029 | 2030 | R operator()(MultiplyExpression &node) { 2031 | R left = node.children[0]->accept(*this); 2032 | R right = node.children[1]->accept(*this); 2033 | if(left.type() == R::NUMBER && right.type() == R::NUMBER) { 2034 | return R(left.number() * right.number()); 2035 | } else { 2036 | error("invalid operands to '*'.", node); 2037 | return R(); 2038 | } 2039 | } 2040 | 2041 | R operator()(DivideExpression &node) { 2042 | R left = node.children[0]->accept(*this); 2043 | R right = node.children[1]->accept(*this); 2044 | if(left.type() == R::NUMBER && right.type() == R::NUMBER) { 2045 | return R(left.number() / right.number()); 2046 | } else { 2047 | error("invalid operands to '/'.", node); 2048 | return R(); 2049 | } 2050 | } 2051 | 2052 | R operator()(ModuloExpression &node) { 2053 | R left = node.children[0]->accept(*this); 2054 | R right = node.children[1]->accept(*this); 2055 | if(left.type() == R::NUMBER && right.type() == R::NUMBER) { 2056 | return R(std::fmod(left.number(), right.number())); 2057 | } else { 2058 | error("invalid operands to '%'.", node); 2059 | return R(); 2060 | } 2061 | } 2062 | 2063 | R operator()(AddExpression &node) { 2064 | R left = node.children[0]->accept(*this); 2065 | R right = node.children[1]->accept(*this); 2066 | if(left.type() == R::NUMBER && right.type() == R::NUMBER) { 2067 | return R(left.number() + right.number()); 2068 | } else if(left.type() == R::STRING && right.type() == R::STRING) { 2069 | return R(left.string() + right.string()); 2070 | } else if(left.type() == R::TABLE && right.type() == R::TABLE) { 2071 | typename R::table_t table(new Table); 2072 | table->append(*left.table()); 2073 | table->append(*right.table()); 2074 | return R(table); 2075 | } else if(left.type() == R::ARRAY && right.type() == R::ARRAY) { 2076 | typename R::array_t array(new Array); 2077 | array->append(*left.array()); 2078 | array->append(*right.array()); 2079 | return R(array); 2080 | } else { 2081 | error("invalid operands to '+'.", node); 2082 | return R(); 2083 | } 2084 | } 2085 | 2086 | R operator()(SubtractExpression &node) { 2087 | R left = node.children[0]->accept(*this); 2088 | R right = node.children[1]->accept(*this); 2089 | if(left.type() == R::NUMBER && right.type() == R::NUMBER) { 2090 | return R(left.number() - right.number()); 2091 | } else { 2092 | error("invalid operands to '-'.", node); 2093 | return R(); 2094 | } 2095 | } 2096 | 2097 | R operator()(LessExpression &node) { 2098 | R left = node.children[0]->accept(*this); 2099 | R right = node.children[1]->accept(*this); 2100 | if(left.type() == R::NUMBER && right.type() == R::NUMBER) { 2101 | return R(left.number() < right.number()); 2102 | } else if(left.type() == R::STRING && right.type() == R::STRING) { 2103 | return R(left.string() < right.string()); 2104 | } else { 2105 | error("invalid operands to '<'.", node); 2106 | return R(); 2107 | } 2108 | } 2109 | 2110 | R operator()(LessEqualExpression &node) { 2111 | R left = node.children[0]->accept(*this); 2112 | R right = node.children[1]->accept(*this); 2113 | if(left.type() == R::NUMBER && right.type() == R::NUMBER) { 2114 | return R(left.number() <= right.number()); 2115 | } else if(left.type() == R::STRING && right.type() == R::STRING) { 2116 | return R(left.string() <= right.string()); 2117 | } else { 2118 | error("invalid operands to '<='.", node); 2119 | return R(); 2120 | } 2121 | } 2122 | 2123 | R operator()(GreaterExpression &node) { 2124 | R left = node.children[0]->accept(*this); 2125 | R right = node.children[1]->accept(*this); 2126 | if(left.type() == R::NUMBER && right.type() == R::NUMBER) { 2127 | return R(left.number() > right.number()); 2128 | } else if(left.type() == R::STRING && right.type() == R::STRING) { 2129 | return R(left.string() > right.string()); 2130 | } else { 2131 | error("invalid operands to '>'.", node); 2132 | return R(); 2133 | } 2134 | } 2135 | 2136 | R operator()(GreaterEqualExpression &node) { 2137 | R left = node.children[0]->accept(*this); 2138 | R right = node.children[1]->accept(*this); 2139 | if(left.type() == R::NUMBER && right.type() == R::NUMBER) { 2140 | return R(left.number() >= right.number()); 2141 | } else if(left.type() == R::STRING && right.type() == R::STRING) { 2142 | return R(left.string() >= right.string()); 2143 | } else { 2144 | error("invalid operands to '>='.", node); 2145 | return R(); 2146 | } 2147 | } 2148 | 2149 | R operator()(EqualExpression &node) { 2150 | R left = node.children[0]->accept(*this); 2151 | R right = node.children[1]->accept(*this); 2152 | return R(left == right); 2153 | } 2154 | 2155 | R operator()(NotEqualExpression &node) { 2156 | R left = node.children[0]->accept(*this); 2157 | R right = node.children[1]->accept(*this); 2158 | return R(!(left == right)); 2159 | } 2160 | 2161 | R operator()(LogicalAndExpression &node) { 2162 | R left = node.children[0]->accept(*this); 2163 | if(left.type() == R::NUMBER) { 2164 | if(left.number() != 0.0) { 2165 | R right = node.children[1]->accept(*this); 2166 | if(right.type() == R::NUMBER) { 2167 | return R(right.number() != 0.0); 2168 | } else { 2169 | error("invalid operands to '&&'.", node); 2170 | return R(); 2171 | } 2172 | } else { 2173 | return R(0.0); 2174 | } 2175 | } else { 2176 | error("invalid operands to '&&'.", node); 2177 | return R(); 2178 | } 2179 | } 2180 | 2181 | R operator()(LogicalOrExpression &node) { 2182 | R left = node.children[0]->accept(*this); 2183 | if(left.type() == R::NUMBER) { 2184 | if(left.number() == 0.0) { 2185 | R right = node.children[1]->accept(*this); 2186 | if(right.type() == R::NUMBER) { 2187 | return R(right.number() != 0.0); 2188 | } else { 2189 | error("invalid operands to '||'.", node); 2190 | return R(); 2191 | } 2192 | } else { 2193 | return R(1.0); 2194 | } 2195 | } else { 2196 | error("invalid operands to '||'.", node); 2197 | return R(); 2198 | } 2199 | } 2200 | 2201 | R operator()(AssignmentExpression &node) { 2202 | R left = node.children[0]->accept(*this); 2203 | R right = node.children[1]->accept(*this); 2204 | set(left, right); 2205 | return right; 2206 | } 2207 | 2208 | R operator()(GlobalAssignmentExpression &node) { 2209 | R left = node.children[0]->accept(*this); 2210 | R right = node.children[1]->accept(*this); 2211 | setGlobal(left, right); 2212 | return right; 2213 | } 2214 | 2215 | R operator()(LocalAssignmentExpression &node) { 2216 | R left = node.children[0]->accept(*this); 2217 | R right = node.children[1]->accept(*this); 2218 | setLocal(left, right); 2219 | return right; 2220 | } 2221 | 2222 | R operator()(AddAssignmentExpression &node) { 2223 | R name = node.children[0]->accept(*this); 2224 | R left = get(name); 2225 | R right = node.children[1]->accept(*this); 2226 | if(left.type() == R::NUMBER && right.type() == R::NUMBER) { 2227 | left = R(left.number() + right.number()); 2228 | } else if(left.type() == R::STRING && right.type() == R::STRING) { 2229 | left.string() += right.string(); 2230 | } else if(left.type() == R::TABLE && right.type() == R::TABLE) { 2231 | left.table()->append(*right.table()); 2232 | } else if(left.type() == R::ARRAY && right.type() == R::ARRAY) { 2233 | left.array()->append(*right.array()); 2234 | } else { 2235 | error("invalid operands to '+='.", node); 2236 | return R(); 2237 | } 2238 | set(name, left); 2239 | return left; 2240 | } 2241 | 2242 | R operator()(SubAssignmentExpression &node) { 2243 | R name = node.children[0]->accept(*this); 2244 | R left = get(name); 2245 | R right = node.children[1]->accept(*this); 2246 | if(left.type() == R::NUMBER && right.type() == R::NUMBER) { 2247 | left = R(left.number() - right.number()); 2248 | } else { 2249 | error("invalid operands to '-='.", node); 2250 | return R(); 2251 | } 2252 | set(name, left); 2253 | return left; 2254 | } 2255 | 2256 | R operator()(MulAssignmentExpression &node) { 2257 | R name = node.children[0]->accept(*this); 2258 | R left = get(name); 2259 | R right = node.children[1]->accept(*this); 2260 | if(left.type() == R::NUMBER && right.type() == R::NUMBER) { 2261 | left = R(left.number() * right.number()); 2262 | } else { 2263 | error("invalid operands to '*='.", node); 2264 | return R(); 2265 | } 2266 | set(name, left); 2267 | return left; 2268 | } 2269 | 2270 | R operator()(DivAssignmentExpression &node) { 2271 | R name = node.children[0]->accept(*this); 2272 | R left = get(name); 2273 | R right = node.children[1]->accept(*this); 2274 | if(left.type() == R::NUMBER && right.type() == R::NUMBER) { 2275 | left = R(left.number() / right.number()); 2276 | } else { 2277 | error("invalid operands to '/='.", node); 2278 | return R(); 2279 | } 2280 | set(name, left); 2281 | return left; 2282 | } 2283 | 2284 | R operator()(ModAssignmentExpression &node) { 2285 | R name = node.children[0]->accept(*this); 2286 | R left = get(name); 2287 | R right = node.children[1]->accept(*this); 2288 | if(left.type() == R::NUMBER && right.type() == R::NUMBER) { 2289 | left = R(std::fmod(left.number(), right.number())); 2290 | } else { 2291 | error("invalid operands to '%='.", node); 2292 | return R(); 2293 | } 2294 | set(name, left); 2295 | return left; 2296 | } 2297 | 2298 | R operator()(Block &node) { 2299 | LocalScope localscope(*this); 2300 | return node.children[0]->accept(*this); 2301 | } 2302 | 2303 | R operator()(TableInitializer &node) { 2304 | double current = 0; 2305 | typename R::table_t table(new Table); 2306 | for(auto tmpchild : node.children) { 2307 | auto child = static_cast*>(tmpchild.get()); 2308 | if(child->children.size() == 1) { 2309 | table->set(R(current++), child->children[0]->accept(*this)); 2310 | } else { 2311 | R index = child->children[0]->accept(*this); 2312 | if(index.type() == R::NUMBER && isint(index.number())) current = index.number()+1; 2313 | table->set(index, child->children[1]->accept(*this)); 2314 | } 2315 | } 2316 | return R(table); 2317 | } 2318 | 2319 | R operator()(ArrayInitializer &node) { 2320 | typename R::array_t array(new Array); 2321 | for(auto& tmpchild : node.children) { 2322 | array->add(tmpchild->accept(*this)); 2323 | } 2324 | return R(array); 2325 | } 2326 | 2327 | R operator()(Function &node) { 2328 | return R(R::FUNCTION, node.shared_from_this()); 2329 | } 2330 | 2331 | R operator()(ReturnStatement &node) { 2332 | if(node.children.size()>0) { 2333 | function_stack.push_back(node.children[0]->accept(*this)); 2334 | } 2335 | return R(typename R::return_tag()); 2336 | } 2337 | 2338 | R operator()(IdentifierList &node) { 2339 | auto i = function_stack.begin(); 2340 | auto end = function_stack.end(); 2341 | 2342 | set(R("this"), *i++); 2343 | for(auto child : node.children) { 2344 | if(i==end) break; 2345 | set(child->accept(*this), *i++); 2346 | } 2347 | function_stack.clear(); 2348 | return R(); 2349 | } 2350 | 2351 | R operator()(BuiltinFunction &node) { 2352 | node.function(function_stack); 2353 | return R(); 2354 | } 2355 | 2356 | R operator()(Call &node) { 2357 | R fun = node.children[0]->accept(*this); 2358 | if(fun.type() != R::FUNCTION) { 2359 | error("can not call non-function.", node); 2360 | return R(); 2361 | } 2362 | auto function = fun.function(); 2363 | 2364 | std::vector args; 2365 | for(size_t i = 1;iaccept(*this)); 2367 | 2368 | function_stack.push_back(R()); 2369 | for(size_t i = 1;ichildren[0]->accept(*this); 2375 | function->children[1]->accept(*this); 2376 | if(!function_stack.empty()) { 2377 | R result = function_stack.back(); 2378 | function_stack.clear(); 2379 | return result; 2380 | } else { 2381 | return R(); 2382 | } 2383 | } 2384 | 2385 | R operator()(MemberCall &node) { 2386 | R table = node.children[0]->accept(*this); 2387 | 2388 | if(table.type() != R::TABLE) { 2389 | error("can only index tables.", node); 2390 | return R(); 2391 | } 2392 | R name = node.children[1]->accept(*this); 2393 | R fun = table.table()->get(name); 2394 | if(fun.type() != R::FUNCTION) { 2395 | error("can not call non-function.", node); 2396 | return R(); 2397 | } 2398 | auto function = fun.function(); 2399 | 2400 | std::vector args; 2401 | for(size_t i = 2;iaccept(*this)); 2403 | 2404 | function_stack.push_back(table); 2405 | for(size_t i = 2;ichildren[0]->accept(*this); 2410 | function->children[1]->accept(*this); 2411 | if(!function_stack.empty()) { 2412 | R result = function_stack.back(); 2413 | function_stack.clear(); 2414 | return result; 2415 | } else { 2416 | return R(); 2417 | } 2418 | } 2419 | 2420 | R operator()(EvalStatement &node) { 2421 | R treeval = node.children[0]->accept(*this); 2422 | if(treeval.type() != R::TREE) { 2423 | error("cannot eval non-tree.", node); 2424 | return R(); 2425 | } 2426 | return treeval.tree()->accept(*this); 2427 | } 2428 | 2429 | R operator()(Eval &node) { 2430 | R treeval = node.children[0]->accept(*this); 2431 | if(treeval.type() != R::TREE) { 2432 | error("cannot eval non-tree.", node); 2433 | return R(); 2434 | } 2435 | return treeval.tree()->accept(*this); 2436 | } 2437 | 2438 | R operator()(Tree &node) { 2439 | return R(R::TREE, node.children[0]); 2440 | } 2441 | 2442 | R operator()(Root &node) { 2443 | if(node.children.empty()) { 2444 | return R(R::TREE, node.root.lock()); 2445 | } else { 2446 | R tree = node.children[0]->accept(*this); 2447 | if(tree.type() == R::TREE || tree.type() == R::FUNCTION) { 2448 | return R(R::TREE, tree.pointer()->root.lock()); 2449 | } else { 2450 | error("cannot find root of non-tree.", node); 2451 | return R(); 2452 | } 2453 | } 2454 | } 2455 | 2456 | R operator()(ParseStatement &node) { 2457 | R val = node.children[0]->accept(*this); 2458 | if(val.type() != R::STRING) { 2459 | error("parse argument needs to be string.", node); 2460 | return R(); 2461 | } 2462 | return R(R::TREE, parser(val.string().begin(), val.string().end())); 2463 | } 2464 | 2465 | R operator()(ParseExpression &node) { 2466 | R val = node.children[0]->accept(*this); 2467 | if(val.type() != R::STRING) { 2468 | error("parse argument needs to be string.", node); 2469 | return R(); 2470 | } 2471 | return R(R::TREE, parser.parse_expression(val.string().begin(), val.string().end())); 2472 | } 2473 | 2474 | R operator()(StatementList &node) { 2475 | for(auto child : node.children) { 2476 | R result = child->accept(*this); 2477 | typename R::Type t = result.internal_type(); 2478 | if(t >= R::RETURN && t<= R::CONTINUE) 2479 | return result; 2480 | } 2481 | return R(); 2482 | } 2483 | 2484 | R operator()(IfStatement &node) { 2485 | R cond = node.children[0]->accept(*this); 2486 | if(cond.type() != R::NUMBER) { 2487 | error("if condition not a number.", node); 2488 | return R(); 2489 | } 2490 | if(cond.number() != 0.0) 2491 | return node.children[1]->accept(*this); 2492 | else if(node.children.size()>2) 2493 | return node.children[2]->accept(*this); 2494 | return R(); 2495 | } 2496 | 2497 | R operator()(WhileStatement &node) { 2498 | while(true) { 2499 | R cond = node.children[0]->accept(*this); 2500 | if(cond.type() != R::NUMBER) error("while condition not a number.", node); 2501 | if(cond == 0.0) break; 2502 | R result = node.children[1]->accept(*this); 2503 | typename R::Type t = result.internal_type(); 2504 | if(t == R::BREAK || t == R::RETURN) 2505 | return result; 2506 | } 2507 | return R(); 2508 | } 2509 | 2510 | R operator()(ForStatement &node) { 2511 | LocalScope(*this); 2512 | node.children[0]->accept(*this); 2513 | while(true) { 2514 | R cond = node.children[1]->accept(*this); 2515 | if(cond.type() != R::NUMBER) error("while condition not a number.", node); 2516 | if(cond == 0.0) break; 2517 | R result = node.children[3]->accept(*this); 2518 | typename R::Type t = result.internal_type(); 2519 | if(t == R::BREAK || t == R::RETURN) 2520 | return result; 2521 | node.children[2]->accept(*this); 2522 | } 2523 | return R(); 2524 | } 2525 | 2526 | R operator()(ForEachStatement &node) { 2527 | if(node.children.size()==3) { 2528 | R value = node.children[0]->accept(*this); 2529 | R table = node.children[1]->accept(*this); 2530 | R::Type t = table.type(); 2531 | if(t != R::TABLE && t != R::ARRAY) error("for each argument is not a table or array", node); 2532 | LocalScope local(*this); 2533 | if(t == R::TABLE) { 2534 | for(auto entry : *table.table()) { 2535 | setLocal(value, entry.second); 2536 | R result = node.children[2]->accept(*this); 2537 | typename R::Type result_t = result.internal_type(); 2538 | if(result_t == R::BREAK || result_t == R::RETURN) 2539 | return result; 2540 | } 2541 | } else { 2542 | for(auto entry : *table.array()) { 2543 | setLocal(value, entry); 2544 | R result = node.children[2]->accept(*this); 2545 | typename R::Type result_t = result.type(); 2546 | if(result_t == R::BREAK || result_t == R::RETURN) 2547 | return result; 2548 | } 2549 | } 2550 | } else { 2551 | R key = node.children[0]->accept(*this); 2552 | R value = node.children[1]->accept(*this); 2553 | R table = node.children[2]->accept(*this); 2554 | if(table.type() != R::TABLE) error("for each argument is not a table", node); 2555 | LocalScope local(*this); 2556 | for(auto entry : *table.table()) { 2557 | setLocal(key, entry.first); 2558 | setLocal(value, entry.second); 2559 | R result = node.children[3]->accept(*this); 2560 | typename R::Type t = result.type(); 2561 | if(t == R::BREAK || t == R::RETURN) 2562 | return result; 2563 | } 2564 | } 2565 | return R(); 2566 | } 2567 | 2568 | R operator()(ContinueStatement &) { 2569 | return R(typename R::continue_tag()); 2570 | } 2571 | 2572 | R operator()(BreakStatement &) { 2573 | return R(typename R::break_tag()); 2574 | } 2575 | 2576 | template 2577 | R operator()(T &node) { 2578 | error("unimplemented ast node.", node); return R(); 2579 | } 2580 | 2581 | Parser parser; 2582 | 2583 | std::vector function_stack; 2584 | 2585 | std::vector> scopes; 2586 | typedef std::shared_ptr> env_t; 2587 | typedef std::vector envstack_t; 2588 | typedef std::vector funstack_t; 2589 | envstack_t envstack; 2590 | funstack_t funstack; 2591 | void beginLocalScope() { 2592 | envstack.push_back(std::make_shared>()); 2593 | } 2594 | void endLocalScope() { 2595 | envstack.pop_back(); 2596 | } 2597 | void beginFunctionScope() { 2598 | funstack.push_back(envstack.size()); 2599 | envstack.push_back(std::make_shared>()); 2600 | } 2601 | void endFunctionScope() { 2602 | envstack.pop_back(); 2603 | funstack.pop_back(); 2604 | } 2605 | R get(R key) { 2606 | int top = envstack.size()-1; 2607 | int bottom = funstack.back(); 2608 | for(int i = top;i>=bottom;--i) { 2609 | R value = envstack[i]->get(key); 2610 | if(value.type() != R::NIL) return value; 2611 | } 2612 | return envstack[0]->get(key); 2613 | } 2614 | void set(R key, R value) { 2615 | envstack[funstack.back()]->set(key, value); 2616 | } 2617 | void setLocal(R key, R value) { 2618 | envstack.back()->set(key, value); 2619 | } 2620 | void setGlobal(R key, R value) { 2621 | envstack[0]->set(key, value); 2622 | } 2623 | 2624 | template 2625 | void error(const std::string text, T &node) { 2626 | auto lc = line_column(node.source->begin(), node.begin->begin); 2627 | auto from = node.begin; 2628 | auto to = node.end-1; 2629 | throw std::runtime_error( 2630 | std::to_string(lc.first)+":"+std::to_string(lc.second)+ 2631 | ": error: " + text + " in: '" + std::string(from->begin, to->end) + "'"); 2632 | } 2633 | 2634 | void addFunction(const std::string &name, std::function&)> fun) { 2635 | auto node = std::make_shared>(); 2636 | node->begin = node->end; 2637 | auto nop = std::make_shared>(); 2638 | nop->begin = nop->end; 2639 | node->children[0] = nop; 2640 | auto builtin = std::make_shared>(); 2641 | builtin->begin = builtin->end; 2642 | builtin->function = fun; 2643 | node->children[1] = builtin; 2644 | setGlobal(R(name), R(R::FUNCTION, node)); 2645 | } 2646 | 2647 | FunctionScope global; 2648 | 2649 | Interpreter() : global(*this) { 2650 | 2651 | } 2652 | 2653 | R run(const std::string &source) { 2654 | auto root = parser(source.begin(), source.end()); 2655 | 2656 | R result = root->accept(*this); 2657 | 2658 | return result; 2659 | } 2660 | }; 2661 | 2662 | void print(std::vector &stack) { 2663 | 2664 | for(size_t i = 1;i &stack) { 2671 | stack.clear(); 2672 | std::string str; 2673 | std::getline(std::cin, str); 2674 | stack.push_back(Interpreter::R(str)); 2675 | } 2676 | 2677 | void children(std::vector &stack) { 2678 | typedef Interpreter::R R; 2679 | if(stack.empty()) return; 2680 | auto arg = stack[1]; 2681 | R::Type t = arg.type(); 2682 | stack.clear(); 2683 | if(t == R::TREE || t == R::FUNCTION) { 2684 | auto result = std::make_shared>(); 2685 | for(size_t i = 0, s = arg.pointer()->size();iadd(R(R::TREE, (*arg.pointer())[i])); 2687 | } 2688 | stack.push_back(result); 2689 | } 2690 | } 2691 | 2692 | void tokens(std::vector &stack) { 2693 | typedef Interpreter::R R; 2694 | if(stack.empty()) return; 2695 | auto arg = stack[1]; 2696 | R::Type t = arg.type(); 2697 | stack.clear(); 2698 | if(t == R::TREE || t == R::FUNCTION) { 2699 | auto result = std::make_shared>(); 2700 | auto node = arg.pointer(); 2701 | for(auto i = node->begin;i!=node->end;++i) { 2702 | result->add(R(std::string(i->begin, i->end))); 2703 | } 2704 | stack.push_back(result); 2705 | } 2706 | } 2707 | 2708 | void expand_node(std::vector &stack) { 2709 | typedef Interpreter::R R; 2710 | if(stack.empty()) return; 2711 | auto arg = stack[1]; 2712 | R::Type t = arg.type(); 2713 | stack.clear(); 2714 | if(t == R::TREE || t == R::FUNCTION) { 2715 | auto result = std::make_shared>(); 2716 | auto &node = *arg.pointer(); 2717 | auto token = node.begin; 2718 | for(size_t i = 0, s = arg.pointer()->size();ibegin;++token) { 2720 | result->add(R(std::string(token->begin, token->end))); 2721 | } 2722 | result->add(R(R::TREE, node[i])); 2723 | token = node[i]->end; 2724 | } 2725 | for(;token!=node.end;++token) { 2726 | result->add(R(std::string(token->begin, token->end))); 2727 | } 2728 | stack.push_back(result); 2729 | } 2730 | } 2731 | 2732 | void tostring(std::vector &stack) { 2733 | typedef Interpreter::R R; 2734 | if(stack.empty()) return; 2735 | auto arg = stack[1]; 2736 | stack.clear(); 2737 | switch(arg.type()) { 2738 | case R::TREE: 2739 | stack.emplace_back(std::string(arg.tree()->begin->begin, (arg.tree()->end-1)->end)); 2740 | return; 2741 | case R::FUNCTION: 2742 | stack.emplace_back(std::string(arg.function()->begin->begin, (arg.function()->end-1)->end)); 2743 | return; 2744 | case R::NUMBER: 2745 | stack.emplace_back(std::to_string(arg.number())); 2746 | return; 2747 | case R::STRING: 2748 | stack.push_back(arg); 2749 | return; 2750 | default: 2751 | stack.clear(); 2752 | return; 2753 | } 2754 | } 2755 | 2756 | void tonumber(std::vector &stack) { 2757 | typedef Interpreter::R R; 2758 | if(stack.empty()) return; 2759 | auto arg = stack[1]; 2760 | stack.clear(); 2761 | if(arg.type() == R::STRING) { 2762 | double result = std::strtod(arg.string().c_str(), nullptr); 2763 | if(result != HUGE_VAL) 2764 | stack.emplace_back(result); 2765 | } 2766 | } 2767 | 2768 | int main(int argc, char *argv[]) { 2769 | if(argc < 2) { 2770 | std::cerr << "no input file provided" << std::endl; 2771 | return 1; 2772 | } 2773 | 2774 | std::ifstream in(argv[1]); 2775 | std::string source((std::istreambuf_iterator(in)), (std::istreambuf_iterator())); 2776 | 2777 | Interpreter interpreter; 2778 | interpreter.addFunction("print", print); 2779 | interpreter.addFunction("readline", readline); 2780 | interpreter.addFunction("children", children); 2781 | interpreter.addFunction("tokens", tokens); 2782 | interpreter.addFunction("expand_node", expand_node); 2783 | interpreter.addFunction("tostring", tostring); 2784 | interpreter.addFunction("tonumber", tonumber); 2785 | interpreter.run(source); 2786 | 2787 | return 0; 2788 | } 2789 | --------------------------------------------------------------------------------