-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpart.h
More file actions
164 lines (138 loc) · 4.17 KB
/
Copy pathpart.h
File metadata and controls
164 lines (138 loc) · 4.17 KB
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
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
#if !defined(PART_H)
#define PART_H
#include <cstdint>
#include <string>
#include <map>
#include <array>
#include <deque>
#include <stack>
#include "mucc_def.h"
#include "part_buffer.h"
class codegen;
struct mml_part
{
int xlen{0};
uint8_t tr_attr{0};
uint8_t xnote{0};
uint8_t oct{0};
uint8_t len{0};
uint8_t vol{0};
int8_t det{0};
uint8_t leg{0};
uint8_t xxleg{0};
uint8_t porsw{0};
uint8_t pornote1{0};
uint8_t pornote2{0};
int8_t oct1{0};
int8_t len1{0};
int8_t vol1{0};
int8_t det1{0};
int8_t trs{0};
int8_t exp{0}; // expression, reset to 0 at vol change
uint8_t def_exp{1}; // default step of relative expression command `(/)`
int exp_mul{1}; // rel. expressions with number, i.e. `(n` or `)n`, are multiplied by this value
void push_loop_addr(uint16_t addr) { nestdata.push(addr); }
uint16_t pop_loop_addr()
{
uint16_t addr = nestdata.top();
nestdata.pop();
return addr;
}
size_t loop_nest_level() const { return nestdata.size(); }
using tickitem = std::pair<unsigned, unsigned>;
auto& current_tick() { return tickstack.top().first; }
auto& ticks_till_break() { return tickstack.top().second; }
void push_tick() { tickstack.emplace(0u, 0u); }
tickitem pop_tick()
{
tickitem v = tickstack.top();
tickstack.pop();
return v;
}
void save_tick_at_loop() { tick_at_loop = current_tick(); }
[[nodiscard]]
unsigned get_tick_at_loop() const { return tick_at_loop; }
mml_part() {
push_tick();
}
private:
std::stack<int> nestdata; // stack of loop start addresses
std::stack<tickitem> tickstack;
unsigned tick_at_loop{0};
};
class mml_ctx
{
std::array<mml_part, MAXPART> parts{}; // A-Z plus some extra
int tempo1 = 0, tempo{120}; // tempo: absolute, tempo1: relative
struct drummacro_item {
int index;
int lineno;
std::string definition;
};
std::map<std::string, drummacro_item> drummacro; // key -> (index, definition)
int drummacro_count = 0;
struct macro_item {
int lineno;
std::string definition;
};
std::map<std::string, macro_item> macro; // key -> (lineno, definition)
struct macro_stack_item {
int lineno;
std::string_view line;
int pos;
};
std::stack<macro_stack_item> macro_stack;
int lineno = 0;
std::string_view line;
int pos{0};
uint32_t partflags = 0;
void push_macro()
{
if(macro_stack.size() >= MACRONEST) {
printf("Macro stack overflow.\n");
return;
}
macro_stack.push({lineno, line, pos});
}
void pop_macro()
{
if(macro_stack.empty()) {
printf("Macro stack underflow.\n");
return;
}
auto [lineno, line, pos] = macro_stack.top();
this->lineno = lineno;
this->line = line;
this->pos = pos;
macro_stack.pop();
}
void set_p(std::string_view new_line, int lineno)
{
line = new_line;
pos = 0;
this->lineno = lineno;
}
char getchar();
[[nodiscard]] char peek() const
{
if(pos >= line.size()) return '\0';
return line[pos];
}
int read_number(int& out, int& is_relative);
int read_numbers(int* out, int count);
int read_length(int& out, int& is_relative);
int call_macro(mml_part &mp, part_buffer &pb);
void gen_note(mml_part &mp, int code, part_buffer &pb);
int parse_drumline(codegen& cg);
int parse_partdef(std::string_view part_name, mml_part &mp, part_buffer &pb);
public:
void register_macro(int lineno, const std::string& name, const std::string& definition);
void register_drummacro(int lineno, const std::string& name, const std::string& definition);
int parse_partline(std::string_view part_token, int lineno, std::string_view line, codegen& cg);
int parse_wildcardline(int lineno, std::string_view line, codegen& cg);
int end_mml(codegen& cg);
auto& get_part(int part) { return parts[part]; }
void report_macro(FILE* fp);
void report_drummacro(FILE* fp);
};
#endif // !defined(PART_H)