Skip to content

Commit f51fc67

Browse files
committed
add shortcuts(functions) to bread
1 parent 493f102 commit f51fc67

2 files changed

Lines changed: 75 additions & 43 deletions

File tree

docs/COMMANDS.md

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,23 +45,31 @@ There are 4 basic maths functions, which are:
4545
- `div/foo/4` - Division. Example: Divides foo by 4
4646
These are only just examples, but the numbers can be replaced with an integer.
4747
Other maths functions:
48-
- `mod/foo/4` - TO BE IMPLEMENTED SOON
48+
- `mod/foo/4` - Modulo. Example: Mod foo by 4
4949

5050
## Other functions
5151
- `wait/5` - Stop the program for X second (5 for example)
5252

53-
## Functions?
54-
## SHORTCUTS TO BE IMPLEMENTED SOON!
53+
## Functions
5554
In bread, functions are shortcuts.
5655
Shortcuts always have to be defined at the top of the .bread file and must start with
5756
`shrtct/shortcutname`
5857
and end with
5958
`endshtrct/`
59+
Currently you cannot pass anything inside the shortcut, if you want to use a variable inside the shortcut you have to define it before using it in the shortcut or else it will only be local to that shortcut.
6060
You do not need to add tabs while defining what a shortcut does.
6161
Here is an example of a shortcut.
6262
```
6363
shrtct/foo
6464
print/Im a shortcut!
6565
int/ran/1
6666
endshrtct/
67-
```
67+
```
68+
A shortcut must be declared before being used.
69+
It can be used like this (in this example, foo is the shortcut name):
70+
```
71+
code...
72+
foo
73+
more code...
74+
```
75+
Shortcuts should not exit, if yes they will lead to errors while compiling.

src/compiler.cpp

Lines changed: 63 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ std::vector<std::string> file_contents;
1313
std::vector<std::string> integer_names;
1414
std::vector<std::string> string_names;
1515
std::vector<std::string> bool_names;
16-
16+
std::vector<std::string> shortcut_names;
1717

1818
int compiler; // 1 = gcc, 2 = clang, if both, clang will be preferred due to faster compile time
1919

@@ -58,8 +58,11 @@ void trimwhtspc(std::string &string) {
5858

5959
int compile_to_cpp(std::string filename) {
6060
std::ifstream breadfile;
61-
std::ofstream cpp_file;
62-
61+
std::ofstream cpp_file_raw;
62+
std::stringstream cpp_file;
63+
std::stringstream func_stream; // needed so that the functions are outside main
64+
std::ostream* curr_out = &cpp_file;
65+
int is_in_func;
6366
breadfile.open(filename);
6467
if (!breadfile.is_open()) {
6568
std::cerr << "error opening file" << std::endl;
@@ -71,8 +74,8 @@ int compile_to_cpp(std::string filename) {
7174
file_contents.push_back(c);
7275
} // save file into vector
7376
breadfile.close();
74-
cpp_file.open(cpp_dir);
75-
if (!cpp_file.is_open()) {
77+
cpp_file_raw.open(cpp_dir);
78+
if (!cpp_file_raw.is_open()) {
7679
std::cerr << "error creating temporary cpp file" << std::endl;
7780
throw 500;
7881
return 1;
@@ -82,7 +85,8 @@ int compile_to_cpp(std::string filename) {
8285
// content.erase(0,7);
8386
// }
8487
//} todo: shortcuts
85-
cpp_file << "#include<iostream>\n#include<chrono>\n#include<thread>\nint main() {\n";
88+
cpp_file_raw << "#include<iostream>\n#include<chrono>\n#include<thread>\n";
89+
*curr_out << "int main() {\n";
8690
for (std::string content : file_contents) {
8791
trimwhtspc(content); // needed if the user uses tabs
8892
if (content.empty()) { // checks if the line is empty, do not delete this function
@@ -94,9 +98,9 @@ int compile_to_cpp(std::string filename) {
9498
auto int_it = std::find(integer_names.begin(), integer_names.end(), content);
9599
auto bool_it = std::find(bool_names.begin(), bool_names.end(), content);
96100
if (string_it != string_names.end() or int_it != integer_names.end() or bool_it != bool_names.end()) {
97-
cpp_file << "std::cout << " + content << " << std::endl;\n";
101+
*curr_out << "std::cout << " + content << " << std::endl;\n";
98102
} else {
99-
cpp_file << "std::cout << \"" << content << "\" << std::endl;\n";
103+
*curr_out << "std::cout << \"" << content << "\" << std::endl;\n";
100104
}
101105

102106
} else if (content.find("int/") == 0 ) {
@@ -113,9 +117,9 @@ int compile_to_cpp(std::string filename) {
113117
}
114118
auto int_it = std::find(integer_names.begin(), integer_names.end(), int_name);
115119
if (int_it != integer_names.end()) {
116-
cpp_file << int_name << " = " << int_val << ";\n";
120+
*curr_out << int_name << " = " << int_val << ";\n";
117121
} else {
118-
cpp_file << "int " << int_name << " = " << int_val << ";\n";
122+
*curr_out << "int " << int_name << " = " << int_val << ";\n";
119123
integer_names.push_back(int_name);
120124
}
121125
}
@@ -133,9 +137,9 @@ int compile_to_cpp(std::string filename) {
133137
}
134138
auto bol_it = std::find(bool_names.begin(), bool_names.end(), bol_name);
135139
if (bol_it != bool_names.end()) {
136-
cpp_file << bol_name << " = " << bol_val << ";\n";
140+
*curr_out << bol_name << " = " << bol_val << ";\n";
137141
} else {
138-
cpp_file << "bool " << bol_name << " = " << bol_val << ";\n";
142+
*curr_out << "bool " << bol_name << " = " << bol_val << ";\n";
139143
bool_names.push_back(bol_name);
140144
}
141145
}
@@ -147,20 +151,20 @@ int compile_to_cpp(std::string filename) {
147151
std::string str_val = content.substr(slash + 1);
148152
auto str_it = std::find(string_names.begin(), string_names.end(), str_name);
149153
if (str_it != string_names.end()) {
150-
cpp_file << str_name << " = \"" << str_val << "\";\n";
154+
*curr_out << str_name << " = \"" << str_val << "\";\n";
151155
} else {
152-
cpp_file << "std::string " << str_name << " = \"" << str_val << "\";\n";
156+
*curr_out << "std::string " << str_name << " = \"" << str_val << "\";\n";
153157
string_names.push_back(str_name);
154158
}
155159
}
156160
} else if (content.find("in/") == 0) {
157161
content.erase(0, 3);
158162
auto it = std::find(string_names.begin(), string_names.end(), content);
159163
if (it == string_names.end()) {
160-
cpp_file << "std::string " << content << ";\n";
164+
*curr_out << "std::string " << content << ";\n";
161165
string_names.push_back(content);
162166
}
163-
cpp_file << "std::cin >> " << content << ";\n";
167+
*curr_out << "std::cin >> " << content << ";\n";
164168
} else if (content.find("exit/") == 0) {
165169
content.erase(0, 5);
166170
int is_int = all_of(content.begin(), content.end(), ::isdigit);
@@ -169,7 +173,7 @@ int compile_to_cpp(std::string filename) {
169173
throw 500;
170174
return 1;
171175
}
172-
cpp_file << "return " << content << ";\n";
176+
*curr_out << "return " << content << ";\n";
173177
} else if (content.find("if/") == 0) {
174178
content.erase(0, 3);
175179
size_t slash1 = content.find('/');
@@ -187,9 +191,9 @@ int compile_to_cpp(std::string filename) {
187191
} else if (condition == "notequals") {
188192
condition = "!=";
189193
}
190-
cpp_file << "if (" << variable1 << " "<< condition << " " << variable2 << ") {\n";
194+
*curr_out << "if (" << variable1 << " "<< condition << " " << variable2 << ") {\n";
191195
} else if (content.find("endif/") == 0) {
192-
cpp_file << "}\n";
196+
*curr_out << "}\n";
193197
} else if (content.find("while/") == 0) {
194198
content.erase(0, 6);
195199
size_t slash1 = content.find('/');
@@ -232,12 +236,12 @@ int compile_to_cpp(std::string filename) {
232236
condition = "== false";
233237
}
234238
if (is_var_2_used == 1) {
235-
cpp_file << "while (" << variable << " " << condition << " " << variable2 << ") {\n";
239+
*curr_out << "while (" << variable << " " << condition << " " << variable2 << ") {\n";
236240
} else {
237-
cpp_file << "while (" << variable << " " << condition << ") {\n";
241+
*curr_out << "while (" << variable << " " << condition << ") {\n";
238242
}
239243
} else if (content.find("endwhile/") == 0) {
240-
cpp_file << "}\n";
244+
*curr_out << "}\n";
241245
} else if (content.find("add/") == 0) {
242246
content.erase(0, 4);
243247
size_t slash1 = content.find('/');
@@ -261,15 +265,15 @@ int compile_to_cpp(std::string filename) {
261265
}
262266
auto int2_it = std::find(integer_names.begin(), integer_names.end(), variable2);
263267
if (int2_it != integer_names.end()) {
264-
cpp_file << variable1 << " += " << variable2 << ";\n";
268+
*curr_out << variable1 << " += " << variable2 << ";\n";
265269
} else {
266270
int is_int = all_of(variable2.begin(), variable2.end(), ::isdigit);
267271
if (!is_int) {
268272
std::cerr << "only numbers can be added to an integer!" << std::endl;
269273
throw 500;
270274
return 1;
271275
} else {
272-
cpp_file << variable1 << " += " << variable2 << ";\n";
276+
*curr_out << variable1 << " += " << variable2 << ";\n";
273277
}
274278
}
275279
} else if (content.find("sub/") == 0) {
@@ -295,15 +299,15 @@ int compile_to_cpp(std::string filename) {
295299
}
296300
auto int2_it = std::find(integer_names.begin(), integer_names.end(), variable2);
297301
if (int2_it != integer_names.end()) {
298-
cpp_file << variable1 << " -= " << variable2 << ";\n";
302+
*curr_out << variable1 << " -= " << variable2 << ";\n";
299303
} else {
300304
int is_int = all_of(variable2.begin(), variable2.end(), ::isdigit);
301305
if (!is_int) {
302306
std::cerr << "only numbers can be subtracted an integer!" << std::endl;
303307
throw 500;
304308
return 1;
305309
} else {
306-
cpp_file << variable1 << " -= " << variable2 << ";\n";
310+
*curr_out << variable1 << " -= " << variable2 << ";\n";
307311
}
308312
}
309313
} else if (content.find("mul/") == 0) {
@@ -329,15 +333,15 @@ int compile_to_cpp(std::string filename) {
329333
}
330334
auto int2_it = std::find(integer_names.begin(), integer_names.end(), variable2);
331335
if (int2_it != integer_names.end()) {
332-
cpp_file << variable1 << " *= " << variable2 << ";\n";
336+
*curr_out << variable1 << " *= " << variable2 << ";\n";
333337
} else {
334338
int is_int = all_of(variable2.begin(), variable2.end(), ::isdigit);
335339
if (!is_int) {
336340
std::cerr << "only numbers can multiply an integer!" << std::endl;
337341
throw 500;
338342
return 1;
339343
} else {
340-
cpp_file << variable1 << " *= " << variable2 << ";\n";
344+
*curr_out << variable1 << " *= " << variable2 << ";\n";
341345
}
342346
}
343347
} else if (content.find("div/") == 0) {
@@ -367,15 +371,15 @@ int compile_to_cpp(std::string filename) {
367371
}
368372
auto int2_it = std::find(integer_names.begin(), integer_names.end(), variable2);
369373
if (int2_it != integer_names.end()) {
370-
cpp_file << variable1 << " /= " << variable2 << ";\n";
374+
*curr_out << variable1 << " /= " << variable2 << ";\n";
371375
} else {
372376
int is_int = all_of(variable2.begin(), variable2.end(), ::isdigit);
373377
if (!is_int) {
374378
std::cerr << "only numbers can divide an integer!" << std::endl;
375379
throw 500;
376380
return 1;
377381
} else {
378-
cpp_file << variable1 << " /= " << variable2 << ";\n";
382+
*curr_out << variable1 << " /= " << variable2 << ";\n";
379383
}
380384
}
381385
} else if (content.find("mod/") == 0) {
@@ -405,15 +409,15 @@ int compile_to_cpp(std::string filename) {
405409
}
406410
auto int2_it = std::find(integer_names.begin(), integer_names.end(), variable2);
407411
if (int2_it != integer_names.end()) {
408-
cpp_file << variable1 << " %= " << variable2 << ";\n";
412+
*curr_out << variable1 << " %= " << variable2 << ";\n";
409413
} else {
410414
int is_int = all_of(variable2.begin(), variable2.end(), ::isdigit);
411415
if (!is_int) {
412416
std::cerr << "only numbers can mod an integer!" << std::endl;
413417
throw 500;
414418
return 1;
415419
} else {
416-
cpp_file << variable1 << " %= " << variable2 << ";\n";
420+
*curr_out << variable1 << " %= " << variable2 << ";\n";
417421
}
418422
}
419423
} else if (content.find("wait/") == 0) {
@@ -431,20 +435,40 @@ int compile_to_cpp(std::string filename) {
431435
throw 500;
432436
return 1;
433437
} else {
434-
cpp_file << "std::this_thread::sleep_for(std::chrono::seconds(" << content << "));\n";
438+
*curr_out << "std::this_thread::sleep_for(std::chrono::seconds(" << content << "));\n";
435439
}
436440
} else {
437-
cpp_file << "std::this_thread::sleep_for(std::chrono::seconds(" << content << "));\n";
441+
*curr_out << "std::this_thread::sleep_for(std::chrono::seconds(" << content << "));\n";
438442
}
439443

444+
} else if (content.find("shrtct/") == 0) {
445+
content.erase(0, 7);
446+
if (content == "") {
447+
std::cerr << "a shortcut must have a name!" << std::endl;
448+
throw 500;
449+
return 1;
450+
}
451+
curr_out = &func_stream;
452+
*curr_out << "void " << content << "() {\n";
453+
shortcut_names.push_back(content);
454+
} else if (content.find("endshrtct/") == 0) {
455+
*curr_out << "}\n";
456+
curr_out = &cpp_file;
440457
} else {
441-
std::cerr << "invalid command: " << content << std::endl;
442-
throw 500;
443-
return 1;
458+
auto shrtct_it = std::find(shortcut_names.begin(), shortcut_names.end(), content);
459+
if (shrtct_it != shortcut_names.end()) {
460+
*curr_out << content << "();\n";
461+
} else {
462+
std::cerr << "invalid command: " << content << std::endl;
463+
throw 500;
464+
return 1;
465+
}
444466
}
445467
}
446-
cpp_file << "return 0;\n}\n";
447-
cpp_file.close();
468+
*curr_out << "return 0;\n}\n";
469+
cpp_file_raw << func_stream.str();
470+
cpp_file_raw << cpp_file.str();
471+
cpp_file_raw.close();
448472
compile_cpp(cpp_dir);
449473
return 0;
450474
}

0 commit comments

Comments
 (0)