summaryrefslogtreecommitdiff
path: root/src/map/script.hpp
blob: 171f8a3f843ad6d6eb0246b926ff196115e1e858 (plain) (blame)
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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
#ifndef SCRIPT_HPP
#define SCRIPT_HPP

#include <cstdint>
#include <cstring> // for inlined get_str - TODO remove

#include <string>
#include <vector>

#include "../common/db.hpp"
#include "../common/dumb_ptr.hpp"

enum class ByteCode : uint8_t;
struct str_data_t;

class ScriptBuffer
{
    std::vector<ByteCode> script_buf;
public:
    // construction methods used only by script.cpp
    void add_scriptc(ByteCode a);
    void add_scriptb(uint8_t a);
    void add_scripti(uint32_t a);
    void add_scriptl(str_data_t *a);
    void set_label(str_data_t *ld, int pos_);
    const char *parse_simpleexpr(const char *p);
    const char *parse_subexpr(const char *p, int limit);
    const char *parse_expr(const char *p);
    const char *parse_line(const char *p);
    void parse_script(const char *src, int line);

    // consumption methods used only by script.cpp
    ByteCode operator[](size_t i) const { return script_buf[i]; }
    const char *get_str(size_t i) const
    {
        return reinterpret_cast<const char *>(&script_buf[i]);
    }

    // method used elsewhere
};

struct ScriptPointer
{
    const ScriptBuffer *code;
    size_t pos;

    ScriptPointer()
    : code()
    , pos()
    {}

    ScriptPointer(const ScriptBuffer *c, size_t p)
    : code(c)
    , pos(p)
    {}

    ByteCode peek() const { return (*code)[pos]; }
    ByteCode pop() { return (*code)[pos++]; }
    const char *pops()
    {
        const char *rv = code->get_str(pos);
        pos += strlen(rv);
        return rv;
    }
};

struct script_data
{
    ByteCode type;
    union uu
    {
        int num;
        dumb_string str;
        // Not a ScriptPointer - pos is stored in a separate slot,
        // to avoid exploding the struct for everyone.
        const ScriptBuffer *script;

        uu() { memset(this, '\0', sizeof(*this)); }
        ~uu() = default;
        uu(const uu&) = default;
        uu& operator = (const uu&) = default;
    } u;
};

struct script_stack
{
    std::vector<struct script_data> stack_datav;
};

enum class ScriptEndState;
// future improvements coming!
class ScriptState
{
public:
    struct script_stack *stack;
    int start, end;
    ScriptEndState state;
    int rid, oid;
    ScriptPointer scriptp, new_scriptp;
    int defsp, new_defsp;
};

std::unique_ptr<const ScriptBuffer> parse_script(const char *, int);
typedef struct argrec
{
    const char *name;
    union _aru
    {
        int i;
        const char *s;

        _aru() = default;
        _aru(int n) : i(n) {}
        _aru(const char *z) : s(z) {}
    } v;
} argrec_t;
int run_script_l(ScriptPointer, int, int, int, argrec_t *args);
int run_script(ScriptPointer, int, int);

extern
Map<std::string, int> scriptlabel_db;
extern
UPMap<std::string, const ScriptBuffer> userfunc_db;

void script_config_read();
void do_init_script(void);
void do_final_script(void);

extern char mapreg_txt[256];

#endif // SCRIPT_HPP