More stuff

This commit is contained in:
2025-08-11 10:07:05 +10:00
parent 566d3aa0fb
commit 09033cd432
3 changed files with 207 additions and 5 deletions

View File

@@ -54,7 +54,10 @@ enum class Instructions {
Add, Subtract, Multiply, Divide,
Equal, Inequal, Greater, Lesser,
End, Set, Empty,
Setlist, Getlistat, Setlistat, Getlistsize, Listappend, Listprepend
Setlist, Getlistat, Setlistat, Getlistsize, Listappend, Listprepend,
Getstrcharat, Getstrsize,
Stoi, Stod, tostring,
Fun, Endfun, Pusharg, Call
};
/*
@@ -531,6 +534,55 @@ void exec(vector<Instruction> in) {
}
}
break;
/*
getstrcharat instruction
This instruction gets a character from a string at an index and saves it
to a variable.
*/
case Instructions::Getstrcharat:
if (l.args.size() < 3) {
error("Could not find all arguments required for Getstrcharat inbuilt");
}
{
string instr;
int ref;
Direct var;
if (holds_alternative<Literal>(l.args[0])) {
if (holds_alternative<string>(get<Literal>(l.args[0]).val)) {
instr = get<string>(get<Literal>(l.args[0]).val);
} else {
error("First argument of getlistat must be a string literal");
}
} else {
error("First argument of getlistat must be a string literal");
}
if (holds_alternative<Literal>(l.args[1])) {
if (holds_alternative<int>(get<Literal>(l.args[1]).val)) {
ref = get<int>(get<Literal>(l.args[1]).val);
} else {
error("Second argument of getlistat must be an integer literal");
}
} else {
error("Second argument of getlistat must be an integer literal");
}
if (holds_alternative<Direct>(l.args[2])) {
var = get<Direct>(l.args[2]);
} else {
error("Third argument of getlistat must be a direct reference");
}
if (instr.size() > ref) {
Literal newLit;
newLit.val = instr[ref];
variables[var.varName] = newLit;
} else {
error("Index " + to_string(ref) + " out of range of string " + instr);
}
}
break;
/*
setlistat instruction
This instruction sets an item in a list to be a certain value.
@@ -643,6 +695,40 @@ void exec(vector<Instruction> in) {
break;
}
/*
getstrsize instruction
This instruction saves the size of a string in a variable.
*/
case Instructions::Getstrsize:
if (l.args.size() < 2) {
error("Could not find all arguments required for Getstrsize inbuilt");
}
{
string ref;
Direct var;
if (holds_alternative<Literal>(l.args[0])) {
if (holds_alternative<string>(get<Literal>(l.args[0]).val)) {
ref = get<string>(get<Literal>(l.args[0]).val);
} else {
error("First argument of getlistsize must be a string value");
}
} else {
error("First argument of getlistsize must be a string value");
}
if (holds_alternative<Direct>(l.args[1])) {
var = get<Direct>(l.args[1]);
} else {
error("Second argument of getlistsize must be a direct reference");
}
Literal newLit;
newLit.val = int(ref.size());
variables[var.varName] = newLit;
break;
}
/*
stdin instruction
This instruction takes input from the standard character input via
the C++ getline() function, and saves it to a variable.
@@ -705,6 +791,12 @@ void exec(vector<Instruction> in) {
final.val = get<double>(left.val) + double(get<int>(right.val));
} else if (holds_alternative<string>(left.val) && holds_alternative<string>(right.val)) {
final.val = get<string>(left.val) + get<string>(right.val);
} else if (holds_alternative<string>(left.val) && holds_alternative<char>(right.val)) {
final.val = get<string>(left.val).append(&get<char>(right.val));
} else if (holds_alternative<char>(left.val) && holds_alternative<string>(right.val)) {
final.val = string().append(&get<char>(left.val)) + get<string>(right.val);
} else if (holds_alternative<char>(left.val) && holds_alternative<char>(right.val)) {
final.val = string().append(&get<char>(left.val)).append(&get<char>(right.val));
} else {
error("Cannot add those two values");
}
@@ -1267,6 +1359,9 @@ vector<Instruction> parser(vector<vector<string>> in) {
else if (i == "setlistat") newInst.inst = Instructions::Setlistat;
else if (i == "getlistat") newInst.inst = Instructions::Getlistat;
else if (i == "getlistsize") newInst.inst = Instructions::Getlistsize;
else if (i == "listappend") newInst.inst = Instructions::Listappend;
else if (i == "getstrsize") newInst.inst = Instructions::Getstrsize;
else if (i == "getstrcharat") newInst.inst = Instructions::Getstrcharat;
else error("Unexpected token: " + i);
} else {
Types type = getType(i);