A simple scripting language in C++
Ferenc Szontágh
2025-04-12 7d7a1e80c8a8c1e52446453d1b86d3c3b945ec29
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#ifndef PRINTFUNCTION_HPP
#define PRINTFUNCTION_HPP
 
#include <iostream>
 
#include "BaseFunction.hpp"
#include "ScriptExceptionMacros.h"
#include "SScriptInterpreter.hpp"
#include "Token.hpp"
#include "Value.hpp"
 
class PrintFunction : public BaseFunction {
  private:
    const std::string name = "print";
  public:
    void validate(const std::vector<Token> & tokens, size_t & i) const override {
        auto index = i;
        if (tokens[index].type != TokenType::Identifier) {
            THROW_UNEXPECTED_TOKEN_ERROR(tokens[index], "identifier: " + name);
        }
        index++;  // skip function name
        if (tokens[index].type != TokenType::LeftParenthesis) {
            THROW_UNEXPECTED_TOKEN_ERROR(tokens[index], "('");
        }
        index++;  // skip '('
        if (tokens[index].type != TokenType::StringLiteral && tokens[index].type != TokenType::Variable &&
            tokens[index].type != TokenType::IntLiteral && tokens[index].type != TokenType::DoubleLiteral) {
            THROW_UNEXPECTED_TOKEN_ERROR(tokens[index], "string, int, double or variable as argument");
        }
        size_t count = 0;
        while (tokens[index].type != TokenType::RightParenthesis) {
            if (tokens[index].type == TokenType::StringLiteral || tokens[index].type == TokenType::Variable ||
                tokens[index].type == TokenType::IntLiteral || tokens[index].type == TokenType::DoubleLiteral) {
                count++;
                index++;
            } else if (tokens[index].type == TokenType::Comma) {
                index++;
            } else {
                THROW_UNEXPECTED_TOKEN_ERROR(tokens[index], "string, int, double or variable as argument");
            }
        }
        if (count == 0) {
            throw std::runtime_error("print() requires at least one argument at");
        }
        index++;  // skip ')'
        if (tokens[index].type == TokenType::Semicolon) {
            index++;
        } else {
            THROW_UNEXPECTED_TOKEN_ERROR(tokens[index], ";");
        }
    }
 
    Value call(const std::vector<Value> & args, bool debug = false) const override {
        for (const auto & arg : args) {
            std::cout << arg.ToString();
        }
        return Value();
    }
};
 
#endif  // PRINTFUNCTION_HPP