forked from ground/ground
Labels
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1 +1,2 @@
|
||||
ground
|
||||
Bobfile
|
||||
|
1
Bobfile
1
Bobfile
@@ -1,4 +1,5 @@
|
||||
compiler "g++";
|
||||
binary "ground";
|
||||
source "src/main.cpp";
|
||||
flag "O3";
|
||||
compile;
|
||||
|
@@ -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
|
||||
|
56
src/main.cpp
56
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<string, Literal> variables;
|
||||
*/
|
||||
map<string, List> lists;
|
||||
|
||||
/*
|
||||
labels map
|
||||
Contains all labels made in the program, for ease of jumping around the code.
|
||||
*/
|
||||
map<string, int> 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<Instruction> 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<ValueRef>(l.args[j])) {
|
||||
if (variables.find(get<ValueRef>(l.args[j]).varName) != variables.end()) {
|
||||
@@ -323,6 +337,17 @@ void exec(vector<Instruction> in) {
|
||||
} else {
|
||||
error("Could not find variable " + get<ValueRef>(l.args[j]).varName);
|
||||
}
|
||||
} else if (holds_alternative<Line>(l.args[j])) {
|
||||
Line ln = get<Line>(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<vector<string>> lexer(string in) {
|
||||
*/
|
||||
vector<Instruction> parser(vector<vector<string>> in) {
|
||||
vector<Instruction> out;
|
||||
|
||||
|
||||
int lineNum = 1;
|
||||
for (vector<string> 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<Instruction> parser(vector<vector<string>> 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;
|
||||
|
@@ -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!"
|
||||
|
Reference in New Issue
Block a user