diff --git a/docs/changelogs/changelog-v1.0.0.md b/docs/changelogs/changelog-v1.0.0.md index 039cd0e..735aadd 100644 --- a/docs/changelogs/changelog-v1.0.0.md +++ b/docs/changelogs/changelog-v1.0.0.md @@ -10,7 +10,8 @@ * moved errors.sts from /usr/bin to /usr/share/stormscript * Function arguments no longer require you to specify the name * `for PLACEHOLDER in LIST/STR` creates a foreach loop -* `randomrange` now uses Mersenne Twister generation rather than cpp `rand()` function +* `randomrange and rand` now uses Mersenne Twister generation rather than cpp `rand()` function +* added `break` for loops ## What's Fixed * Removed snapcraft files diff --git a/example/example.sts b/example/example.sts index 78bddb4..e24e833 100755 --- a/example/example.sts +++ b/example/example.sts @@ -1,3 +1 @@ -print "What is your favorite color: "; -in color; -printl "Cool! I like $color too!"; \ No newline at end of file +printl random; \ No newline at end of file diff --git a/src/core/errors.sts b/src/core/errors.sts index 03b5a82..1e295c3 100755 --- a/src/core/errors.sts +++ b/src/core/errors.sts @@ -54,4 +54,7 @@ else if arg[1] is "17" { } else if arg[1] is "18" { printl "Error: Function ", arg[2], " requires arguments"; +} +else if arg[1] is "19" { + printl "Error: break ouside loop"; } \ No newline at end of file diff --git a/src/include/core.h b/src/include/core.h index 3210568..87f67a4 100644 --- a/src/include/core.h +++ b/src/include/core.h @@ -13,6 +13,13 @@ class sts //variables int lineon; //line the parser is on int function = -1; + /* + * What the function numbers mean: + * -1: Not a function + * -2: A loop + * > 1: The number of the function that is running + */ + bool looping = false; unsigned int sizeoff = 0; //size of the program std::vector prg; //unparsed program std::vector expressions; // Replacing prs. Same thing with more info diff --git a/src/include/parser.h b/src/include/parser.h index bbaad9a..a07a3d5 100644 --- a/src/include/parser.h +++ b/src/include/parser.h @@ -64,7 +64,8 @@ enum Builtin { // these are built in commands READ, RANDOM, RANDOMRANGE, - LENGTH + LENGTH, + BREAK }; enum Value { // these are types diff --git a/src/interpreter/eval.cc b/src/interpreter/eval.cc index f3483fd..91a13f5 100644 --- a/src/interpreter/eval.cc +++ b/src/interpreter/eval.cc @@ -12,7 +12,7 @@ bool evaluateBuiltin(string kwd) { if ((kwd == "int") || (kwd == "str") || (kwd == "bool") || (kwd == "def") ||(kwd == "list") || (kwd == "func") || (kwd == "class") || (kwd == "mod") || (kwd == "return")) return 1; else if ((kwd == "print") || (kwd == "printl") || (kwd == "in") || (kwd == "write") || (kwd == "read") || (kwd == "sys") || (kwd == "wait")) return 1; else if ((kwd == "if") || (kwd == "else") || (kwd == "exit") || (kwd =="for") || (kwd == "foreach") || (kwd == "while")) return 1; - else if ((kwd == "random") || (kwd == "randomrange") || (kwd == "length")) return 1; + else if ((kwd == "random") || (kwd == "randomrange") || (kwd == "length") || (kwd == "break")) return 1; return 0; } @@ -86,6 +86,7 @@ Builtin getBuiltincmd(string kwd) { else if (kwd == "random") return RANDOM; else if (kwd == "randomrange") return RANDOMRANGE; else if (kwd == "length") return LENGTH; + else if (kwd == "break") return BREAK; return NONE; } diff --git a/src/interpreter/interpret.cc b/src/interpreter/interpret.cc index 3cb585a..db37d7e 100644 --- a/src/interpreter/interpret.cc +++ b/src/interpreter/interpret.cc @@ -48,6 +48,13 @@ void sts::runBuiltin(int *y, std::vector *scpvars, std::vector case SYSTEM: sys(y, scpvars, *functions); break; + case BREAK: + if (looping) { + scopedown(y, expressions); + looping = false; + } + else error(19, ""); + break; case EXIT: exit(0); } diff --git a/src/parser/parse.cc b/src/parser/parse.cc index e80f5df..041c0cd 100755 --- a/src/parser/parse.cc +++ b/src/parser/parse.cc @@ -63,3 +63,5 @@ void sts::parse(std::vector prg){ evaluateProgram(x); } + +// TODO: Add error and line parsing here \ No newline at end of file diff --git a/src/stream/loops.cc b/src/stream/loops.cc index f75d645..0aac266 100644 --- a/src/stream/loops.cc +++ b/src/stream/loops.cc @@ -2,33 +2,41 @@ void whileloop(sts *script, std::vector *variables, std::vector functions, int *y) { *y += 1; + sts s = *script; int n = *y; + s.looping = true; + + while (toBool(s.getval(variables, functions, &n).val)) { + s.newScope(new int(n), variables, &functions); + + if (!s.looping) break; - while (condition(script, &n, variables, functions)) { - script->newScope(new int(n), variables, &functions); n = *y; // set n back to y to repeat } - while (script->expressions[*y].tktype != OPENCURL) *y += 1; + while (s.expressions[*y].tktype != OPENCURL) *y += 1; *y += 1; - scopedown(y, script->expressions); + + s.looping = false; + scopedown(y, s.expressions); } void forloop(sts *script, std::vector *variables, std::vector functions, int *y) { *y += 1; - bool foreach = (script->expressions[*y+1].btn == STSIN); - + sts s = *script; + bool foreach = (s.expressions[*y+1].btn == STSIN); + s.looping = true; if (foreach) { stsvars root; string name; int rootsize; - name = script->expressions[*y].contents; + name = s.expressions[*y].contents; *y += 2; - root = findVar(*variables, script->expressions[*y].contents); // grab variable listed on 3rd argument of for loop + root = findVar(*variables, s.expressions[*y].contents); // grab variable listed on 3rd argument of for loop *y += 1; switch (root.type) { @@ -37,7 +45,7 @@ void forloop(sts *script, std::vector *variables, std::vector break; case 'i': case 'b': - script->error(9, root.name); + s.error(9, root.name); } for (int i = 0; i < rootsize; i++) { @@ -55,23 +63,31 @@ void forloop(sts *script, std::vector *variables, std::vector newvars.push_back(placeholder); - script->newScope(new int(*y), &newvars, &functions); + s.newScope(new int(*y), &newvars, &functions); + + variables->insert(variables->begin(), newvars.begin(), newvars.end()-1); + + if (!s.looping) break; } + *y += 1; } else { - int r = std::stoi(script->getval(variables, functions, y).val); + int r = std::stoi(s.getval(variables, functions, y).val); *y += 1; if (r <= 0) - script->error(17, std::to_string(r)); + s.error(17, std::to_string(r)); - for (int i = 0; i < r; i++) - script->newScope(new int(*y), variables, &functions); + for (int i = 0; i < r; i++) { + s.newScope(new int(*y), variables, &functions); + if (!s.looping) break; + } *y += 1; } - scopedown(y, script->expressions); + s.looping = false; + scopedown(y, s.expressions); } diff --git a/src/values/random.cc b/src/values/random.cc index 2509324..9ffc20f 100644 --- a/src/values/random.cc +++ b/src/values/random.cc @@ -25,7 +25,9 @@ int genrandomintfromrange(sts *s, std::vector *vars, std::vector (time(0)); - srand(ut); - return rand() % 2; + std::random_device randomd; + + std::mt19937_64 generate(randomd()); + std::uniform_int_distribution<> dis(0, 1); + return dis(generate); } \ No newline at end of file