diff --git a/.gitignore b/.gitignore index b649b43..5485e21 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ ground +Bobfile diff --git a/Bobfile b/Bobfile index 89aa177..c50ee3c 100644 --- a/Bobfile +++ b/Bobfile @@ -1,4 +1,5 @@ compiler "g++"; binary "ground"; source "src/main.cpp"; +flag "O3"; compile; diff --git a/docs/syntax.md b/docs/syntax.md index 8972dc1..4fa9220 100644 --- a/docs/syntax.md +++ b/docs/syntax.md @@ -32,7 +32,13 @@ Reference a line (a line reference) with a percent symbol before a line number: jump %10 ``` -(WORK IN PROGRESS) Alternatively, set a label and jump to that (setting labels will be discussed below): +Alternatively, set a label: + +``` + @myLabel +``` + +and jump to that (setting labels will be discussed below): ``` jump %myLabel diff --git a/src/main.cpp b/src/main.cpp index eb47931..51665c8 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -72,7 +72,7 @@ enum class Instructions { See also parser function */ enum class Types { - Int, Double, String, Char, Bool, Value, Direct, Line, ListRef + Int, Double, String, Char, Bool, Value, Direct, Line, ListRef, Label }; /* @@ -146,6 +146,12 @@ map variables; */ map lists; +/* + labels map + Contains all labels made in the program, for ease of jumping around the code. +*/ +map labels; + /* ValueRef struct If the program being executed makes a value reference, it is stored in a ValueRef @@ -186,6 +192,8 @@ struct Direct { */ struct Line { int lineNum; + bool isLabel = false; + string label; }; /* @@ -282,6 +290,11 @@ bool isLine(string in) { else return false; } +bool isLabel(string in) { + if (in.size() >= 1 && in[0] == '@') return true; + else return false; +} + bool isListRef(string in) { if (in.size() >= 1 && in[0] == '*') return true; else return false; @@ -301,6 +314,7 @@ Types getType(string in) { if (isValue(in)) return Types::Value; if (isDirect(in)) return Types::Direct; if (isLine(in)) return Types::Line; + if (isLabel(in)) return Types::Label; if (isListRef(in)) return Types::ListRef; error("Could not determine type of \"" + in + "\""); return Types::Int; @@ -315,7 +329,7 @@ Types getType(string in) { void exec(vector in) { for (int i = 0; i < in.size(); i++) { Instruction l = in[i]; - // Pre process value references + // Pre process value references and labels for (int j = 0; j < l.args.size(); j++) { if (holds_alternative(l.args[j])) { if (variables.find(get(l.args[j]).varName) != variables.end()) { @@ -323,6 +337,17 @@ void exec(vector in) { } else { error("Could not find variable " + get(l.args[j]).varName); } + } else if (holds_alternative(l.args[j])) { + Line ln = get(l.args[j]); + if (ln.isLabel) { + if (labels.find(ln.label) != labels.end()) { + Line newLine; + newLine.lineNum = labels[ln.label]; + l.args[j] = newLine; + } else { + error("Could not find label " + ln.label); + } + } } } switch (l.inst) { @@ -1123,17 +1148,26 @@ vector> lexer(string in) { */ vector parser(vector> in) { vector out; - + + int lineNum = 1; for (vector lineTokens : in) { - if (lineTokens.empty()) continue; - + lineNum ++; Instruction newInst; + if (lineTokens.empty()) { + out.push_back(newInst); + continue; + }; bool firstInst = true; for (string i : lineTokens) { if (firstInst) { firstInst = false; - if (i == "stdin") newInst.inst = Instructions::Stdin; + if (isLabel(i)) { + labels[i.substr(1)] = lineNum; + out.push_back(newInst); + continue; + } + else if (i == "stdin") newInst.inst = Instructions::Stdin; else if (i == "stdout") newInst.inst = Instructions::Stdout; else if (i == "stdlnout") newInst.inst = Instructions::Stdlnout; else if (i == "jump") newInst.inst = Instructions::Jump; @@ -1170,10 +1204,18 @@ vector parser(vector> in) { newInst.args.push_back(newDirect); } break; + case Types::Label: + error("Label should be defined as first token"); + break; case Types::Line: { Line newLine; - newLine.lineNum = stoi(i.substr(1)); + if (isInt(i.substr(1))) newLine.lineNum = stoi(i.substr(1)); + else { + newLine.isLabel = true; + newLine.label = i.substr(1); + newLine.lineNum = 0; + } newInst.args.push_back(newLine); } break; diff --git a/tests/input.grnd b/tests/input.grnd index 9c1fc16..51ba13c 100644 --- a/tests/input.grnd +++ b/tests/input.grnd @@ -1,7 +1,9 @@ +@begin stdout "Do you like cheese? " stdin &userin equal $userin "yes" &condition -if $condition %7 +if $condition %end stdlnout "That is sad" -jump %1 +jump %begin +@end stdlnout "Awesome! I do too!"