forked from ground/ground
Labels
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1 +1,2 @@
|
|||||||
ground
|
ground
|
||||||
|
Bobfile
|
||||||
|
1
Bobfile
1
Bobfile
@@ -1,4 +1,5 @@
|
|||||||
compiler "g++";
|
compiler "g++";
|
||||||
binary "ground";
|
binary "ground";
|
||||||
source "src/main.cpp";
|
source "src/main.cpp";
|
||||||
|
flag "O3";
|
||||||
compile;
|
compile;
|
||||||
|
@@ -32,7 +32,13 @@ Reference a line (a line reference) with a percent symbol before a line number:
|
|||||||
jump %10
|
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
|
jump %myLabel
|
||||||
|
54
src/main.cpp
54
src/main.cpp
@@ -72,7 +72,7 @@ enum class Instructions {
|
|||||||
See also parser function
|
See also parser function
|
||||||
*/
|
*/
|
||||||
enum class Types {
|
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;
|
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
|
ValueRef struct
|
||||||
If the program being executed makes a value reference, it is stored in a ValueRef
|
If the program being executed makes a value reference, it is stored in a ValueRef
|
||||||
@@ -186,6 +192,8 @@ struct Direct {
|
|||||||
*/
|
*/
|
||||||
struct Line {
|
struct Line {
|
||||||
int lineNum;
|
int lineNum;
|
||||||
|
bool isLabel = false;
|
||||||
|
string label;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -282,6 +290,11 @@ bool isLine(string in) {
|
|||||||
else return false;
|
else return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isLabel(string in) {
|
||||||
|
if (in.size() >= 1 && in[0] == '@') return true;
|
||||||
|
else return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool isListRef(string in) {
|
bool isListRef(string in) {
|
||||||
if (in.size() >= 1 && in[0] == '*') return true;
|
if (in.size() >= 1 && in[0] == '*') return true;
|
||||||
else return false;
|
else return false;
|
||||||
@@ -301,6 +314,7 @@ Types getType(string in) {
|
|||||||
if (isValue(in)) return Types::Value;
|
if (isValue(in)) return Types::Value;
|
||||||
if (isDirect(in)) return Types::Direct;
|
if (isDirect(in)) return Types::Direct;
|
||||||
if (isLine(in)) return Types::Line;
|
if (isLine(in)) return Types::Line;
|
||||||
|
if (isLabel(in)) return Types::Label;
|
||||||
if (isListRef(in)) return Types::ListRef;
|
if (isListRef(in)) return Types::ListRef;
|
||||||
error("Could not determine type of \"" + in + "\"");
|
error("Could not determine type of \"" + in + "\"");
|
||||||
return Types::Int;
|
return Types::Int;
|
||||||
@@ -315,7 +329,7 @@ Types getType(string in) {
|
|||||||
void exec(vector<Instruction> in) {
|
void exec(vector<Instruction> in) {
|
||||||
for (int i = 0; i < in.size(); i++) {
|
for (int i = 0; i < in.size(); i++) {
|
||||||
Instruction l = in[i];
|
Instruction l = in[i];
|
||||||
// Pre process value references
|
// Pre process value references and labels
|
||||||
for (int j = 0; j < l.args.size(); j++) {
|
for (int j = 0; j < l.args.size(); j++) {
|
||||||
if (holds_alternative<ValueRef>(l.args[j])) {
|
if (holds_alternative<ValueRef>(l.args[j])) {
|
||||||
if (variables.find(get<ValueRef>(l.args[j]).varName) != variables.end()) {
|
if (variables.find(get<ValueRef>(l.args[j]).varName) != variables.end()) {
|
||||||
@@ -323,6 +337,17 @@ void exec(vector<Instruction> in) {
|
|||||||
} else {
|
} else {
|
||||||
error("Could not find variable " + get<ValueRef>(l.args[j]).varName);
|
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) {
|
switch (l.inst) {
|
||||||
@@ -1124,16 +1149,25 @@ vector<vector<string>> lexer(string in) {
|
|||||||
vector<Instruction> parser(vector<vector<string>> in) {
|
vector<Instruction> parser(vector<vector<string>> in) {
|
||||||
vector<Instruction> out;
|
vector<Instruction> out;
|
||||||
|
|
||||||
|
int lineNum = 1;
|
||||||
for (vector<string> lineTokens : in) {
|
for (vector<string> lineTokens : in) {
|
||||||
if (lineTokens.empty()) continue;
|
lineNum ++;
|
||||||
|
|
||||||
Instruction newInst;
|
Instruction newInst;
|
||||||
|
if (lineTokens.empty()) {
|
||||||
|
out.push_back(newInst);
|
||||||
|
continue;
|
||||||
|
};
|
||||||
bool firstInst = true;
|
bool firstInst = true;
|
||||||
|
|
||||||
for (string i : lineTokens) {
|
for (string i : lineTokens) {
|
||||||
if (firstInst) {
|
if (firstInst) {
|
||||||
firstInst = false;
|
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 == "stdout") newInst.inst = Instructions::Stdout;
|
||||||
else if (i == "stdlnout") newInst.inst = Instructions::Stdlnout;
|
else if (i == "stdlnout") newInst.inst = Instructions::Stdlnout;
|
||||||
else if (i == "jump") newInst.inst = Instructions::Jump;
|
else if (i == "jump") newInst.inst = Instructions::Jump;
|
||||||
@@ -1170,10 +1204,18 @@ vector<Instruction> parser(vector<vector<string>> in) {
|
|||||||
newInst.args.push_back(newDirect);
|
newInst.args.push_back(newDirect);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case Types::Label:
|
||||||
|
error("Label should be defined as first token");
|
||||||
|
break;
|
||||||
case Types::Line:
|
case Types::Line:
|
||||||
{
|
{
|
||||||
Line newLine;
|
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);
|
newInst.args.push_back(newLine);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@@ -1,7 +1,9 @@
|
|||||||
|
@begin
|
||||||
stdout "Do you like cheese? "
|
stdout "Do you like cheese? "
|
||||||
stdin &userin
|
stdin &userin
|
||||||
equal $userin "yes" &condition
|
equal $userin "yes" &condition
|
||||||
if $condition %7
|
if $condition %end
|
||||||
stdlnout "That is sad"
|
stdlnout "That is sad"
|
||||||
jump %1
|
jump %begin
|
||||||
|
@end
|
||||||
stdlnout "Awesome! I do too!"
|
stdlnout "Awesome! I do too!"
|
||||||
|
Reference in New Issue
Block a user