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

@@ -134,7 +134,7 @@ Appends an item to a list.
Usage: `listappend *list $var` Usage: `listappend *list $var`
### String Operations (ALL WORK IN PROGRESS) ### String Operations
#### getstrsize #### getstrsize
@@ -200,7 +200,7 @@ Checks if the left value is lesser than the right value. Outputs a boolean to a
Usage: `lesser $value $value &var` Usage: `lesser $value $value &var`
### Type Conversions ### Type Conversions (ALL WORK IN PROGRESS)
#### stoi #### stoi
@@ -248,6 +248,24 @@ Usage: `pusharg $value`
#### call #### call
Calls a function, with all the arguments in the argument list. Calls a function, with all the arguments in the argument list. The return value will be put in the specified variable.
Usage: `call !function` Usage: `call !function &var
### Interacting with Libraries (ALL WORK IN PROGRESS)
#### use
Attempts to import another Ground program. Gets inserted wherever the use statement is. Any code (including code outside function declarations) will be executed.
Note: Ground will check the directory where the program is stored when trying to find imported programs. If that fails, it will check the directory set in the $GROUND_PATH environment variable set by your system. The '.grnd' extension is appended automatically.
Usage: `use $stringvalue`
#### extern
Attempts to import a shared object library written for Ground. All functions in the external library will be usable with `call`.
Note: Ground will check the directory where the program is stored when trying to find external programs. If that fails, it will check the directory set in the $GROUND_PATH environment variable set by your system. The '.so', '.dll', etc extension is appended automatically.
Usage: `extern $stringvalue`

View File

@@ -54,7 +54,10 @@ enum class Instructions {
Add, Subtract, Multiply, Divide, Add, Subtract, Multiply, Divide,
Equal, Inequal, Greater, Lesser, Equal, Inequal, Greater, Lesser,
End, Set, Empty, 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; 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 setlistat instruction
This instruction sets an item in a list to be a certain value. This instruction sets an item in a list to be a certain value.
@@ -643,6 +695,40 @@ void exec(vector<Instruction> in) {
break; 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 stdin instruction
This instruction takes input from the standard character input via This instruction takes input from the standard character input via
the C++ getline() function, and saves it to a variable. 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)); final.val = get<double>(left.val) + double(get<int>(right.val));
} else if (holds_alternative<string>(left.val) && holds_alternative<string>(right.val)) { } else if (holds_alternative<string>(left.val) && holds_alternative<string>(right.val)) {
final.val = get<string>(left.val) + get<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 { } else {
error("Cannot add those two values"); 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 == "setlistat") newInst.inst = Instructions::Setlistat;
else if (i == "getlistat") newInst.inst = Instructions::Getlistat; else if (i == "getlistat") newInst.inst = Instructions::Getlistat;
else if (i == "getlistsize") newInst.inst = Instructions::Getlistsize; 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 error("Unexpected token: " + i);
} else { } else {
Types type = getType(i); Types type = getType(i);

89
tests/everything.grnd Normal file
View File

@@ -0,0 +1,89 @@
# I/O
stdlnout "Hello there!"
stdout "What is your name? "
stdin &name
add "Hello, " $name &out
stdlnout $out
# Types
stdlnout "dingus"
stdlnout 7
stdlnout 3.14159
stdlnout true
stdlnout 'e'
# Variables
set &testVar "This is a test"
stdlnout $testVar
# Lists
setlist *testList "Item 1" "Another Item" "Item the Third"
getlistat *testList 2 &tmp
stdlnout $tmp
setlistat *testList 1 "I changed this item"
getlistat *testList 1 &tmp
stdlnout $tmp
listappend *testList "I appended this item"
getlistat *testList 3 &tmp
stdlnout $tmp
getlistsize *testList &tmp
stdlnout $tmp
# String Operations
set &testStr "dingus"
getstrsize $testStr &tmp
stdlnout $tmp
getstrcharat $testStr 3 &tmp
stdlnout $tmp
# Maths
add 1 1 &tmp
stdlnout $tmp
subtract 10 5 &tmp
stdlnout $tmp
multiply 15 15 &tmp
stdlnout $tmp
divide 36 4 &tmp
stdlnout $tmp
# Comparisons
equal 5 5 &tmp
stdlnout $tmp
inequal 5 5 &tmp
stdlnout $tmp
greater 10 5 &tmp
stdlnout $tmp
lesser 10 5 &tmp
stdlnout $tmp
# Control flow
set &counter 0
@myLabel
add $counter 1 &counter
stdlnout $counter
inequal $counter 10 &case
if $case %myLabel
# That's it!
stdlnout "Everything ran! Check the output to see if it is what is expected."
end 0